Beispiel: Eine leere Maske mit der Tabelle DEPT. In diesem Beispiel soll es drei Regeln geben, nach denen die Default-Where-Bedingung aufgebaut wird. Das Problem ist: Ab dem zweiten IF muss man jedesmal überprüfen, ob in V_Default_Where schon etwas drinsteht. Falls ja wird ein ' AND ' dran konkatiniert vor jedem neuen Teilstring.
DECLARE
V_Default_Where VARCHAR2 (2000);
BEGIN
IF Rule_1_is_TRUE THEN
V_Default_Where := 'DEPTNO IN (10, 20, 30)';
END IF;
IF Rule_2_is_TRUE THEN
IF V_Default_Where IS NOT NULL THEN
V_Default_Where := V_Default_Where ||
' AND DNAME != ''SALES'' ';
ELSE
V_Default_Where := 'DNAME != ''SALES'' ';
END IF;
END IF;
IF Rule_3_is_TRUE THEN
IF V_Default_Where IS NOT NULL THEN
V_Default_Where := V_Default_Where ||
' AND LOC IS NOT NULL';
ELSE
V_Default_Where := 'LOC IS NOT NULL';
END IF;
END IF;
Set_Block_Property ('DEPT', DEFAULT_WHERE,
V_Default_Where);
Go_Block ('DEPT');
Execute_Query;
END;
Diese IF's sind nicht wartbar. Änderungen in der Where-Bedingung bedeuten immer zwei Änderungen im Code:
...
V_Default_Where := V_Default_Where ||
' AND LOC IS NULL';
ELSE
V_Default_Where := 'LOC IS NULL';
...
Ein besserer Ansatz ist die Benutzung von ' AND ' bei jeder Konkatinierung:
DECLARE
V_Default_Where VARCHAR2 (2000);
BEGIN
IF Rule_1_is_TRUE THEN
V_Default_Where := ' AND DEPTNO IN (10, 20, 30)';
END IF;
IF Rule_2_is_TRUE THEN
V_Default_Where := V_Default_Where ||
' AND DNAME != ''SALES'' ';
END IF;
IF Rule_3_is_TRUE THEN
V_Default_Where := V_Default_Where ||
' AND LOC IS NOT NULL';
END IF;
Set_Block_Property ('DEPT', DEFAULT_WHERE,
Substr (V_Default_Where, 6));
Go_Block ('DEPT');
Execute_Query;
END;
der Substr (V_Default_Where, 6) eliminiert zum Schluss das führende ' AND '.
Sehr einfacher und wartbarer Code!
PS: In den englischen Kommentaren gibt es eine Erklärung dafür, dass ich nicht den Trick mit "1=1" benutze
Keine Kommentare:
Kommentar veröffentlichen