如何将包含uniqueidentifier列表的varchar转换为SQL Server中的uniqueidentifier列表

时间:2018-04-07 07:43:42

标签: sql sql-server sql-server-2017

在employeeId列的查询数据类型中为uniqueidentifier。我在执行

时遇到以下错误
  

从字符串转换为uniqueidentifier时转换失败。

declare @tt nvarchar = 'e347d817-3121-e811-9c0b-58fb847a6047,e447d817-3121-e811-9c0b-58fb847a6047,e147d817-3121-e811-9c0b-58fb847a6047,df47d817-3121-e811-9c0b-58fb847a6047,de47d817-3121-e811-9c0b-58fb847a6047,e547d817-3121-e811-9c0b-58fb847a6047,e247d817-3121-e811-9c0b-58fb847a6047,e047d817-3121-e811-9c0b-58fb847a6047,dd47d817-3121-e811-9c0b-58fb847a6047'

select * 
from [dbo].[employee] 
where [employeeId] in (@tt)

如何将uniqueidentifiers(GUID)字符串转换为uniqueidentifiers列表?

我曾尝试执行转换,如图所示 Convert varchar list to int in Sql Server 但它没有用。

3 个答案:

答案 0 :(得分:1)

--Create this function.  This function will convert string to Id as row
CREATE FUNCTION [dbo].[StrParse]
               (@delimiter CHAR(1),  
                @csv       NTEXT)  
RETURNS @tbl TABLE(Keys  NVARCHAR(255))  
AS  

  BEGIN  
    DECLARE  @len INT  
    SET @len = Datalength(@csv)  
    IF NOT @len > 0  
      RETURN  

    DECLARE  @l INT  
    DECLARE  @m INT  

    SET @l = 0  
    SET @m = 0  

    DECLARE  @s VARCHAR(255)  
    DECLARE  @slen INT  

    WHILE @l <= @len  
      BEGIN  

        SET @l = @m + 1--current position  
        SET @m = Charindex(@delimiter,Substring(@csv,@l + 1,255))--next delimiter or 0  

        IF @m <> 0  
          SET @m = @m + @l  
        --insert @tbl(keys) values(@m)  
        SELECT @slen = CASE   
                         WHEN @m = 0 THEN 255 --returns the remainder of the string  
                         ELSE @m - @l  
                       END --returns number of characters up to next delimiter  

        IF @slen > 0  
          BEGIN  
            SET @s = Substring(@csv,@l,@slen)  
            INSERT INTO @tbl  
                       (Keys)  
            SELECT @s  
          END  

        SELECT @l = CASE   
                      WHEN @m = 0 THEN @len + 1 --breaks the loop  
                      ELSE @m + 1  
                    END --sets current position to 1 after next delimiter  
      END  

    RETURN  
  END
go

--Below code will return the value you are expecting
declare @tt nvarchar (MAX) = 'e347d817-3121-e811-9c0b-58fb847a6047,e447d817-3121-e811-9c0b-58fb847a6047'
select * 
from [dbo].[employee]
where [employeeId] in (select keys from dbo.StrParse (',', @tt))

答案 1 :(得分:0)

好吧,如果你声明你的变量:

y

你得到一串正好一个字符的字符串!

您应 始终 (无例外!)为您的declare @tt nvarchar 定义明确的长度(和varchar )变量:

nvarchar

此外 - 如果您将declare @tt nvarchar(2000) = ..... 定义为Unicode字符串,则必须为您为其分配的字符串文字前缀nvarchar,以使其成为Unicode字符串文字:

N

但最终,即使那样也会起作用 - 因为declare @tt nvarchar(2000) = N'.......' 运算符需要列表 - 而不是单个字符串.. ...您应声明一个表变量,将值插入该表变量,然后执行select:

IN

答案 2 :(得分:0)

您需要动态SQL才能实现:

--declare string, that will hold your query
declare @query varchar(4000) = 'select * 
                                from [dbo].[employee] 
                                where [employeeId] in '
--transform your list of IDs to list of values suitable for a where clause
set @tt = '(''' + replace(@tt, ',', ''',''') + ''')'
set @query = @query + @tt
--execute the query
exec(@query)