2014-06-16 76 views
0

我想要一個可以通過交換變量值來配置的可重用腳本。我希望能夠遍歷tag_ids的集合併爲每個標記插入一行。此外,我想在提交之前檢查插件的任一側以進行可視化驗證。PL/SQL - 循環插入並選擇

這是我到目前爲止已經試過:

set verify off; 
set serveroutput on; 

define uname = 'foobar' 
define f_name = 'foo' 
define l_name = 'bar' 

declare 
type numListType is table of number; 
numList numListType; 

begin 
numList := numListType(432,433,434,435); 

for i in numList.FIRST..numList.LAST loop 
    dbms_output.put_line('EXPECTING 0'); 
    select count(*) 
    from security_tag_tbl 
    where tag_id = numList(i); 

    dbms_output.put_line('INSERTING ROW'); 
    insert into security_tag_tbl (id, username, first_name, last_name, tag_id) 
    values (security_tag_tbl_seq.nextval, '&uname', '&f_name', '&l_name', numList(i)); 

    dbms_output.put_line('EXPECTING 1'); 
    select count(*) 
    from security_tag_tbl 
    where tag_id = numList(i); 
end loop; 
end; 
/

set serveroutput off; 
set verify on; 

問題與此示例:

  • 該樣品返回各地選擇查詢錯誤。
  • 當我刪除select語句時,示例代碼返回'numList'中索引的錯誤。

有關正確處理此方案的任何建議?

+0

上面的代碼有什麼問題? –

+0

對不起,我已經添加了詳細信息。謝謝@BobJarvis – travega

回答

2

好的,首先,上面的代碼包含一些問題。您不能在PL/SQL中使用選擇,而不將它們存儲在具有INTO關鍵字的變量中。

要重現你的問題,我用這些腳本來創建表和順序:

create table security_tag_tbl (id number, username varchar2(200), first_name varchar2(200), last_name varchar2(200), tag_id number); 

create sequence security_tag_tbl_seq; 

我再修改你的代碼是:

set verify off; 
set serveroutput on; 

define uname = 'foobar' 
define f_name = 'foo' 
define l_name = 'bar' 

declare 
type numListType is table of number; 
numList numListType; 

firstcount number; 
secondcount number; 

begin 
numList := numListType(432,433,434,435); 

for i in numList.FIRST..numList.LAST loop 
    dbms_output.put_line('EXPECTING 0'); 
    select count(*) 
    into firstcount 
    from security_tag_tbl 
    where tag_id = numList(i); 

    dbms_output.put_line('GOT ' || firstcount); 


    dbms_output.put_line('INSERTING ROW'); 
    insert into security_tag_tbl (id, username, first_name, last_name, tag_id) 
    values (security_tag_tbl_seq.nextval, '&uname', '&f_name', '&l_name', numList(i)); 

    dbms_output.put_line('EXPECTING 1'); 
    select count(*) 
    into secondcount 
    from security_tag_tbl 
    where tag_id = numList(i); 

    dbms_output.put_line('GOT ' || secondcount); 

end loop; 
end; 
/

set serveroutput off; 
set verify on; 

現在,您將得到什麼的視覺反饋發生。下一個問題是,當你沒有得到期望的結果時該怎麼辦?你可以去像這樣的建築,你基於這些計數的結果提交或回滾事務:

set verify off; 
set serveroutput on; 

define uname = 'foobar' 
define f_name = 'foo' 
define l_name = 'bar' 

declare 
type numListType is table of number; 
numList numListType; 

firstcount number; 
secondcount number; 
errorocured boolean := false; 

begin 
numList := numListType(432,433,434,435); 

for i in numList.FIRST..numList.LAST loop 
    dbms_output.put_line('EXPECTING 0'); 
    select count(*) 
    into firstcount 
    from security_tag_tbl 
    where tag_id = numList(i); 

    dbms_output.put_line('GOT ' || firstcount); 
    if (firstcount != 0) then 
     errorocured := true; 
    end if; 


    dbms_output.put_line('INSERTING ROW'); 
    insert into security_tag_tbl (id, username, first_name, last_name, tag_id) 
    values (security_tag_tbl_seq.nextval, '&uname', '&f_name', '&l_name', numList(i)); 

    dbms_output.put_line('EXPECTING 1'); 
    select count(*) 
    into secondcount 
    from security_tag_tbl 
    where tag_id = numList(i); 

    dbms_output.put_line('GOT ' || secondcount); 

    if (secondcount != 1) then 
     errorocured := true; 
    end if; 


end loop; 


if errorocured = true then 
    dbms_output.put_line('Something wend wrong, rolling back batch'); 
    rollback; 
else 
    dbms_output.put_line('Everything ok, committing batch'); 
    commit; 
end if; 

end; 
/

set serveroutput off; 
set verify on; 

您可能還需要尋找到批量操作,如果你要使用此代碼爲大數字或記錄。關於它的好文檔可以在這裏找到:http://www.oracle-base.com/articles/9i/bulk-binds-and-record-processing-9i.php

+0

很好的答案謝謝@ErikL ... – travega