Có ba điều sai với SQL động của bạn.
- THỰC HIỆN NGAY LẬP TỨC không phải là một hàm:cú pháp thích hợp là
execute immediate '<<query>>' into <<variable>>
. - Một câu lệnh INSERT nhận mệnh đề VALUES hoặc một mệnh đề SELECT nhưng không phải cả hai. SELECT sẽ rất sai trong trường hợp này. Cũng lưu ý rằng nó CÓ GIÁ TRỊ không phải GIÁ TRỊ.
- COLUMN_NAME là một chuỗi ký tự trong SQL động nên nó cần phải nằm trong dấu ngoặc kép. Nhưng vì bản thân câu lệnh SQL là một chuỗi, các dấu ngoặc kép trong chuỗi động cần phải được thoát ra, vì vậy nó phải là `` '' '|| column_name ||' ''.
Vì vậy, phiên bản đã sửa sẽ trông giống như thế này
declare
Cursor C_TABLE is
select trim(table_name) as table_name
from all_tables
where table_name in ('T1', 'T2', 'T3');
V_ROWNUM number;
begin
for m in C_TABLE
loop
for i in ( select column_name
from (
select c.column_name
from all_tab_columns c
where c.table_name = m.table_name
and c.owner = 'owner1'
)
)
loop
execute immediate 'select count(*) from ' || m.table_name into V_ROWNUM;
execute immediate 'insert into MY_table values ( ''' || i.column_name || ''', ' || V_ROWNUM || ')';
end loop;
end loop;
end;
/
SQL động rất khó vì nó biến lỗi biên dịch thành lỗi thời gian chạy. Trước tiên, bạn nên viết các câu lệnh dưới dạng SQL tĩnh. Khi bạn đã có đúng cú pháp cơ bản, bạn có thể chuyển đổi nó thành SQL động.