簡體   English   中英

PL / SQL-循環插入並選擇

[英]PL/SQL - Loop insert and select

我想要一個可重用的腳本,可以通過換出變量值進行配置。 我希望能夠遍歷tag_ids的集合並為每個標簽插入一行。 我也想在提交之前檢查插入的任何一側以進行視覺驗證。

到目前為止,這是我嘗試過的:

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;

此樣本存在以下問題:

  • 此示例返回有關選擇查詢的錯誤。
  • 當我刪除選擇語句時,示例代碼將返回錯誤,並在“ numList”中添加索引。

關於解決這種情況的正確方法有何建議?

好的,首先,上面的代碼包含一些問題。 如果不將選擇存儲在帶有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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM