SQL 服务器 2005
在您可以利用表值参数之前,我建议您只创建一个专门的表值 UDF 来拆分您的 GUID 参数。然后,您可以在连接、存在子句、交叉应用等中使用输出。
CREATE FUNCTION dbo.SplitGUIDs
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT [GUID] = CONVERT(UNIQUEIDENTIFIER, x) FROM
(
SELECT x = RTRIM(y.i.value('.[1]', 'nvarchar(4000)'))
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
) AS x WHERE LEN(Item) > 0
);
GO
用法:
DECLARE @GUIDs VARCHAR(MAX);
SET @GUIDs = 'E2072E08-84D3-4EEA-A6ED-F38F1E4E34A6,'
+ 'A6B047BA-647E-4B35-8D95-F4A204B860F6';
SELECT [GUID] FROM dbo.SplitGUIDs(@GUIDs, ',') AS g;
结果:
Item
------------------------------------
E2072E08-84D3-4EEA-A6ED-F38F1E4E34A6
A6B047BA-647E-4B35-8D95-F4A204B860F6
存储过程可能如下所示:
CREATE PROCEDURE dbo.Whatever
@GUIDs VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT t.columns
FROM dbo.sometable AS t
INNER JOIN dbo.SplitGUIDs(@GUIDs, ',') AS g
ON t.key = g.[GUID];
END
GO
(当然,如果您的字符串中的任何元素包含无效的 GUID,则该函数将失败。在 SQL Server 2012 中您可以使用TRY_CONVERT()
但您不需要这样做,因为您将使用 TVP,更多内容如下。)
SQL Server 2008+
稍后,当您从 SQL Server 2005 毕业时(以及其他面临此问题但使用 SQL Server 2008+ 的读者),您可以使用表类型更有效地执行此操作:
CREATE TYPE dbo.GUIDs AS TABLE(GUID UNIQUEIDENTIFIER PRIMARY KEY);
然后您的存储过程可以将此类型作为输入而不是大字符串:
CREATE PROCEDURE dbo.Whatever
@GUIDs dbo.GUIDs READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT t.columns
FROM dbo.sometable AS t
INNER JOIN @GUIDs AS g
ON t.key = g.[GUID];
END
GO
(请注意切换到 TVP 是多么容易——只需要更改第 2 行和第 9 行。)
然后,您的 Web 应用程序可以将诸如 DataTable 之类的集合传递给 @GUIDs 参数。没有混乱的字符串拆分,没有类型转换,没有人为限制您可以传递多少个不同的 GUID。