动态查询:新值

时间:2016-05-30 14:40:42

标签: sql oracle

我有一个名为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;

有什么想法吗?

1 个答案:

答案 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