pl/sql-native dynamic sql

To process dynamic SQL statements, you use EXECUTE IMMEDIATE or OPEN-FOR, FETCH,
and CLOSE statements. EXECUTE IMMEDIATE is used for single-row SELECT statements, all
DML statements, and DDL statements. OPEN-FOR, FETCH, and CLOSE statements are used
for multirow SELECTs and reference cursors.

 

Part One: execute immediate

EXECUTE IMMEDIATE dynamic_SQL_string
[ INTO defined_variable1, defined_variable2, ...]
[ USING [IN | OUT | IN OUT] bind_argument1, bind_argument2,
...][{ RETURNING | RETURN } field1, field2, ... INTO bind_argument1,

bind_argument2, ...] 

 

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
     --  and 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; ' ;
    
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 ;

 


 

 

NOte that:
CREATE TABLE statement is a data definition statement(DDL). Therefore, it cannot accept any  bind
arguments. Following example will generate error:

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 = :zip ' ;
    
EXECUTE  IMMEDIATE sql_stmt USING v_zip;
    
--  Select total number of records from MY_STUDENT table
     --  and 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

 

DECLARE
*
ERROR at line 1:
ORA-01027: bind variables not allowed for data definition operations

ORA-06512: at line 12 

 

 

 

 

DECLARE
    sql_stmt 
VARCHAR2 ( 100 );
    v_zip 
VARCHAR2 ( 5 ) : =   ' 11106 ' ;
    v_total_students 
NUMBER ;
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
     --  and display results on the screen
     EXECUTE  IMMEDIATE  ' SELECT COUNT(*) FROM :my_table '
    
INTO  v_total_students
    USING 
' my_student ' ;
    DBMS_OUTPUT.PUT_LINE (
' Students added:  ' ||  v_total_students);
END ;


When  run, this example causes the following error:
DECLARE
*
ERROR at line 
1 :
ORA
- 00903 : invalid  table  name
ORA
- 06512 : at line  13

This example causes an error because you cannot pass names 
of schema objects to dynamic SQL
statements 
as bind arguments. 
To  provide a  table  name at runtime, you need  to  concatenate this
example 
with  the  SELECT  statement:

EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||my_table
INTO v_total_students;

 

Notice: The semicolon added to the SELECT statement is treated as an invalid character when the statement
is created dynamically. A somewhat similar error is generated when a PL/SQL block is

terminated by a slash: 

 

Part Two: OPEN-FOR, FETCH, and CLOSE Statements

below is an example :

 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;
    ...

 

 

你可能感兴趣的:(dynamic sql)