簡體   English   中英

TSQL語句輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM