Moin,
also das Anlegen eines DB Triggers für
ORACLE habe ich gelöst.
ALLE folgenden Programme sind für SAP-systeme mit ORACLE Datenbank !!!
Ein fehlerhaft implementierter Trigger führt dazu, dass keine Werte mehr in die betroffene Tabelle geschrieben werden kann.
Daher sollte man sich im klaren sein, wie man Trigger wieder löschen kann. (mit DROP TRIGGER xx)
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
* Lösche Triggers T00X
EXEC SQL.
DROP TRIGGER T00X
- GeSHi ©
Zuerst ein kleiner Report zum Auflisten aller vorhandenen Trigger, da man keine wirklich brauchbaren Informationen über das erfolgreiche Anlegen erhält.
(SAP verwendet keine Trigger, zumindest in unserem System)
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
DATA: trigger
TYPE ddf4dbtrig
, event TYPE ddtrgevent,
triggername TYPE ddtrigname,
tabname TYPE dd02l-tabname,
code(1024),
refnames(1024).
DATA: BEGIN OF li
OCCURS 0, li(512),
END OF li.
EXEC SQL.
open c for
select table_name, trigger_name, triggering_event,
referencing_names ,trigger_body
from all_triggers
EXEC SQL.
fetch next c
into :tabname
, :triggername
, :event
, :refnames
, :code
WRITE: / tabname
COLOR COL_GROUP, triggername COLOR COL_GROUP,
event COLOR COL_GROUP,
refnames COLOR COL_GROUP.
SPLIT code
AT crlf
+1(1) INTO TABLE li
.
WRITE: / li
-li
COLOR COL_KEY .
EXEC SQL.
close c
- GeSHi ©
Ein DB-Trigger wird an einer Datenbanktabelle als eine Art Prozedur angehängt.
Als ORACLE SQL-Code sieht das u.a. so aus:
Dieser Trigger schreibt einen Timestamp und die Werte der Tabelle Z003 vor deren Änderung in die Tabelle Z004, wenn in Tabelle Z003 ein Wert geändert wird.
(Also genau wie der DBTABLOG-Mechanismus.)
Ich habe zuerst 2 SAP Tabellen angelegt (SE11)
Tabelle Z003:
F1 Keyfeld CHAR10
F2 CHAR10
Tabelle Z004:
TSTAMP Keyfeld CHAR14
F1 CHAR10
F2 CHAR10
Ein NATIVE SQL Ansatz für den Trigger sieht so aus:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
EXEC SQL.
REFERENCING NEW AS New OLD AS newRow
FOR EACH ROW
DECLARE
TSTAMP varchar2(14);
BEGIN
IF :newRow
.f1
IS NOT NULL THEN SELECT TO_CHAR
(sysdate
, 'YYYYMMDDHH24MISS') into TSTAMP
FROM dual;
INSERT INTO Z004
VALUES(TSTAMP
,:newRow
.f1
,:newRow
.f2
);
END JGTEST;
- GeSHi ©
Es gibt hier das Problem, daß ":newRow.f1" ungewollt eine Wertübergabe an das weiterverarbeitende ABAP darstellt !!!
So meldet auch die Syntaxprüfung einen Fehler!
Eine funktionierende Lösung:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
DATA t
TYPE TABLE OF tab512
WITH HEADER LINE.
DATA: sql_statement
(65535) TYPE c
, sql_stmt_length TYPE i,
sql_error_text(300),
sql_error_number LIKE sy-tabix,
record_count LIKE jctab-counter,
lt_error_codes TYPE STANDARD TABLE OF i.
APPEND 'CREATE OR REPLACE TRIGGER T003' TO t
. APPEND 'AFTER INSERT OR UPDATE' TO t
. APPEND 'REFERENCING NEW AS New OLD AS newRow' TO t
. APPEND 'TSTAMP varchar2(14);' TO t
. APPEND 'IF :newRow.f1 IS NOT NULL THEN' TO t
. 'SELECT TO_CHAR(sysdate, ''YYYYMMDDHH24MISS'') into TSTAMP FROM dual;'
TO t.
'INSERT INTO Z004 VALUES(TSTAMP, :newRow.f1, :newRow.f2);' TO t.
SEPARATED BY crlf+1(1).
SHIFT sql_statement
LEFT BY 1 PLACES
.
sql_stmt_length = STRLEN( sql_statement ).
record_count = 1.
CALL 'C_DB_EXECUTE' ID 'STATLEN' FIELD sql_stmt_length
ID 'STATTXT' FIELD sql_statement
ID 'ROWNUM' FIELD record_count
ID 'SQLERR' FIELD sql_error_number
ID 'ERRTXT' FIELD sql_error_text.
- GeSHi ©
Resourcen:
http://infolab.stanford.edu/~ullman/fcd ... ggers.htmlhttp://download.oracle.com/docs/cd/B141 ... tm#1007172gruß Tron