问题描述
|
我想调用存储过程,该存储过程在表值函数中返回一个表。如何创建表值函数?
例如:\“ sp_GetTable \”是存储过程。它返回一个表。
在这里,我要编写一个名为\“ fn_GetTable \”的函数。
我想得到与存储过程相同的结果。
这是我的存储过程:
ALTER PROC sp_GetTable
AS
BEGIN
------------ Creating TempTable(#MasterTable) ----------------------
CREATE TABLE #MasterTable
(ItemID INT,ItemName VARCHAR(100),Specifications VARCHAR(100),D1 VARCHAR(50),D2 VARCHAR(50),D3 VARCHAR(50),D1_Code VARCHAR(50),D2_Code VARCHAR(50),D3_Code VARCHAR(50))
------------ Creating TempTable(#TempItems) ----------------------
CREATE TABLE #TempItems(ItemID INT,D3_Code VARCHAR(50))
------------ Creating & Inserting TempTable(@Dim) ----------------------
DECLARE @Dim TABLE (DCodes VARCHAR(100))
INSERT INTO @Dim SELECT D1_Code FROM MAS_SizeType WHERE D1_Code <> \'\'
INSERT INTO @Dim SELECT D2_Code FROM MAS_SizeType WHERE D2_Code <> \'\'
INSERT INTO @Dim SELECT D3_Code FROM MAS_SizeType WHERE D3_Code <> \'\'
------------ Inserting data into TempTable(#MasterTable) ----------------------
INSERT INTO #MasterTable
SELECT STR_Item.ItemID,STR_Item.ItemName,STR_Item_Specifications.SpecificationName,STR_Item.D1,STR_Item.D2,STR_Item.D3,MAS_SizeType.D1_Code,MAS_SizeType.D2_Code,MAS_SizeType.D3_Code
FROM STR_Item INNER JOIN
MAS_SizeType ON STR_Item.SizeTypeID = MAS_SizeType.SizeTypeID INNER JOIN
STR_Item_Specifications ON STR_Item.SpecificationID = STR_Item_Specifications.SpecificationID
-------------------- Inserting Data into #TempItems Table ----------------------------
INSERT INTO #TempItems
SELECT
*
FROM #MasterTable
------------------Cursor for All dimensions details into single row for each items ----------------------
DECLARE @DCode VARCHAR(MAX),@Cnt INT
SET @Cnt = 0
DECLARE ColAdd CURSOR FOR
SELECT disTINCT DCodes FROM @Dim
OPEN ColAdd
FETCH NEXT FROM ColAdd INTO @DCode
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Cnt = 1
EXECUTE (\'ALTER TABLE #TempItems ADD \' + @DCode + \' VARCHAR(50)\')
EXECUTE(\'UPDATE #TempItems SET [\' + @DCode + \'] = M.D1
FROM #MasterTable M
INNER JOIN #TempItems T ON T.ItemID = M.ItemID AND M.D1_Code = \'\'\' + @DCode + \'\'\'\')
EXECUTE(\'UPDATE #TempItems SET [\' + @DCode + \'] = M.D2
FROM #MasterTable M
INNER JOIN #TempItems T ON T.ItemID = M.ItemID AND M.D2_Code = \'\'\' + @DCode + \'\'\'\')
EXECUTE(\'UPDATE #TempItems SET [\' + @DCode + \'] = M.D3
FROM #MasterTable M
INNER JOIN #TempItems T ON T.ItemID = M.ItemID AND M.D3_Code = \'\'\' + @DCode + \'\'\'\')
FETCH NEXT FROM ColAdd INTO @DCode
END
CLOSE ColAdd
DEALLOCATE ColAdd
IF (@Cnt = 1)
BEGIN
SELECT @DCode = STUFF(( SELECT disTINCT \'],[\' + ltrim(DCodes)
FROM @Dim
ORDER BY \'],[\' + ltrim(DCodes)
FOR XML PATH(\'\')
),1,2,\'\') + \']\'
EXECUTE (\'SELECT ItemID,ItemName,Specifications,\' + @DCode + \' FROM #TempItems ORDER BY ItemName\')
END
DROP TABLE #TempItems
DROP TABLE #MasterTable
END
解决方法
可以从标量函数中执行此操作,而不能从表值函数中执行。标量值函数返回单个数据类型的值,也不能返回表。由于您不能从存储过程中选择(需要
EXEC
),因此在表值函数中没有位置。
一般来说,如果存储过程
返回单个结果集,定义
表值函数。如果存放
过程计算一个标量值,
定义一个标量函数。
来自:将存储过程重写为函数
将存储过程重写为表值函数将为您带来最大的性能。
, 不能完成。您需要将SP重写为UDF。
编辑
显然,使用openquery
存在一些非常丑陋的解决方法。但我建议您将SP重写为一个函数,然后可以从旧的SP调用新函数(如果需要)