[英]TSQL Statement IN
我在使用IN SQL語句時遇到了一個小問題。 我只是想知道是否有人可以幫助我?
@Ids = "1,2,3,4,5"
SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (CONVERT(VARCHAR,@Ids))
這又返回了以下錯誤,我敢肯定這很簡單!
Conversion failed when converting the varchar value '1,' to data type int.
SQL IN子句不接受單個變量來代表值列表-如果不使用動態SQL,則數據庫不支持。 否則,您可以使用表值函數 (SQL Server 2000+)將值從列表中拉出,並將它們作為可聯接的表返回。
動態SQL示例:
EXEC('SELECT *
FROM Nav
WHERE NavigationID IN ('+ @Ids +')')
我建議在SQL Server上使用動態SQL之前閱讀動態SQL的詛咒和祝福 。
傑森:
首先創建一個這樣的功能
Create FUNCTION [dbo].[ftDelimitedAsTable](@dlm char, @string varchar(8000))
RETURNS
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
declare @dlm char, @string varchar(1000)
set @dlm=','; set @string='t1,t2,t3';
-- tHIS FUNCION RETUNRS IN THE ASCENDING ORDER
-- 19TH Apr 06
------------------------------------------------------------------------*/
--declare
@table_var TABLE
(id int identity(1,1),
r varchar(1000)
)
AS
BEGIN
declare @n int,@i int
set @n=dbo.fnCountChars(@dlm,@string)+1
SET @I =1
while @I <= @N
begin
insert @table_var
select dbo.fsDelimitedString(@dlm,@string,@i)
set @I= @I+1
end
if @n =1 insert @TABLE_VAR VALUES(@STRING)
delete from @table_var where r=''
return
END
接着
set quoted_identifier off
declare @ids varchar(max)
select @Ids = "1,2,3,4,5"
declare @nav table ( navigationid int identity(1,1),theother bigint)
insert @nav(theother) select 10 union select 11 union select 15
SELECT * FROM @Nav WHERE CONVERT(VARCHAR,NavigationID) IN (select id from dbo.ftDelimitedAsTable(',',@Ids))
select * from dbo.ftDelimitedAsTable(',',@Ids)
SQL IN
語句無法實現您正在執行的操作。 您不能向其傳遞字符串,並且不能期望對該字符串進行解析。 IN用於特定的硬編碼值。
有兩種方法可以在這里完成您想做的事情。 一種是在替換您的IN列表后,創建一個“動態sql”查詢並執行它。
DECLARE @query varchar(max);
SET @query = 'SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (' + @Ids + ')'
exec (@query)
這可能會影響性能並帶來其他並發症。 通常,我會盡量避免這種情況。
另一種方法是使用用戶定義函數(UDF)將字符串分成其組成部分,然后對此進行查詢。 有一個帖子,詳細說明了如何創建功能在這里
一旦函數存在,加入它就很簡單了
SELECT * FROM Nav
CROSS APPLY dbo.StringSplit(@Ids) a
WHERE a.s = CONVERT(varchar, Nav.NavigationId)
注意:“ as”字段引用基於鏈接函數,該函數將拆分值存儲在名為“ s”的列中。 根據您的字符串拆分功能的實現,這可能會有所不同
這很好,因為它對查詢使用了基於集合的方法,而不是IN子查詢,但是CROSS JOIN目前可能有點復雜,因此,如果您要維護IN語法,則應該可以執行以下操作:
SELECT * FROM Nav
WHERE Nav.NavigationId IN
(SELECT CONVERT(int, a.s) AS Value
FROM dbo.StringSplit(@Ids) a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.