動態sql參數
『壹』 動態sql的使用
在介紹動態SQL前我們先看看什麼是靜態SQL
靜態SQL
靜態 SQL 語句一般用於嵌入式 SQL 應用中,在程序運行前,SQL 語句必須是確定的,例如 SQL 語句中涉及的列名和表名必須是存在的。靜態 SQL 語句的編譯是在應用程序運行前進行的,編譯的結果會存儲在資料庫內部。而後程序運行時,資料庫將直接執行編譯好的 SQL 語句,降低運行時的開銷。
動態SQL
動態 SQL 語句是在應用程序運行時被編譯和執行的,例如,使用 DB2 的互動式工具 CLP 訪問資料庫時,用戶輸入的 SQL 語句是不確定的,因此 SQL 語句只能被動態地編譯。動態 SQL 的應用較多,常見的 CLI 和 JDBC 應用程序都使用動態 SQL。
動態SQL作用
動態SQL執行方法
使用EXEC(EXECUTE的縮寫)命令和使用SP_EXECUTERSQL。
EXEC命令執行
語法
註:EXECUTE 命令有兩個用途,一個是用來執行存儲過程,另一個是執行動態SQL
不帶參數示例
在變數@SQL中保存了一個字元串,該字元串中包含一條查詢語句,再用EXEC調用保存在變數中的批處理代碼,我們可以這樣寫SQL:
EXEC ('SELECT * FROM Customers')
結果如下:
與我們直接執行SELECT * FROM Customers一樣。
帶參數示例
還是上面的示例,我們換一種寫法
DECLARE @SQL AS VARCHAR(100);
DECLARE @Column AS VARCHAR(20);
SET @Column = '姓名'
SET @SQL = 'SELECT ' + @Column + ' FROM Customers'
EXEC (@SQL)
結果如下:
SP_EXECUTERSQL執行
語法
注意:SP_EXECUTERSQL是繼EXEC後另一種執行動態SQL的方法。使用這個存儲過程更加安全和靈活,因為它支持輸入和輸出參數。注意的是,與EXEC不同的是,SP_EXECUTERSQL只支持使用Unicode字元串作為其輸入的批處理代碼。
示例
構造了一個對Customers表進行查詢的批處理代碼,在其查詢過濾條件中使用一個輸入參數@CusID
DECLARE @SQL AS NVARCHAR(100);
SET @SQL=N'SELECT * FROM Customers
WHERE 客戶ID=@CusID;'
EXEC SP_EXECUTESQL
@STMT=@SQL,
@PARMS=N'@CusID AS INT',
@CusID=1;
結果如下:
代碼中將輸入參數取值指定為1,但即使採用不同的值在運行這段代碼,代碼字元串仍然保存相同。這樣就可以增加重用以前緩存過的執行計劃的機會
『貳』 存儲過程中如何執行帶輸出參數的動態SQL
SQL Server存儲過程中執行帶輸出參數的動態sql是很多人經常碰到的問題,比如根據一些條件查詢列表,並返回記錄數等。下面是一個參考示例,查詢用戶列表,它可以利用臨時表實現翻頁,並帶有死鎖和超時檢測功能。 CREATE PRocere pUserList ( @UserType char(2), @pagenum int, @perpagesize int, @pagetotal int out, @rowcount int out ) as set nocount on DECLARE @Err INT,@ErrCounter INT declare @sql nvarchar(2000) --聲明動態sql執行語句 declare @pagecount int --當前頁數 declare @sWhere nvarchar(200) declare @sOrder nvarchar(100) set @sWhere = ' where 1=1 ' if not(@UserType is null) set @sWhere = @sWhere + ' and UserType = ' + @UserType set @sOrder = ' order by UserID ' --取得當前資料庫的記錄總數 declare @row_num int LockTimeOutRetry: --創建臨時表,作為數據過濾 create table #change (T_id int) set @sql = 'select @row_num=count(*) from dbo.[User]' + @sWhere exec sp_executesql @sql,N'@row_num int output', @row_num output if @row_num % @perpagesize =0 set @pagetotal = @row_num/@perpagesize else set @pagetotal = @row_num/@perpagesize + 1 set @rowcount = @row_num if @row_num > @perpagesize begin set @row_num = @pagenum * @perpagesize if @row_num = @perpagesize begin set @sql = N'select top ' + cast(@perpagesize as varchar) + ' UserID,LoginName,RealName from dbo.[User]' + @sWhere + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end else begin set @row_num = (@pagenum-1) * @perpagesize set @pagecount = @row_num set @sql=N'insert #change (T_id) select top ' + cast(@pagecount as varchar) + ' UserID from dbo. [User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder exec sp_executesql @sql set @sql = N'select top ' + cast(@perpagesize as varchar) + ' UserID,LoginName,RealName from dbo.[User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end end else begin set @sql = 'select UserID,LoginName,RealName from dbo.[User]' + @sWhere + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end ErrorHandler: IF (@Err = 1222 OR @Err = 1205) AND @ErrCounter = 5 BEGIN RAISERROR ('Unable to Lock Data after five attempts.', 16,1) return -100 END IF @Err = 1222 OR @Err = 1205 -- Lock Timeout / Deadlock BEGIN WAITFOR DELAY '00:00:00.25' SET @ErrCounter = @ErrCounter + 1 GOTO LockTimeOutRetry END -- else unknown error RAISERROR (@err, 16,1) WITH LOG return -100 GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO
『叄』 動態sql中如何執行 帶參數的存儲過程
exec
sp_executesql
@sqlGetCount,N'@Counts
int
out
',@Counts
out
實際上
就是通過這個sp_executesql來執行存儲過程時,會定義變數
@Counts
,然後執行你的語句把值放到@Counts
里,最後返回。
另外,本質上這個和exec語句是一樣的都是動態執行sql。
『肆』 mybatis 動態sql和參數
動態SQL,就是根據條件拼接的條件吧。
比如:if、where等等條件,都是動態sql的標簽。
參數:就是#$兩個標簽,注意下$可能會導致sql注入的問題就可以了。
『伍』 存儲過程中動態SQL中的傳入參數為datetime類型的問題
你先調試一下,少了個@和begin、end
另外,拼接變數不能在字元串內啊,這樣沒用
create procere [dbo].[baobiao1]
@date1 datetime,
@date2 datetime
as
set nocount on
begin
Set XACT_ABORT ON;
Begin Tran
Declare @SQL1 varchar(8000)
Declare @SQL2 varchar(8000)
--Set @SQL='Create view A as select ....'
--Exec(@SQL)
if exists (SELECT * FROM sysobjects WHERE name = 'report1')
begin
drop view report1
end
set @SQL1='create view report1 as select s.englishName,s.belongzu,count(*) kaitai,
jiachan=(case s.shiftName when ''甲'' then sum(s.realproc) else 0 end),
jiachaochan=(case s.shiftName when ''甲'' then sum(s.realproc-s.singleplan*s.workminute/60) else 0 end),
yichan=(case s.shiftName when ''乙'' then sum(s.realproc) else 0 end),
yichaochan=(case s.shiftName when ''乙'' then sum(s.realproc-s.singleplan*s.workminute/60) else 0 end),
bingchan=(case s.shiftName when''丙''then sum(s.realproc) else 0 end),
bingchaochan=(case s.shiftName when''丙''then sum(s.realproc-s.singleplan*s.workminute/60) else 0 end),
dingchan=(case s.shiftName when''丁''then sum(s.realproc) else 0 end),
dingchaochan=(case s.shiftName when''丁''then sum(s.realproc-s.singleplan*s.workminute/60) else 0 end),
(case when s.shiftName =''甲''then sum(p.cibushu) else 0 end) jiacibu,
(case when s.shiftName =''乙''then sum(p.cibushu) else 0 end) yicibu,
(case when s.shiftName =''丙''then sum(p.cibushu) else 0 end) bingcibu,
(case when s.shiftName =''丁''then sum(p.cibushu) else 0 end) dingcibu,
(case when s.shiftName =''甲''then sum(p.kaijianshu) else 0 end) jiakaijian,
(case when s.shiftName =''乙''then sum(p.kaijianshu) else 0 end) yikaijian,
(case when s.shiftName =''丙''then sum(p.kaijianshu) else 0 end) bingkaijian,
(case when s.shiftName =''丁''then sum(p.kaijianshu) else 0 end) dingkaijian
from HistoryPro1 s left outer join kaijianjicibu2 p on s.wholeDate = p.wholeDate AND
s.MachineID = p.MachineID AND
s.shiftName = p.shiftName where s.wholeDate >=『+@date1+『 and s.wholeDate <=』+@date2=『 group by s.englishName,s.belongzu,s.shiftName'
exec(@SQL1)
commit Tran
end
set nocount on
GO
『陸』 如何支持動態拼接SQL的參數化查詢求解答
remarkvarchar(100))go--寫入部分測試數據insertintooswica_test_table_1select1,
'oswica',''insertintooswica_test_table_1select2,
'stone',''insertintooswica_test_table_1select3,
'nana',''insertintooswica_test_table_1select4,
'nana',''go--建立存儲過程createprocoswica_proc_querytestdata(@whereSqlnvarchar(max),
@paramNameListnvarchar(max),
@paramValueListnvarchar(max))asbegindeclare@exesqlnvarchar(max)
--生成查詢語句set@exesql='EXECsp_executesqlN'
'select*fromoswica_test_table_1'
+@whereSql+''
',N'''+@paramNameList+''
','
+@paramValueList+''
print@exesqlexec(@exesql)endgo--執行存儲過程execoswica_proc_querytestdataN
'whereid=@idandname=@name',N
'@idint,@namevarchar(50)',N
'@id=1,@name=''oswica'''go--結果
--EXECsp_executesqlN'select*fromoswica_test_table_1whereid=@idandname=@name',N'@idint,@namevarchar(50)',@id=1,@name='oswica'
--idnameremark
-------------------------------------------------------------------------------------------------------------------------------------------------------------------1oswica--說明
--實際上我們不推薦直接在存儲過程中這么使用。因為這里還是存在執行代碼裡面有拼接sql的情況。
--最好的辦法是在程序代碼裡面動態拼接好然後使用參數方式動態的根據實際參數個數傳入參數,已
--實現即能夠兼容參數化查詢又能夠拼接字元串。----建議
--按照上面的說法,我們可以拼接如下sql:
--select*fromoswica_test_table_1whereid=@idandname=@name
--然後按照拼接的參數個數使用SqlCommand的Parameters動態的添加2個參數:@id和@name來達到
--目的。而在編程語言中實現動態添加參數相對比較容易,或者通過實現sqlserver的CLR存儲過程來
--達到這一目的。
『柒』 Oracle 動態SQL中如何參數化表名
表名可用變數,但一般需要用到動態sql,舉例如下:
declare
v_date varchar2(8);--定義日期變數
v_sql varchar2(2000);--定義動態sql
v_tablename varchar2(20);--定義動態表名
begin
select to_char(sysdate,'yyyymmdd') into v_date from al;--取日期變數
v_tablename := 'T_'||v_date;--為動態表命名
v_sql := 'create table '||v_tablename||'
(id int,
name varchar2(20))';--為動態sql賦值
dbms_output.put_line(v_sql);--列印sql語句
execute immediate v_sql;--執行動態sql
end;
執行以後,就會生成以日期命名的表。
『捌』 關於Java的sql動態參數
String sql = "select * from stuInfo where id = ? and name = ?";
Object[] params = {id,name};
public int executeSQL(String sql,Object[] params){
PreparedStatement psmt =conn.prepareStatement(sql);
if(params != null){
for(int i = 0 ;i<params.length;i++){
psmt.setObject((i+1),params[i]);
}
}
}
『玖』 動態sql語句如何輸出多個參數
DECLARE @FORM_KIND VARCHAR(50)
DECLARE @FORM_NO VARCHAR(50)
DECLARE @Sql NVARCHAR(1000)
declare @X nvarchar(500)
declare @Y nvarchar(500)
set @form_kind='SYS.FORM.008';
set @form_no=12500;
SET @Sql ='select 1 as num, tah.travel_purpose || ''$$'' || tah.bu_code || ''$$'' || tah.ou_code document_summary from bpm.bpm_tes_flow f,bpm.bpm_tes_ta_head tah where tah.ta_head_id=f.source_id and f.source_category=''TA''
and f.form_kind='''+@form_kind+''' and f.form_no=12500';
print @Sql
SET @Sql = 'SELECT @A=document_summary,@B=num FROM OPENQUERY(ORACLE_ERP, ''' + REPLACE(@Sql, '''', '''''') + ''')'
exec sp_executesql @Sql,N'@A NVARCHAR(500) output,@B NVARCHAR(50) OUTPUT',@X output,@Y OUTPUT
PRINT @X+'============'+@Y