此文章主要向大家講述的是非動(dòng)態(tài)SQL ServerSQL語句執(zhí)行動(dòng)態(tài)查詢,在實(shí)際操作中我嘗試在一個(gè)存儲(chǔ)過程中,來進(jìn)行傳遞一系列以逗號(hào)劃定界限的值,來對(duì)結(jié)果集進(jìn)行限制。但是無論什么時(shí)候,我在IN子句中使用變量,都會(huì)得到錯(cuò)誤信息。
是否存在一種不執(zhí)行動(dòng)態(tài)SQL語句也能完成查詢的方式呢?
我嘗試在一個(gè)存儲(chǔ)過程中傳遞一系列以逗號(hào)劃定界限的值,以限制結(jié)果集。但是無論什么時(shí)候,我在IN子句中使用變量,都會(huì)得到錯(cuò)誤信息。是否存在一種不執(zhí)行動(dòng)態(tài)SQL ServerSQL語句也能完成查詢的方式呢?
專家解答:
這里存在一種不執(zhí)行動(dòng)態(tài)SQL ServerSQL語句也能完成查詢的方式,但是首先讓我們來探究這個(gè)問題。我將在以下例子中運(yùn)用AdventureWorks數(shù)據(jù)庫。
在你只有一個(gè)值的時(shí)候,執(zhí)行將不會(huì)有什么問題。
Declare @ManagerIDs Varchar(100)
Set @ManagerIDs = '3'
Select * from HumanResources.Employee
Where ManagerID IN (@ManagerIDs)
但是一旦你增加逗號(hào),結(jié)果就會(huì)大致如下:
Declare @ManagerIDs Varchar(100)
Set @ManagerIDs = '3,6'
Select * from HumanResources.Employee
Where ManagerID IN (@ManagerIDs)
Msg 245, Level 16, State 1, Line 4
Conversion failed when converting the varchar value '3,6' to data type int.
這是因?yàn)镾QL Sever分辨出ManagerID列是一個(gè)整數(shù),因此會(huì)自動(dòng)把@ManagerIDs轉(zhuǎn)換成變量。
為了解決這個(gè)問題,你可以運(yùn)用動(dòng)態(tài)SQL執(zhí)行這個(gè)語句。這樣,你就能在執(zhí)行它之前動(dòng)態(tài)地建立整個(gè)查詢。
Declare @ManagerIDs Varchar(100)
Set @ManagerIDs = '3,6'
Declare @SQL Varchar(1000)
Set @SQL =
'Select * from HumanResources.Employee
Where ManagerID IN (' + @ManagerIDs + ')'
EXEC (@SQL)
這樣能讓你執(zhí)行這個(gè)查詢,但是動(dòng)態(tài)SQL是個(gè)危險(xiǎn)分子,在一些特定的組織中甚至不被允許使用。
那么你要如何在不使用動(dòng)態(tài)SQL的情況下執(zhí)行查詢呢?可以通過XML實(shí)現(xiàn)。
第一步,你需要從一個(gè)以逗劃定界限的字符串中產(chǎn)生一個(gè)XML字段。
Declare @ManagerIDs Varchar(100)
Set @ManagerIDs = '3,6'
DECLARE @XmlStr XML
SET @XmlStr =
--Start Tag
'' +
--Replace all commas with an ending tag and start a new tag
REPLACE( @ManagerIDs, ',', '') +
--End Tag
''
接著,選擇這個(gè)XML值,結(jié)果顯示如下:
既然你有一個(gè)XML字段,我們就可以查詢它,結(jié)果按行顯示如下:
SELECT x.ManagerID.value('.', 'INT') AS A
FROM @XmlStr.nodes('//ManagerID') x(ManagerID)
現(xiàn)在,你可以利用之前的查詢來限制結(jié)果:
SELECT *
FROM HumanResources.Employee
WHERE ManagerID IN(
SELECT x.ManagerID.value('.', 'INT') AS A
FROM @XmlStr.nodes('//ManagerID') x(ManagerID)
)
或者,你可以利用Inner Join來限制結(jié)果:
SELECT *
FROM HumanResources.Employee AS A
INNER JOIN
(SELECT x.ManagerID.value('.', 'INT') AS ManagerID
FROM @XmlStr.nodes('//ManagerID') x(ManagerID)) B
ON A.ManagerID = B.ManagerID
上述的相關(guān)內(nèi)容就是對(duì)非動(dòng)態(tài)SQL ServerSQL語句執(zhí)行動(dòng)態(tài)查詢的描述,希望會(huì)給你帶來一些幫助在此方面。
您可能感興趣的文章:- PHP實(shí)現(xiàn)mysqli批量執(zhí)行多條語句的方法示例
- SQL SERVER 中構(gòu)建執(zhí)行動(dòng)態(tài)SQL語句的方法
- mybatis 插件: 打印 sql 及其執(zhí)行時(shí)間實(shí)現(xiàn)方法
- Mysql使用kill命令解決死鎖問題(殺死某條正在執(zhí)行的sql語句)
- Mysql 服務(wù) 1067 錯(cuò)誤 的解決方法:修改mysql可執(zhí)行文件路徑
- MySql批量插入優(yōu)化Sql執(zhí)行效率實(shí)例詳解
- oracle查看執(zhí)行最慢與查詢次數(shù)最多的sql語句
- SQL執(zhí)行步驟的具體分析