行子集的调用函数
Call function for subset of rows
我在 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
这是我的数据的简化。
我有一个标量函数,它将此数据作为用户定义的 table 类型(整个 table 数据)进行处理(非常复杂,有很多规则)然后 returns 每个 id 的字符串,例如对于 ID 为 1 的数据子集,它将 return open plan kitchen,对于 ID 为 2 的数据子集,它将 return air空调宽敞的客厅,与 id 3 类似,它将 return 金属瓦屋顶 。我的函数必须为每个 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
这是我的table类型
CREATE TYPE InputDataType AS TABLE
(
CategoryId INT NOT NULL,
Keyword varchar(100) NULL,
Type INT NOT NULL,
)
GO
我认为您可以使用以下解决方法:
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;
我传递 XML 参数而不是 TVP 参数,并立即在函数内部将其解包回 TVP。
我在 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
这是我的数据的简化。
我有一个标量函数,它将此数据作为用户定义的 table 类型(整个 table 数据)进行处理(非常复杂,有很多规则)然后 returns 每个 id 的字符串,例如对于 ID 为 1 的数据子集,它将 return open plan kitchen,对于 ID 为 2 的数据子集,它将 return air空调宽敞的客厅,与 id 3 类似,它将 return 金属瓦屋顶 。我的函数必须为每个 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
这是我的table类型
CREATE TYPE InputDataType AS TABLE
(
CategoryId INT NOT NULL,
Keyword varchar(100) NULL,
Type INT NOT NULL,
)
GO
我认为您可以使用以下解决方法:
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;
我传递 XML 参数而不是 TVP 参数,并立即在函数内部将其解包回 TVP。