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)
- SQL> create table PEOPLE_T(
- 2 id number,
- 3 name varchar(50)
- 4 );
- Table created
- SQL> set serveroutput on;
- SQL> declare
- 2 cnt integer;
- 3 begin
- 4 execute immediate 'insert into people_t values(1, ''zhangsan'')';
- 5 rollback;
- 6 select count(*) into cnt from people_t;
- 7 dbms_output.put_line(cnt);
- 8 end;
- 9 /
- 0
- PL/SQL procedure successfully completed
- SQL>
The above code and results can prove that execute immediate does not automatically submit DML operations. In the following code, we commit manually:
- SQL> declare
- 2 cnt integer;
- 3 begin
- 4 execute immediate 'insert into people_t values (2, ''Lisi'')';
- 5 commit;
- 6 select count(*) into cnt from people_t;
- 7 dbms_output.put_line(cnt || ' records after commit');
- 8 end;
- 9 /
- 1 records after commit
- 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:
- SQL> declare
- 2 cnt integer;
- 3 begin
- 4 execute immediate 'insert into people_t values (3, ''Wangwu'')';
- 5 execute immediate 'commit';
- 6 select count(*) into cnt from people_t;
- 7 dbms_output.put_line(cnt || ' records after commit');
- 8 end;
- 9 /
- 2 records after commit
- PL/SQL procedure successfully completed
- 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:
- SQL> begin
- 2 execute immediate 'insert into people_t values (1, ''Zhangsan'');';
- 3 end;
- 4 /
- begin
- execute immediate 'insert into people_t values (1, ''Zhangsan'');';
- end;
- ORA-00911: invalid character
- ORA-06512: at line 3
- SQL>
- SQL> begin
- 2 execute immediate 'begin insert into people_t values (1, ''Zhangsan''); end';
- 3 end;
- 4 /
- begin
- execute immediate 'begin insert into people_t values (1, ''Zhangsan''); end';
- end;
- ORA-06550: line 1, column 54:
- PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
- ; <an identifier> <a double-quoted delimited-identifier>
- The symbol ";" was substituted for "end-of-file" to continue.
- ORA-06512: at line 3
- 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.