如何将包含唯一标识符列表的 varchar 转换为 SQL 服务器中的唯一标识符列表
How to convert varchar containing list of uniqueidentifiers into a list of uniqueidentifiers in SQL Server
查询中employeeId列的数据类型为uniqueidentifier
。执行时出现以下错误
Conversion failed when converting from a character string to 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)
如何将唯一标识符 (GUID) 字符串转换为唯一标识符列表?
我曾尝试按照中所示执行转换
但是没用。
嗯,如果你这样声明你的变量:
declare @tt nvarchar
您得到一串长度正好是一个字符的字符串!
您应该始终(没有例外!)为您的[定义明确的长度 =14=](和nvarchar
)变量:
declare @tt nvarchar(2000) = .....
此外 - 如果您将 nvarchar
定义为 Unicode 字符串,您 必须 在您分配给它的字符串文字前加上 N
它是一个 Unicode 字符串文字:
declare @tt nvarchar(2000) = N'.......'
但最终,即使这样 也不会 起作用 - 因为 IN
运算符需要一个 列表 - 不是单个字符串.....您应该声明一个 table 变量,将您的值插入该 table 变量,然后执行 select:
DECLARE @tt TABLE (ID UNIQUEIDENTIFIER)
INSERT INTO @tt(ID)
VALUES ('e347d817-3121-e811-9c0b-58fb847a6047'),
('e447d817-3121-e811-9c0b-58fb847a6047'),
etc.
SELECT *
FROM [dbo].[employee]
WHERE [employeeId] IN (SELECT ID FROM @tt)
您需要动态 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)
--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))
查询中employeeId列的数据类型为uniqueidentifier
。执行时出现以下错误
Conversion failed when converting from a character string to 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)
如何将唯一标识符 (GUID) 字符串转换为唯一标识符列表?
我曾尝试按照中所示执行转换
嗯,如果你这样声明你的变量:
declare @tt nvarchar
您得到一串长度正好是一个字符的字符串!
您应该始终(没有例外!)为您的[定义明确的长度 =14=](和nvarchar
)变量:
declare @tt nvarchar(2000) = .....
此外 - 如果您将 nvarchar
定义为 Unicode 字符串,您 必须 在您分配给它的字符串文字前加上 N
它是一个 Unicode 字符串文字:
declare @tt nvarchar(2000) = N'.......'
但最终,即使这样 也不会 起作用 - 因为 IN
运算符需要一个 列表 - 不是单个字符串.....您应该声明一个 table 变量,将您的值插入该 table 变量,然后执行 select:
DECLARE @tt TABLE (ID UNIQUEIDENTIFIER)
INSERT INTO @tt(ID)
VALUES ('e347d817-3121-e811-9c0b-58fb847a6047'),
('e447d817-3121-e811-9c0b-58fb847a6047'),
etc.
SELECT *
FROM [dbo].[employee]
WHERE [employeeId] IN (SELECT ID FROM @tt)
您需要动态 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)
--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))