動態sqlusing
① 動態sql語句裡面,USING後面一定要跟常數嗎
不用using就相當於你沒有傳入參數,這樣動態sql的變數就可能被輸入成了null,所以你的動態sql有可能出錯
② 在執行動態SQL語句時,事物處理不能釋放如何解決
在 execute immediate :ls_sql using sqlca;後
寫上
if sqlca.sqlcode=0 then
commit using sqlca;
else
rollback using sqlca;
messagebox('提交錯誤','錯誤原因:~r~n'+sqlca.sqlerrtext)
end if
③ oracle中動態sql中的using、into各是什麼作用通俗地講,別用書面語
using 指的是where條件中的變數
into 指的是要獲取的數據變數
比如說
V_SQL_T := 'SELECT SUM(QTY), SUM(COST * QTY)
FROM SALES
WHERE SALE_DATE = :1';
EXECUTE IMMEDIATE V_SQL_T
INTO T_QTY, T_AMT
USING D_SALESDATE;
上面INTO就是要sum(qty)和sum(cost*qty)賦值到t_qty和t_amt兩個變數,using就是把d_salesdate變數代入:1作為條件
④ 動態SQL中的重復佔位符如何與綁定變數進行
BEGIN calc_stats(:x, :x, :y, :x); END 是一個PL/SQL 代碼段,而非 insert into t6 (a,b,c) values (:x,:y,:x) 這樣的DML,標准SQL語句。
在EXECUTE IMMEDIATE 中,利用USING語句綁定變數時,Oracle遵循針對PL/SQL存儲過程使用佔位符名稱匹配的原則,而針對SQL語句則採用佔位符位置匹配的原則。
PL/SQL 用戶指南與參考 中的 例子如下:
動態SQL語句中的佔位符與USING子句中的綁定參數是位置關聯的,而不是名稱關聯。所以,如果在SQL語句中同樣的佔位符出現兩次或多次,那麼,它的每次出現都必須與一個USING子句中的綁定參數相關聯。例如下面的動態字元串:
sql_stmt := 'INSERT INTO payroll VALUES (:x, :x, :y, :x)';
我們可以為動態字元串編寫對應的USING子句:
EXECUTE IMMEDIATE sql_stmt USING a, a, b, a;
但 是,動態PL/SQL塊中只有唯一的佔位符才與USING子句中的綁定參數按位置對應。所以,如果一個佔位符在PL/SQL塊中出現兩次或多次,那麼所有 這樣相同的佔位符都只與USING語句中的一個綁定參數相對應。比如下面的例子,第一個佔位符(x)與第一個綁定參數(a)關聯,第二個佔位符(y)與第 二個綁定參數(b)關聯。
DECLARE
a NUMBER := 4;
b NUMBER := 7;
BEGIN
plsql_block := 'BEGIN calc_stats(:x, :x, :y, :x); END';
EXECUTE IMMEDIATE plsql_block
USING a, b;
...
END;
---------------------------------------------------------------------------------------------
CREATE TABLE T1 (N1 NUMBER, N2 NUMBER,N3 NUMBER,N4 NUMBER);
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO T1(N1,N2,N3,N4) VALUES (:N1,:N2,:N2,:N1)' USING 1,2;
END;
/
*
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 2
BEGIN
EXECUTE IMMEDIATE 'BEGIN INSERT INTO T1(N1,N2,N3,N4) VALUES (:N1,:N2,:N2,:N1); END;' USING 1,2;
END;
/
PL/SQL procere successfully completed.
SELECT * FROM T1;
N1 N2 N3 N4
---------- ---------- ---------- ----------
1 2 2 1
----------------------------------------------
⑤ oracle中的using怎麼用啊
V_SQLSTR := 'INSERT INTO ' || V_TABLENAME || '(' ||
' SELECT DISTINCT KBP,KPI_NO,DCTIME,:1 WRITETIME,TO_NUMBER(VALUE) ' ||
' FROM BIZMAN_PM_TEMP )';
這是一個動態的SQL,即通過EXECUTE IMMEDIATE來執行一個字元串的SQL,而這裡面通過冒號開頭的是參數,EXECUTE IMMEDIATE後邊USING的順序就是裡面參數的順序。您這裡面對應的就是:1,即把V_CURRENTTIME的值代入到冒號1的位置,執行這個插入語句。
USING OUT:如果動態SQL中有一個過程,而該過程的有個OUT 參數,此時就可以用USING OUT 的方式
⑥ 動態sql中怎麼綁定多個重復出現參數
目前我知道的綁定方式是按順序一個個對應著動態sql的佔位符,如
open cur_Record for L_sql using P_TestKey,P_SchoolKey,P_TestKey,P_TestKey,P_ClassKey
但我想問的是有沒有其他的綁定方法,如簡化成
open cur_Record for L_sql using P_TestKey,P_SchoolKey,P_ClassKey
這樣的話比較簡潔清晰
⑦ orcale中的動態SQL
第一、按照你貼出來的代碼片段考慮,沒必要必須用動態SQL;
第二、你改的那樣細節不對,先解釋這句SQL,它需要傳入一個參數,execute immediate 後面跟的是一個字元串,所以需要放在 一對單引號中,如
execute immediate 'select name,salary from emp where id=:1',而這里的 :1 是佔位用的,即需要搭配 using 傳入動態參數,:1 代表 using 後的第一個參數 p_id,如果有 :2,以此類推……;
第三:換為你的思路,那這句SQL應該這樣,參數是拼接上:
execute immediate 'select name,salary from emp where id=' || p_id returning into ……;
第四:你這個情景,可以不用動態sql,直接begin select …… into …… from …… where …… exception …… end; 即可;
⑧ using(){}
會的,using相當於try catch finally 語句, 在finally子句里釋放資源
無論try..catch子句里何時return,finally子句都一定執行的
⑨ 如何使用動態SQL語句
SQL文本在編譯時是未知的。
例如,SELECT語句包含的標識符(如表名)在編譯時是未知的,或者WHERE子句的條件數量在編譯時是未知。
靜態SQL不支持
例如,在PL/SQL中用靜態SQL只能執行查詢以及DML語句。如果想要執行DDL語句,只能使用動態SQL。
當讓使用靜態SQL,也有它的好處:
編譯成功驗證了靜態SQL語句引用有效的資料庫對象和訪問這些對象的許可權
編譯成功創建了模式對象的依賴關系
動態SQL語句是一個最多隻能返回一行的SELECT語句
使用動態SQL語句返回單列,查詢SCOTT的薪水:
declare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'SCOTT';
begin
v_sql_text := 'select e.sal from emp e where e.ename = :ename';
execute immediate v_sql_text
into v_sal
using v_ename;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
使用動態SQL返回一條記錄,查詢SCOTT的基本信息:
declare
v_sql_text varchar2(1000);
v_ename emp.ename%type := 'SCOTT';
vrt_emp emp%rowtype;
begin
v_sql_text := 'select * from emp e where e.ename = :ename';
execute immediate v_sql_text
into vrt_emp
using v_ename;
dbms_output.put_line(v_ename || '的基本信息:');
dbms_output.put_line('工號:' || vrt_emp.empno);
dbms_output.put_line('工資:' || vrt_emp.sal);
dbms_output.put_line('入職日期:' || vrt_emp.hiredate);
end;
⑩ 如何動態執行sql語句
這里只介紹動態SQL的使用。關於動態SQL語句的語法,參見:http://blog.csdn.NET/chiclewu/article/details/16097133
1.什麼是時候需要使用動態SQL?
SQL文本在編譯時是未知的。
例如,SELECT語句包含的標識符(如表名)在編譯時是未知的,或者WHERE子句的條件數量在編譯時是未知。
靜態SQL不支持
例如,在PL/SQL中用靜態SQL只能執行查詢以及DML語句。如果想要執行DDL語句,只能使用動態SQL。
當讓使用靜態SQL,也有它的好處:
編譯成功驗證了靜態SQL語句引用有效的資料庫對象和訪問這些對象的許可權
編譯成功創建了模式對象的依賴關系
2.EXECUTE IMMEDIATE語句
EXECUTE IMMEDIATE語句的意思是使用本地動態SQL處理大多數動態SQL語句。
如果動態SQL語句是自包含的(也就是說,它的綁定參數沒有佔位符,並且結果不可能返回錯誤),則EXECUTE IMMEDIATE語句不需要子句。
如果動態SQL語句包行佔位符綁定參數,每個佔位符在EXECUTE IMMEDIATE語句的子句中必須有一個相應的綁定參數,具體如下:
如果動態SQL語句是一個最多隻能返回一行的SELECT語句,OUT綁定參數放置在INTO子句,IN綁定參數放置在USING子句。
如果動態SQL語句是一個可以返回多行的SELECT語句,OUT綁定參數放置在BULK COLLECT INTO子句,IN綁定參數放置在USING子句。
如果動態SQL語句是一個除了SELECT以外的其他DML語句,且沒有RETURNING INTO子句,所有的綁定參數放置在USING子句中。
如果動態SQL還語句一個匿名PL/SQL塊或CALL語句,把所有的綁定參數放置在USING子句中。
如果動態SQL語句調用一個子程序,請確保:
每個對應子程序參數佔位符的綁定參數與子程序參數具有相同的參數模式和兼容的數據類型。
綁定參數不要有SQL不支持的數據類型(例如,布爾類型,關聯數組,以及用戶自定的記錄類型)
USING子句不能包含NULL字面量。如果想要在USING子句中使用NULL值,可以使用位初始化的變數或者函數顯示將NULL轉換成一個有類型的值。
2.1動態SQL語句是一個最多隻能返回一行的SELECT語句
使用動態SQL語句返回單列,查詢SCOTT的薪水:
declare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'SCOTT';
begin
v_sql_text := 'select e.sal from emp e where e.ename = :ename';
execute immediate v_sql_text
into v_sal
using v_ename;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
使用動態SQL返回一條記錄,查詢SCOTT的基本信息:
declare
v_sql_text varchar2(1000);
v_ename emp.ename%type := 'SCOTT';
vrt_emp emp%rowtype;
begin
v_sql_text := 'select * from emp e where e.ename = :ename';
execute immediate v_sql_text
into vrt_emp
using v_ename;
dbms_output.put_line(v_ename || '的基本信息:');
dbms_output.put_line('工號:' || vrt_emp.empno);
dbms_output.put_line('工資:' || vrt_emp.sal);
dbms_output.put_line('入職日期:' || vrt_emp.hiredate);
end;
2.2動態SQL語句是一個可以返回多行的SELECT語句
2.2.1隻有一個佔位符
使用動態SQL語句返回多行記錄,查詢30部門的員工基本信息:
declare
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 30;
type nt_emp is table of emp%rowtype;
vnt_emp nt_emp;
begin
v_sql_text := 'select * from emp e where e.deptno = :deptno';
execute immediate v_sql_text bulk collect
into vnt_emp
using v_deptno;
for i in 1 .. vnt_emp.count loop
dbms_output.put_line(vnt_emp(i).ename || '的基本信息:');
dbms_output.put_line('工號:' || vnt_emp(i).empno);
dbms_output.put_line('工資:' || vnt_emp(i).sal);
dbms_output.put_line('入職日期:' || vnt_emp(i).hiredate);
dbms_output.put_line('');
end loop;
end
2.2.2多個佔位符
查詢20部門工資大於2000的員工基本信息:
declare
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 20;
v_sal number := 2000;
type nt_emp is table of emp%rowtype;
vnt_emp nt_emp;
begin
v_sql_text := 'select * from emp e where e.sal>:sal and e.deptno = :deptno';
execute immediate v_sql_text bulk collect
into vnt_emp
using v_sal, v_deptno; --注意綁定多個變數時,綁定變數只與佔位符位置有關,與佔位符名稱無關,
for i in 1 .. vnt_emp.count loop
dbms_output.put_line(vnt_emp(i).ename || '的基本信息:');
dbms_output.put_line('工號:' || vnt_emp(i).empno);
dbms_output.put_line('工資:' || vnt_emp(i).sal);
dbms_output.put_line('入職日期:' || vnt_emp(i).hiredate);
dbms_output.put_line('');
end loop;
注意:對於SQL文本,佔位符名稱是沒有意義的,綁定變數與佔位符名稱無關,只與佔位符的配置有關。即使有多個相同名稱佔位符,也需要每個佔位符對應一個綁定變數。對於PL/SQL塊,佔位符名稱是有意義的,相同名稱的佔位符,只需要第一個佔位符綁定變數。
2.3動態SQL語句是一個帶有RETURNING子句的DML語句
KING的工資增長20%,返回增長後的工資:
eclare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'KING';
begin
v_sql_text := 'update emp e set e.sal= e.sal*1.2 where e.ename = :ename returning e.sal into :sal';
execute immediate v_sql_text
using v_ename
returning into v_sal;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
注意:只有當v_sql_text語句有returning into子句時,動態SQL語句才能使用returning into子句。
2.4給佔位符傳遞NULL值
2.4.1通過未初始化變數傳遞NULL值
declare
v_sql_text varchar2(1000);
v_deptno emp.ename%type := 'ALLEN';
v_comm emp.comm%type;
begin
v_sql_text := 'update emp e set e.comm = :comm where e.ename =:ename';
execute immediate v_sql_text
using v_comm, v_deptno;
end;
2.4.2通過函數將NULL值顯式的轉換成一個有類型的值
declare
v_sql_text varchar2(1000);
v_deptno emp.ename%type := 'ALLEN';
begin
v_sql_text := 'update emp e set e.comm = :comm where e.ename =:ename';
execute immediate v_sql_text
using to_number(null), v_deptno;
end;
3.OPEN FOR語句
PL/SQL引入OPEN FOR語句實際上並不是為了支持本地動態SQL,而是為了支持游標變數。現在它以一種極其優雅的方式實現了多行的動態查詢。
使用OPEN FOR語句來關聯動態SQL語句的游標變數,在OPEN FOR語句的USING子句中,指定動態SQL語句每個佔位符的綁定參數。
使用FETCH語句獲取運行時結果集。
使用CLOSE語句關閉游標變數
使用OPEN FOR語句查詢出10部門的員工的基本信息:
declare
type rc_emp is ref cursor;
vrc_emp rc_emp;
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 10;
vrt_emp emp%rowtype;
begin
v_sql_text := 'select * from emp e where e.deptno=:deptno';
open vrc_emp for v_sql_text
using v_deptno;
loop
exit when vrc_emp%notfound;
fetch vrc_emp
into vrt_emp;
dbms_output.put_line(vrt_emp.ename || '的基本信息:');
dbms_output.put_line('工號:' || vrt_emp.empno);
dbms_output.put_line('工資:' || vrt_emp.sal);
dbms_output.put_line('入職日期:' || vrt_emp.hiredate);
dbms_output.put_line('');
end loop;
close vrc_emp;
end;
4.重復的佔位符名稱
如果在動態SQL語句重復佔位符名稱,要知道佔位符關聯綁定參數的方式依賴於動態語句的類型。
如果執行的是一個動態SQL字元串,則必須為每一個佔位符提供一個綁定參數,即使這些佔位符是重復的。
如果執行的是一個動態PL/SQL塊,則必須為每一個唯一佔位符提供一個綁定參數,即重復的佔位符只需要提供一個綁定參數。
4.1重復佔位符的動態SQL字元串
declare
v_sql_text varchar2(1000);
v_sal emp.sal%type := 4000;
v_comm emp.comm%type;
v_ename emp.ename%type := 'SCOTT';
begin
v_sql_text := 'update emp e set e.sal=:sal , e.comm = :sal*0.1 where e.ename =:ename returning e.comm into :comm ';
execute immediate v_sql_text
using v_sal, v_sal, in v_ename
returning into v_comm;
dbms_output.put_line(v_ename || '分紅:' || v_comm);
end;
4.2重復佔位符的動態PL/SQL塊
declare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'KING';
begin
v_sql_text := ' begin select e.sal,e.ename into :sal,:ename from emp e where e.ename =:ename; end;';
execute immediate v_sql_text
using out v_sal, in out v_ename;
dbms_output.put_line(v_ename || ':' || v_sal);
end;