Oracle dynamically executes the command execute immediate

You can use execute immediate to dynamically execute SQL statements and stored procedures. In this project, I have a class of stored procedures that start with "P_InsertInto_", followed by table names such as: P_InsertInto_AC01, P_InsertInto_AC02, etc., for AC01, AC02. ...... If data is inserted into these tables, we can only use execute immediate to dynamically execute these processes, which will be much more convenient in terms of speed and code writing. This method has been studied for a long time, and it is not easy, huh, huh. . . . , and finally succeeded! My understanding of the usage of execute immediate is illustrated with an example. There is a stored procedure named: p_test, which has three parameters: two input parameters and one output parameter. The implementation process is as follows: declare v_sql varchar2(1000) ; c varchar2(1000); a varchar2(1) :='1'; b number :=1; begin -- of course, dynamic stored procedures can be implemented here, just put them in the variable v_sql (here is a specified procedure p_test) v_sql:='begin p_test(:v1,:v2,:v3); end;'; execute immediate v_sql using    

 








        in '1',in '2', out   c;
--or execute immediate v_sql using '1', '2', out c; dbms_output.put_line(c); end; Above we have implemented dynamic passing parameters and dynamic The calling method of the stored procedure. It is worth noting that: the default is in, in can be saved, out cannot be saved! There is another point worth noting: each dynamic ( execute immediate ) method has its own begin.........end; just wrap it, if there are more than one, just write: - - first begin v_sql:='begin p_test1(:v1,:v2,:v3); end;'; execute immediate v_sql using in '1',in '2', out c; --or execute immediate v_sql using          



 



         
        '1', '2', out   c;
dbms_output.put_line(c);
end;
--第二个
begin
v_sql:='begin p_test2(:v1,:v2,:v3); end;';
execute immediatev_sql usingin '1',in '2', outc; --或 executeimmediatev_sql using'1', '2', outc; dbms_output.put_line(c); end; 。。。。。。。 --第N个 begin -- end;          
         








 

 

EXECUTE IMMEDIATE replaces the previous DBMS_SQL package in Oracle8i. It parses and immediately executes dynamic SQL statements or PL/SQL blocks created by non-runtime. Dynamically create and execute SQL statements with advanced performance. The goal of EXECUTE IMMEDIATE is to reduce enterprise costs and Get higher performance and it's much easier to code than before. Although DBMS_SQL is still available, EXECUTE IMMEDIATE is recommended because it benefits over the package.   

skills

 

1. EXECUTE IMMEDIATE does not automatically submit a DML operation, and requires manual submission or rollback  

If the DML command is processed via EXECUTE IMMEDIATE , then it needs to be committed either explicitly or as part of EXECUTE IMMEDIATE itself. If the DDL command is processed via EXECUTE IMMEDIATE , it commits all previously changed data   

 

2. Queries that return multiple rows are not supported. This interaction will use temporary tables to store records (see example below) or use REF cursors.

 

3. When executing SQL statements, do not use semicolons, when executing PL/SQL blocks, use semicolons at the end of them.

 

4. In the Oracle manual, these functions are not covered in detail. The following example shows all possible aspects of using Execute immediate . Hope it will bring you convenience. 

 

5. For Forms developers, when in PL/SQL 8.0.6.3. version, Forms 6i cannot use this feature.

 

EXECUTE IMMEDIATE usage example 

 Oracle 's execute immediate can dynamically execute SQL statements. The following summarizes the usage of this statement:
1. execute immediate will not automatically commit DML transaction execution, it needs to be explicitly committed or as part of the execute immediate statement. (refer to the code below)

  1. SQL> create table PEOPLE_T(
  2.   2 id number,
  3.   3 name varchar(50)
  4.   4 );
  5.  
  6. Table created
  7. SQL> set serveroutput on;
  8. SQL> declare
  9.   2 cnt integer;
  10.   3 begin
  11.   4 execute immediate 'insert into people_t values(1, ''zhangsan'')';
  12.   5 rollback;
  13.   6 select count(*) into cnt from people_t;
  14.   7 dbms_output.put_line(cnt);
  15.   8 end;
  16.   9 /
  17.  
  18. 0
  19.  
  20. PL/SQL procedure successfully completed
  21.  
  22. SQL>

