1.EXECUTE IMMEDIATE 語句:在執行前才解析動態SQL語句或者PLSQL語句塊。
DECLARE
sql_stmt VARCHAR2(100);plsql_block VARCHAR2(300);
v_zip VARCHAR2(5) := '11106';
v_total_students NUMBER;
v_new_zip VARCHAR2(5);
v_student_id NUMBER := 151;
BEGIN
--create table MY_STUDENT
sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
EXECUTE IMMEDIATE sql_stmt;
--select total number of records from my.student table
--add display results on the screen
EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
INTO v_total_students;
dbms_output.put_line('Students added: ' || v_total_students);
--select current date and display it on the screen
plsql_block := 'declare ' || 'v_date date;' || 'begin ' ||
'select sysdate into v_date from dual;' ||
'dbms_output.put_line(to_char(v_date,''dd-mon-yyyy''));' ||
'end;';
--dbms_output.put_line(plsql_block);
EXECUTE IMMEDIATE plsql_block;
--update record in my_student table
sql_stmt := 'update my_student set zip=11105 where student_id=:1' ||
'returning zip into :2';
EXECUTE IMMEDIATE sql_stmt
USING v_student_id
RETURNING INTO v_new_zip;
dbms_output.put_line('New zip code: ' || v_new_zip);
END;
BEGIN
--drop table my_student
--EXECUTE IMMEDIATE 'DROP TABLE MY_student';
--create table MY_STUDENT
sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
'AS SELECT * FROM STUDENT WHERE ZIP= :zip';
EXECUTE IMMEDIATE sql_stmt
USING v_zip;
--select total number of records from my.student table
--add display results on the screen
EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
INTO v_total_students;
dbms_output.put_line('Students added: ' || v_total_students);
18 END;
19 /
DECLARE
*
ERROR at line 1:
ORA-01027: bind variables not allowed for data definition operations --create table 是DDL語句,他不接受任何綁定參數;
ORA-06512: at line 11
修改如下:
DECLARE
sql_stmt VARCHAR2(100);
v_zip VARCHAR2(5) := '11106';
v_total_students NUMBER;
BEGIN
--drop table my_student
EXECUTE IMMEDIATE 'DROP TABLE MY_student';
--create table MY_STUDENT
sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
EXECUTE IMMEDIATE sql_stmt;
--select total number of records from my.student table
--add display results on the screen
EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
INTO v_total_students;
dbms_output.put_line('Students added: ' || v_total_students);
END;
動態SQL結尾不應該是分號;
BEGIN
--drop table my_student
--EXECUTE IMMEDIATE 'DROP TABLE MY_student';
--create table MY_STUDENT
sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
EXECUTE IMMEDIATE sql_stmt;
--select total number of records from my.student table
--add display results on the screen
EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT;'
INTO v_total_students;
dbms_output.put_line('Students added: ' || v_total_students);
17 END;
18 /
DECLARE
*
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at line 14
DECLARE
sql_stmt VARCHAR2(100);
BEGIN
sql_stmt := 'update course' || ' set prerequisite=:some_value';
EXECUTE IMMEDIATE sql_stmtl
USING NULL;
END;
6 7 8
9 /
EXECUTE IMMEDIATE sql_stmtl
*
ERROR at line 5:
ORA-06550: line 5, column 23:
PLS-00201: identifier 'SQL_STMTL' must be declared
ORA-06550: line 5, column 5:
PL/SQL: Statement ignored
DECLARE
sql_stmt VARCHAR2(100);
v_null VARCHAR2(1);
BEGIN
sql_stmt := 'update course' || ' set prerequisite=:some_value';
EXECUTE IMMEDIATE sql_stmt
USING v_null;
END;
DECLARE
sql_stmt VARCHAR2(200);
v_student_id NUMBER := &sv_student_id;
v_first_name VARCHAR2(25);
v_last_name VARCHAR2(25);
BEGIN
sql_stmt := 'select first_name,last_name' || ' from student' ||
' where student_id=:1';
EXECUTE IMMEDIATE sql_stmt
INTO v_first_name, v_last_name
USING v_student_id;
dbms_output.put_line('First Name: ' || v_first_name);
dbms_output.put_line('Last Name: ' || v_last_name);
END;
輸出更多的信息:
DECLARE
sql_stmt VARCHAR2(200);
v_student_id NUMBER := &sv_student_id;
v_first_name VARCHAR2(25);
v_last_name VARCHAR2(25);
v_street VARCHAR2(50);
v_city VARCHAR2(25);
v_state VARCHAR2(2);
v_zip VARCHAR2(5);
BEGIN
sql_stmt := 'select a.first_name,a.last_name,a.street_address,b.city,b.state,b.zip' ||
' from student a,zipcode b' || '
where a.zip=b.zip' || ' and student_id=:1';
EXECUTE IMMEDIATE sql_stmt
INTO v_first_name, v_last_name, v_street, v_city, v_state, v_zip
USING v_student_id;
dbms_output.put_line('First Name: ' || v_first_name);
dbms_output.put_line('Last Name: ' || v_last_name);
dbms_output.put_line('Steet: ' || v_street);
dbms_output.put_line('City: ' || v_city);
dbms_output.put_line('State: ' || v_state);
dbms_output.put_line('Zip Code: ' || v_zip);
END;
OPEN-FOR ,FETCH,CLOSE:
DECLARE
TYPE student_cur_type IS REF CURSOR;
student_cur student_cur_type;
v_zip VARCHAR2(5) := '&sv_zip';
v_first_name VARCHAR2(25);
v_last_name VARCHAR2(25);
BEGIN
OPEN student_cur FOR 'select first_name,last_name from student' || ' where zip=:1'
USING v_zip;
LOOP
FETCH student_cur
INTO v_first_name, v_last_name;
EXIT WHEN student_cur%NOTFOUND;
dbms_output.put_line('First Name: ' || v_first_name);
dbms_output.put_line('Last Name: ' || v_last_name);
END LOOP;
CLOSE student_cur;
EXCEPTION
WHEN OTHERS THEN
IF student_cur%ISOPEN
THEN
CLOSE student_cur;
END IF;
dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
END;
同時使用open for,fetch和close語句:
DECLARE
TYPE zip_cur_type IS REF CURSOR;
zip_cur zip_cur_type;
sql_stmt VARCHAR2(500);
v_zip VARCHAR2(5);
v_total NUMBER;
v_count NUMBER;
BEGIN
sql_stmt := 'select zip,count(*) total' || ' from student ' ||
'group by zip';
v_count := 0;
OPEN zip_cur FOR sql_stmt;
LOOP
fetch zip_cur
INTO v_zip, v_total;
EXIT WHEN zip_cur%NOTFOUND;
v_count := v_count + 1;
IF v_count <= 10
THEN
dbms_output.put_line('Zip code: ' || v_zip || ' Total: ' ||
v_total);
END IF;
END LOOP;
CLOSE zip_cur;
EXCEPTION
WHEN OTHERS THEN
IF zip_cur%ISOPEN
THEN
CLOSE zip_cur;
END IF;
dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
END;
DECLARE
TYPE zip_cur_type IS REF CURSOR;
zip_cur zip_cur_type;
sql_stmt VARCHAR2(500);
v_table_name VARCHAR2(20) := '&sv_table_name';
TYPE zip_rec_type IS RECORD(
zip VARCHAR2(5),
total NUMBER);
zip_rec zip_rec_type;
v_count NUMBER;
BEGIN
dbms_output.put_line('Totals from ' || v_table_name || ' talbe');
sql_stmt := 'select zip,count(*) total' || ' from ' || v_table_name || ' ' ||
'group by zip';
v_count := 0;
OPEN zip_cur FOR sql_stmt;
LOOP
FETCH zip_cur
INTO zip_rec;
EXIT WHEN zip_cur%NOTFOUND;
v_count := v_count + 1;
IF v_count <= 10
THEN
dbms_output.put_line('Zip code: ' || zip_rec.zip || ' Total: ' ||
zip_rec.total);
END IF;
END LOOP;
CLOSE zip_cur;
EXCEPTION
WHEN OTHERS THEN
IF zip_cur%ISOPEN
THEN
CLOSE zip_cur;
END IF;
dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
END;