简体   繁体   中英

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).

@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. which means that it only compares with the first GUID in the string. 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'

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'''

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. 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. 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. 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.

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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