The above code and results can prove that execute immediate does not automatically submit DML operations. In the following code, we commit manually:

  1. SQL> declare
  2.   2 cnt integer;
  3.   3 begin
  4.   4 execute immediate 'insert into people_t values (2, ''Lisi'')';
  5.   5 commit;
  6.   6 select count(*) into cnt from people_t;
  7.   7 dbms_output.put_line(cnt || ' records after commit');
  8.   8 end;
  9.   9 /
  10.  
  11. 1 records after commit
  12.  
  13. PL/SQL procedure successfully completed

It can be seen that after the manual submission, the records of the DML statement are inserted into the table. Of course, the commit statement can also be executed dynamically in the following way, but it has little practical significance with manual commit:

  1. SQL> declare
  2.   2 cnt integer;
  3.   3 begin
  4.   4 execute immediate 'insert into people_t values (3, ''Wangwu'')';
  5.   5 execute immediate 'commit';
  6.   6 select count(*) into cnt from people_t;
  7.   7 dbms_output.put_line(cnt || ' records after commit');
  8.   8 end;
  9.   9 /
  10.  
  11. 2 records after commit
  12.  
  13. PL/SQL procedure successfully completed
  14.  
  15. SQL>

2. When executing sql statement, semicolon is not required at the end; when executing pl/sql block, semicolon is required at the end.    The following code shows incorrect syntax:
   

  1. SQL> begin
  2.   2 execute immediate 'insert into people_t values (1, ''Zhangsan'');';
  3.   3 end;
  4.   4 /
  5.  
  6. begin
  7.   execute immediate 'insert into people_t values (1, ''Zhangsan'');';
  8. end;
  9.  
  10. ORA-00911: invalid character
  11. ORA-06512: at line 3
  12.  
  13. SQL>
  1. SQL> begin
  2.   2 execute immediate 'begin insert into people_t values (1, ''Zhangsan''); end';
  3.   3 end;
  4.   4 /
  5.  
  6. begin
  7.   execute immediate 'begin insert into people_t values (1, ''Zhangsan''); end';
  8. end;
  9.  
  10. ORA-06550: line 1, column 54:
  11. PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
  12.    ; <an identifier> <a double-quoted delimited-identifier>
  13. The symbol ";" was substituted for "end-of-file" to continue.
  14. ORA-06512: at line 3
  15.  
  16. SQL>

3. Run DDL statements in PL/SQL


begin
executeimmediate'set role all';end;  

 

4. Passing values ​​to dynamic statements ( USING  clause)


declare
l_depnam varchar2(20) := 'testing';
l_loc    varchar2(10) := 'Dubai';
begin
executeimmediate'insert into dept values (:1, :2, :3)'using50, l_depnam, l_loc;commit;end;  
     

 

5. Retrieving values ​​from dynamic statements (INTO clause)


declare
l_cnt    varchar2(20);
begin
executeimmediate'select count(1) from emp'into l_cnt;dbms_output.put_line(l_cnt);end;  
    

 

6. Dynamically call the routine. The bound variable parameters used in the routine must specify the parameter type. It is considered that the IN type, other types must be explicitly specified

 

declare
l_routin   varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam   varchar2(20) := 'emp';
l_cnt      number;
l_status   varchar2(200);
begin
executeimmediate'begin ' || l_routin || '(:2, :3, :4); end;'usingin l_tblnam,outl_cnt, inoutl_status;  
         

if l_status != 'OK' then
     dbms_output.put_line('error');
end if;
end;

 

7. Pass the return value to the PL/SQL record type; also use the %rowtype variable


declare
type empdtlrec is record (empno number(4),
                           ename varchar2(20),
                           deptno number(2));
empdtl empdtlrec;
begin
executeimmediate'select empno, ename, deptno ' ||'from emp where empno = 7934'into empdtl;end;  
                   
    

 

8. Pass and retrieve values. The INTO clause is used before the USING clause

 

declare
l_dept    pls_integer := 20;
l_nam     varchar2(20);
l_loc     varchar2(20);
begin
executeimmediate'select dname, loc from dept where deptno = :1'into l_nam, l_locusingl_dept ;end;  
    
     

 

9. Multi-line query option. For this option, use insert statement to fill the temporary table, use the temporary table for further processing, or use REF cursors to correct this defect.

declare
l_sal pls_integer    :  = 2000;
begin
execute immediate 'insert into temp(empno , ename) ' || '          select empno, ename from emp ' || '          where sal > :1' using l_sal; commit; end;  
                    
                    
     

 

       For handling dynamic statements, EXECUTE IMMEDIATE is easier and more efficient than previously possible. Appropriate handling of exceptions is even more important when dynamic statements are intended to be executed. Attention should be paid to catching all possible exceptions. 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326943432&siteId=291194637