我有一个名为PKCHANGES的表,它有几列,其中一列是primary_key列。我想要的是在其他表上创建一个触发器,并在插入时我获取一些值并将它们发布到PKCHANGES表。除了我尝试发布主键值时,一切都很好。我希望在primary_key列中输入逗号分隔的主键值。因此,如果TableX有3个主键,在PKCHANGES(primary_key列)中我发布了value1,value2,value3。
到目前为止,我只是设法得到以下结果,而不是实际值 ":new.pkCol1:new.pkCol2:new.pkCol3"
我的pl / sql块是:
DECLARE
mySql varchar2(5000);
myTable varchar2(10) := 'TableX';
BEGIN
mySql := 'CREATE OR REPLACE TRIGGER ' || 't_1' || ' AFTER INSERT ON ' || myTable || '
FOR EACH ROW
DECLARE
currentPK varchar2(200); --Contains the current primary key value in the loop
result varchar2(200); --Contains the appended string of primary key values
--Cursor that contains primaryKeys for table
CURSOR pks IS
SELECT cols.column_name FROM all_constraints cons, all_cons_columns cols
WHERE cons.constraint_type = ''P''
AND cons.constraint_name = cols.constraint_name
AND cons.table_name = ' || '''' || myTable || '''' || ';
BEGIN
--Loop through primary keys, get the value from the trigger, and append the string.
for current_pk IN pks LOOP
BEGIN
currentPK := '':new.'' || current_pk.column_name;
result:= result || currentPK;
END;
END LOOP;'
||
' --Insert the appended values into the primary_key column
INSERT INTO PKCHANGES(primary_key)' ||
'VALUES (result);'
|| ' END;';
dbms_output.put_line(mySql);
EXECUTE IMMEDIATE mySql;
END;
有什么想法吗?
答案 0 :(得分:2)
无需在每个插件上查询TableX的主键。它是稳定的,如果一旦改变,你也会改变触发器。
这允许您弹出触发器的逻辑。
在第一步中连接PK。我更喜欢LISTAGG
,因为它优雅的分隔符。你得到像:new.COL1||','||:new.COL2||','||:new.COL3
还要确保表名的大小写正确(我认为大写;否则你需要引用名称)。
在下一步中生成触发器,该触发器将基本上仅包含INSERT
DECLARE
mySql varchar2(5000);
myTable varchar2(10) := 'TableX';
result varchar2(200); -- Contains the concatenated string of primary key column names with delimiters,
-- e.g. ":new.COL1||','||:new.COL2||','||:new.COL3"
BEGIN
SELECT listagg(':new.'||cols.column_name,'||'',''||') within group (order by position) into result
FROM all_constraints cons, all_cons_columns cols
WHERE cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.table_name = upper(myTable);
mySql := 'CREATE OR REPLACE TRIGGER ' || 't_1' || ' AFTER INSERT ON ' || myTable || '
FOR EACH ROW
BEGIN
--Insert the appended values into the primary_key column
INSERT INTO PKCHANGES(primary_key)' ||
'VALUES ('||result||');'
|| ' END;';
dbms_output.put_line(mySql);
EXECUTE IMMEDIATE mySql;
END;
/
<强>测试强>
create table TableX
(col1 number,
col2 number,
col3 number,
col4 number);
alter table TableX add (primary key (col1, col2, col3));
insert into TableX values (1,2,3,4);
select * from PKCHANGES;
PRIMARY_KEY
-----------
1,2,3