I want a reusable script that can be configured by swapping out variable values. I am hoping to be able to loop over a collection of tag_ids
and insert a row for each tag. Also I want to have a check either side of the insert for visual verification before committing.
This is what I have tried so far:
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;
Issues with this sample:
Any suggestions about the correct way to approach this scenario?
Ok, first of all, the above code contains a few problems. You can't use selects in PL/SQL without storing them in a variable with the INTO keyword.
To reproduce your problem, I used these script to create the table and sequence:
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;
I then modified your code into this:
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;
You will now get visual feedback about what's happening. Next question is, what to do when you don't get the desired result? You could go for a construction like this where you commit or rollback the transaction based on the results of those counts:
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;
You might also want to look into bulk operations if you're going to use this code for larger numbers or records. Good documentation about it can be found here: http://www.oracle-base.com/articles/9i/bulk-binds-and-record-processing-9i.php
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.