我在SQL Server 2012数据库中有以下数据:
CategoryID Keyword Type
-------------------------------------
1 open plan 0
1 kitchen 0
2 air conditioned 3
2 spacious 2
2 living room 1
3 metal 5
3 shingled 4
3 roof 4
这是我数据的简化。
我有一个标量函数,它将这些数据作为用户定义的表类型(整个数据表),进行一些处理(非常复杂,许多规则),然后为每个id返回一个字符串,例如:对于id为1的数据子集,它将返回开放式厨房,对于id为2的数据子集,它将返回空调,宽敞的起居室,类似于id 3它将返回金属瓦屋顶。我的函数必须为每个id执行此操作。目前我正在使用游标循环遍历不同的id并为匹配id的每组数据调用函数。
我很关心表现。有什么更好的方法来做到这一点?
功能示例:
CREATE FUNCTION [dbo].[func_GenerateString]
(
@MyData InputDataType READONLY
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @outputString VARCHAR(MAX)
SET @outputString = ''
-- implement rules
RETURN @outputString
END
这是我的表类型
CREATE TYPE InputDataType AS TABLE
(
CategoryId INT NOT NULL,
Keyword varchar(100) NULL,
Type INT NOT NULL,
)
GO
答案 0 :(得分:0)
我认为您可以使用以下解决方法:
<强> SqlFiddleDemo 强>
CREATE TYPE InputDataType AS TABLE
(
CategoryId INT NOT NULL,
Keyword varchar(100) NULL,
Type INT NOT NULL
);
GO
CREATE FUNCTION [dbo].[func_GenerateString]( @MyXml XML)
RETURNS VARCHAR(MAX)
AS
BEGIN
/* Unwrapping */
DECLARE @MyData AS InputDataType;
INSERT INTO @MyData(CategoryId, Keyword, Type)
SELECT
[CategoryId] = t.c.value('(CategoryId)[1]', 'int'),
[Keyword] = t.c.value('(Keyword)[1]', 'varchar(100)') ,
[Type] = t.c.value('(Type)[1]', 'int')
FROM @MyXml.nodes('//row') AS t(c);
DECLARE @outputString VARCHAR(MAX);
SET @outputString = '';
-- your logic
SET @outputString = STUFF(
(SELECT ' ' + Keyword
FROM @MyData
FOR XML PATH('')), 1, 1, '')
RETURN @outputString
END;
GO
/* Main query */
SELECT CategoryId,
[result] = [dbo].[func_GenerateString]((SELECT CategoryId, Keyword, Type
FROM tab t1
WHERE t.CategoryId = t1.CategoryId
FOR XML PATH, ROOT('root')))
FROM tab t
GROUP BY CategoryId;
而不是TVP参数我传递XML参数并立即在函数内部将其解包回TVP。