在SQL server中对IN子句使用唯一标识符



我有一个存储过程,它将GUID字符串作为输入,并从GUID为IN (@Param)的表中进行选择。

@Param = 'b2e16cdc-1f1b-40e2-a979-f87a6a2457af,
c275dd13-bb54-4b8c-aa12-220b5980cabd,
af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c,
3a7fda02-558b-49a9-a870-30350254d8c0,'
    SELECT * FROM dbo.Table1 WHERE 
    TableGUID IN (@Param) 

然而,我注意到查询返回值,只有当第一个GUID匹配,否则它不会返回任何东西。这意味着它只比较字符串中的第一个GUID。有人知道怎么解决这个问题吗?

declare @sql varchar(max)
set @sql='SELECT * FROM dbo.Table1 WHERE 
    TableGUID IN ('+@Param+') '
exec (@sql)

我们不能这样做,因为SQL没有列表、数组或其他有用的数据结构的概念——它只知道表(和基于表的信息),所以它在编译命令时将字符串列表转换为表结构——而且它不能编译可变字符串,所以它会抱怨,你会很恼火。或者至少,我知道。

我们首先要做的是将逗号分隔的值转换成一个表。我最初的版本是内联的,相当混乱,所以我把它重新设计成一个用户函数,使它更通用一些。

USE [Testing] GO
CREATE FUNCTION [dbo].[VarcharToTable] (@InStr NVARCHAR(MAX))
RETURNS @TempTab TABLE
   (id UNIQUEIDENTIFIER NOT NULL)
AS
BEGIN
    ;-- Ensure input ends with comma
    SET @InStr = REPLACE(@InStr + ',', ',,', ',')
    DECLARE @SP INT
    DECLARE @VALUE NVARCHAR(MAX)
    WHILE PATINDEX('%,%', @INSTR ) <> 0 
    BEGIN
       SELECT  @SP = PATINDEX('%,%',@INSTR)
       SELECT  @VALUE = LEFT(@INSTR , @SP - 1)
       SELECT  @INSTR = STUFF(@INSTR, 1, @SP, '')
       INSERT INTO @TempTab(id) VALUES (@VALUE)
    END
        RETURN
END
GO

这创建了一个用户函数,该函数接受逗号分隔的值字符串,并将其转换为SQL能够理解的表—只需传递字符串,它就可以完成所有操作。它的工作原理很明显,唯一的复杂性是REPLACE部分,它通过附加一个逗号来确保字符串以单个逗号结束,并从字符串中删除所有双逗号。如果不这样做,while循环就会变得更难处理,因为最后的数字可能有也可能没有结束逗号,而这必须单独处理。

DECLARE @LIST NVARCHAR(MAX)
SET @LIST = '973150D4-0D5E-4AD0-87E1-037B9D4FC03B,973150d4-0d5e-4ad0-87e1-037b9d4fc03c'
SELECT Id, Descr FROM TableA WHERE Id IN (SELECT * FROM dbo.VarcharToTable(@LIST))

除了MikkaRin的回答:GUID必须在撇号中打开,所以参数中的值应该看起来像'b2e16cdc-1f1b-40e2-a979-f87a6a2457af', 'c275dd13-bb54-4b8c-aa12-220b5980cabd', 'af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c', '3a7fda02-558b-49a9-a870-30350254d8c0'

最后,你必须传递这样的东西: @Param = '''b2e16cdc-1f1b-40e2-a979-f87a6a2457af'', ''c275dd13-bb54-4b8c-aa12-220b5980cabd'', ''af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c'', ''3a7fda02-558b-49a9-a870-30350254d8c0'''

注意列表最后一个逗号。

相关内容

  • 没有找到相关文章

最新更新