简体   繁体   English

在SQL Server中对IN子句使用uniqueidentifier

[英]Using uniqueidentifier with IN Clause in SQL server

I have a stored procedure that takes as an input a string of GUIDs and selects from table where table GUID IN (@Param). 我有一个存储过程,将一串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) 

However, I noticed that the query return values, only if the first GUID matches, otherwise it will not return anything. 但是,我注意到只有第一个GUID匹配时,查询才返回值,否则它将不返回任何内容。 which means that it only compares with the first GUID in the string. 这意味着它仅与字符串中的第一个GUID比较。 anyone knows how solve the problem? 有人知道如何解决问题吗?

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

exec (@sql)

In addition to MikkaRin's answer: a GUID has to be unclosed in apostrophes, so the value in the parameter should look like 'b2e16cdc-1f1b-40e2-a979-f87a6a2457af', 'c275dd13-bb54-4b8c-aa12-220b5980cabd', 'af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c', '3a7fda02-558b-49a9-a870-30350254d8c0' 除了MikkaRin的答案:GUID必须用撇号'b2e16cdc-1f1b-40e2-a979-f87a6a2457af', 'c275dd13-bb54-4b8c-aa12-220b5980cabd', 'af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c', '3a7fda02-558b-49a9-a870-30350254d8c0' ,因此参数中的值应类似于'b2e16cdc-1f1b-40e2-a979-f87a6a2457af', 'c275dd13-bb54-4b8c-aa12-220b5980cabd', 'af3552ec-37b1-4a76-81ad-1bd6b8c4cd6c', '3a7fda02-558b-49a9-a870-30350254d8c0'

In the end, you have to pass something like: @Param = '''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'''

Pay attention to the last comma of the list. 请注意列表的最后一个逗号。 It should be removed. 应该将其删除。

We can't do it, because SQL has no concept of Lists, or array or other useful data structures - it only knows about tables (and table based information) so it converts the string list into a table structure when it compiles the command - and it can't compile a variable string, so it complains and you get annoyed. 我们无法做到,因为SQL没有列表,数组或其他有用的数据结构的概念-它只知道表(以及基于表的信息),因此在编译命令时会将字符串列表转换为表结构-而且它无法编译变量字符串,因此它会抱怨并且使您烦恼。 Or at least, I do. 至少,我愿意。

What we have to do is convert the comma separated values into a table first. 我们要做的是先将逗号分隔的值转换为表格。 My initial version was inline, and rather messy, so I re-worked it to a user function and made it a bit more general purpose. 我的最初版本是内联的,相当凌乱,因此我将其重新设计为用户功能,并使之更加通用。

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

This creates a user function that takes a comma separated value string and converts it into a table that SQL does understand - just pass it the sting, and it works it all out. 这将创建一个用户函数,该函数采用逗号分隔的值字符串,并将其转换为SQL可以理解的表-只需将其传递给字符串,然后就可以解决所有问题。 It's pretty obvious how it works, the only complexity is the REPLACE part which ensures the string is terminated with a single comma by appending one, and removing all double commas from the string. 很明显,它是如何工作的,唯一的复杂性是REPLACE部分,该部分通过附加一个逗号并从字符串中删除所有双逗号来确保该字符串以单个逗号终止。 Without this, while loop becomes harder to process, as the final number might or might not have a terminating comma and that would have to be dealt with separately. 如果没有这个,则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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM