如果目标中不存在值,则Oracle存储过程从查询中插入值

时间:2018-04-06 22:10:40

标签: oracle stored-procedures insert

Oracle存储过程:我想要一个将表和列名称插入另一个表(target:add_definitions)的存储过程。我希望能够随时运行此过程来获取可能已添加到数据库的新表/列。此外,我只想添加属于特定所有者的项目(Oracle术语 - 又名" PUBUSER"),并尽量避免使用" system"表。解决方案必须是存储过程。

当前存储的proc无效

create or replace procedure test_adding as
    sqlcmd varchar2(2000);

begin
    sqlcmd := 'insert into add_definitions (table_name, column_name) ' ||
      'select aa.table_name, aa.column_name ' ||
      'from all_tab_columns aa ' ||
      'where (instr(aa.table_name, ''$'') = 0 and aa.owner = ''PUBUSER'') and ' ||
      '(not exists (select item_id from add_definitions cc where cc.table_name = aa.table_name and cc.column_name = aa.column_name))';
    execute immediate sqlcmd;

end test_adding;

我首先通过手动填充add_definitions表(包含所有正确的值)来检查上述内容。然后我删除了2行。然后当我运行上面的那些时,不会添加这两行。我检查了上面INSERT的SELECT部分​​,它确实返回了我删除的2个项目(table_name和column_name)。

注意:我简化了代码,我需要在插入过程中添加其他值,这些值可以从其他代码片段中计算出来(我计划执行" USING" EXECUTE IMMEDIATE的一部分...来代替那些值进入sql命令)。但是我无法让这个非常基本的步骤先行。所以请不要向"不做"提供建议。存储过程等等。在这30个小时后,我即将开枪。

更新:根据其中一条评论,我试图让它在没有EXECUTE IMMEDIATE的情况下运行 - 只是做了直接的" INSERT INTO ... SELECT ...&#34 ;它仍然无法恢复已删除的值(我使用直接INSERT方法重新测试了上述步骤几次。这是非常令人沮丧的,因为其中一个回应说它对他们工作正常.... ??? (我使用的是Oracle 11g Express Edition - 但我当然希望这不会产生任何影响。)

1 个答案:

答案 0 :(得分:0)

您的代码似乎没有问题,除了在insert语句中不包含和不填充item_id列:

SQL> create table add_definitions (item_id int, table_name varchar2(100), column_name varchar2(100));
SQL> create sequence seq_test start with 1;
SQL> create or replace procedure test_adding as
    sqlcmd varchar2(2000);
begin
    sqlcmd := 'insert into add_definitions (item_id,table_name, column_name) ' ||
      'select seq_test.nextval,aa.table_name, aa.column_name ' ||
      'from all_tab_columns aa ' ||
      'where (instr(aa.table_name, ''$'') = 0 and aa.owner = ''PUBUSER'') and ' ||
      '(not exists (select item_id from add_definitions cc where cc.table_name = aa.table_name and cc.column_name = aa.column_name))';
    --dbms_output.put_line(sqlcmd);
      execute immediate sqlcmd;
end test_adding;

SQL> exec test_adding; -- Assume 100 rows inserted

SQL> select count(1) from add_definitions;

  COUNT(1)
----------
       100

SQL> delete add_definitions where item_id in (99,100);  

SQL> select count(1) from add_definitions;

  COUNT(1)
----------
        98

SQL> exec test_adding; 

SQL> select count(1) from add_definitions;

  COUNT(1)
----------
       100             

SQL> commit;