Sử dụng SQL động là cách tiếp cận đơn giản nhất từ quan điểm mã hóa. Tuy nhiên, vấn đề với SQL động là bạn phải phân tích cú pháp khó khăn cho mọi phiên bản riêng biệt của truy vấn, điều này không chỉ có khả năng đánh thuế CPU của bạn mà còn có khả năng làm ngập nhóm chia sẻ của bạn với rất nhiều câu lệnh SQL không thể chia sẻ, đẩy ra các câu lệnh mà bạn muốn lưu vào bộ nhớ cache, gây ra nhiều phân đoạn khó hơn và lỗi phân mảnh nhóm chia sẻ. Nếu bạn đang chạy điều này một lần mỗi ngày, đó có lẽ không phải là mối quan tâm lớn. Nếu hàng trăm người đang thực hiện nó hàng nghìn lần mỗi ngày, đó có thể là một mối quan tâm lớn.
Một ví dụ về cách tiếp cận SQL động
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos varchar2(100) := '10,20';
3 l_rc sys_refcursor;
4 l_dept_rec dept%rowtype;
5 begin
6 open l_rc for 'select * from dept where deptno in (' || l_deptnos || ')';
7 loop
8 fetch l_rc into l_dept_rec;
9 exit when l_rc%notfound;
10 dbms_output.put_line( l_dept_rec.dname );
11 end loop;
12 close l_rc;
13* end;
SQL> /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.
Ngoài ra, bạn có thể sử dụng một bộ sưu tập. Điều này có lợi thế là tạo ra một con trỏ duy nhất, có thể chia sẻ, do đó bạn không phải lo lắng về việc phân tích cú pháp khó hoặc làm ngập nhóm được chia sẻ. Nhưng nó có thể yêu cầu nhiều mã hơn một chút. Cách đơn giản nhất để xử lý các bộ sưu tập
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos tbl_deptnos := tbl_deptnos(10,20);
3 begin
4 for i in (select *
5 from dept
6 where deptno in (select column_value
7 from table(l_deptnos)))
8 loop
9 dbms_output.put_line( i.dname );
10 end loop;
11* end;
SQL> /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.
Mặt khác, nếu bạn thực sự phải bắt đầu với một danh sách các giá trị được phân tách bằng dấu phẩy, thì bạn sẽ phải phân tích chuỗi đó thành một tập hợp trước khi có thể sử dụng nó. Có nhiều cách khác nhau để phân tích cú pháp một chuỗi được phân tách - yêu thích của cá nhân tôi là sử dụng các biểu thức chính quy trong một truy vấn phân cấp nhưng chắc chắn bạn cũng có thể viết một cách tiếp cận thủ tục
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_deptnos tbl_deptnos;
3 l_deptno_str varchar2(100) := '10,20';
4 begin
5 select regexp_substr(l_deptno_str, '[^,]+', 1, LEVEL)
6 bulk collect into l_deptnos
7 from dual
8 connect by level <= length(replace (l_deptno_str, ',', NULL));
9 for i in (select *
10 from dept
11 where deptno in (select column_value
12 from table(l_deptnos)))
13 loop
14 dbms_output.put_line( i.dname );
15 end loop;
16* end;
17 /
ACCOUNTING
RESEARCH
PL/SQL procedure successfully completed.