Oracle動態SQL語句
阿新 • • 發佈:2018-12-30
在使用ODP.NET進行Oracle程式設計時,有時候SQL語句非常複雜,需要採用動態構造查詢語句的情況,有兩種方法可以構造動態的SQL語句,並執行返回結果集。
1、在資料訪問層構造SQL語句
例如下面的語句,將構造完整的SQL語句賦值給CommandText,再傳遞到資料庫進行執行,返回結果集。
loadCommand.CommandType = CommandType.TextloadCommand.CommandText = "Select * From Users"
dataAdapter .SelectCommand = loadCommand
dataAdapter . Fill(data)
dataAdapter .SelectCommand = loadCommand
dataAdapter . Fill(data)
該方法需要將整個SQL的構造過程放在DataAccess層,業務邏輯發生變化,修改不方便,而且每次查詢需要傳遞給資料庫很長的查詢字串,傳遞引數的效率也不高。
2、在儲存過程中構造動態SQL語句並執行
以下為一個完整的事例(經過刪減),其中RefCursor 為自定義遊標型別
PROCEDURE G_Search(P_YearNO INNUMBER,P_ControlType
P_Progress INCHAR,
P_DepartID INVARCHAR2,
P_ProjectName IN NVARCHAR2,
C_Projects OUT RefCursor) IS
e_ErrInterruption EXCEPTION;
v_ErrID NUMBER; --
v_DepartID VARCHAR2(16);
v_ProjectName NVARCHAR2(128);
v_SQL VARCHAR2(512);
v_Where VARCHAR2(256);
BEGIN
v_SQL :='SELECT PROJECTID, PARENTID, PROJECTNAME ';
v_SQL := v_SQL ||' FROM PROJECTS A';
v_Where :=' Where';
-- 年度IF P_YearNO <9999THEN
v_Where := v_Where ||' A.YearNO = '|| P_YearNO ||' And';
ELSE
v_Where := v_Where ||' A.YearNO < '|| P_YearNO ||' And';
ENDIF;
-- 控制類別IF P_ControlType =9THEN
v_Where := v_Where ||' A.ControlType < 9 And';
ELSE
v_Where := v_Where ||' A.ControlType = '|| P_ControlType ||' And';
ENDIF;
-- 進度IF P_Progress <'Z'THEN
v_Where := v_Where ||' A.Progress = '''|| P_Progress ||''' And';
ELSE
v_Where := v_Where ||' A.Progress < '''|| P_Progress ||''' And';
ENDIF;
IF TRIM(P_DepartID) <>'%'THEN
v_Where := v_Where ||' A.DepartID = '''|| P_DepartID ||''' And';
ELSE
v_Where := v_Where ||' A.DepartID Like '''|| P_DepartID ||''' And';
ENDIF;
--專案名稱 v_ProjectName := NVL(P_ProjectName,
'%');
IF v_ProjectName <>'%'THEN
v_ProjectName :='%'|| P_ProjectName ||'%';
ENDIF;
v_Where := v_Where ||' A.ProjectName Like '||''''|| v_ProjectName ||''' And';
v_SQL := v_SQL || v_Where;
OPEN C_PROJECTS FOR v_SQL;
--COMMIT; EXCEPTION
--根據需要定義錯誤異常WHEN OTHERS THEN--ROLLBACK; v_ErrID := SQLCODE;
v_ErrText := SQLERRM;
raise_application_error(v_ErrID,
v_ErrText);
END G_Search;
該方法只需要傳遞給儲存過程一些引數,使用遊標返回資料。引數傳遞效率較高,而且業務邏輯在儲存過程中,調整比較方便。該方法關鍵的在下面的語句:
Open C_Projects For v_SQL;
它直接使用遊標開啟構造的查詢字串即可。
注意事項:
A)、構造的SQL語句最後不能帶有分號;
B)、SQL語句中對於字元和字串的條件需要用單引號包括起來
C)、最重要:動態SQL語句需要防止SQL注入攻擊。我們採用最簡單的辦法,只允許一個關鍵詞查詢,將關鍵詞中的所有空格去掉。對於多關鍵詞,需要將他們用空格拆開,再構造。