【问题标题】:How to call the Stored Procedure in the Table Valued Function in SQL Server 2005?SQL Server 2005如何调用表值函数中的存储过程?
【发布时间】:2011-09-14 12:09:11
【问题描述】:

我想调用在表值函数中返回一个表的存储过程。如何创建表值函数?

例如:“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, 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 & 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

【问题讨论】:

  • “我尝试了下面的方法,但它给出了错误。”为什么不提及引发的错误?
  • @Tim:它给出了“'RETURNS'附近的语法错误”

标签: sql sql-server sql-server-2005 stored-procedures user-defined-functions


【解决方案1】:

可以在标量函数中执行此操作,无法通过表值函数执行此操作。标量值函数返回单个数据类型值,也不能返回表。由于您无法从存储过程中进行选择(您需要EXEC),因此在表值函数中没有这个位置。

一般来说,如果存储过程 返回一个,单个,结果集,定义 一个表值函数。如果存储 过程计算一个标量值, 定义一个标量函数。

发件人:Rewriting Stored Procedures as Functions

将存储过程重写为表值函数将使您获得最佳性能。

【讨论】:

  • 使用表值函数的问题是它不应该返回动态列。它只返回静态列。有没有办法返回动态列?
  • 我不得不说,msdn 链接是 b.s,没什么用处。
【解决方案2】:

做不到。您需要将您的 SP 重写为 UDF。

编辑

显然有一些really ugly workarounds 使用openquery。但我建议将您的 SP 重写为一个函数,然后您可以从旧 SP 调用新函数(如果需要)

【讨论】:

  • 这在技术上仍然是一个标量值函数,在加入 select 语句时不能使用。我猜OP想像视图一样使用它,也许?我不确定。
  • @Codesleuth:重写到视图或 UDF 将是最佳选择。
  • 在那个存储过程中,我创建了两个表变量,它包含更多语句。是否可以创建视图?
  • @thevan 在您的问题中发布 SP,我会帮助您。
  • 我在我的问题中发布了 SP。请给出解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2012-04-18
  • 2010-09-09
相关资源
最近更新 更多