【问题标题】:How to pass a table variable from one stored procedure to another如何将表变量从一个存储过程传递到另一个
【发布时间】:2014-10-17 16:27:19
【问题描述】:

我的场景是这样的,

CREATE PROCEDURE SP_1
AS 
BEGIN
    INSERT INTO #tmpTable(ID, Value)
    VALUES(1, 1), (2, 2)
END
GO

CREATE PROCEDURE SP_2
AS
BEGIN
    CREATE TABLE #tmpTable(ID INT, Value INT)
    EXEC SP_1

    SELECT * FROM #tmpTable

    DROP TABLE #tmpTable
END
GO

EXEC SP_2
GO

DROP PROCEDURE SP_1
DROP PROCEDURE SP_2

我想将这个# 表替换为TABLE VARIABLE@ 表)。

我尝试将表变量作为参数传递给 SP_1,但我应该将表变量作为只读参数传递。由于它是只读的,我无法插入到 SP_1 内的表变量中。有没有其他方法可以做到这一点?

【问题讨论】:

  • 您将需要创建一个TABLE TYPE 然后声明该类型的参数,是的,它将是一个只读参数,但是您可以将数据放入参数中的另一个表变量或临时表中并用它做任何你想做的事情。

标签: sql sql-server sql-server-2008 sql-server-2005 stored-procedures


【解决方案1】:

这种方式是行不通的。您应该将您的查询封装在一个字符串中。完成后,您可以根据需要更改表名。然后,使用 EXEC sp_executesql 执行。
我之前回答过一个类似的问题,可以在下面找到:
SQL: How to make table name in stored procedure dynamic
这是我提供的示例

declare @sql nvarchar(max)
    declare @TableName nvarchar(max)
    set @TableName = 'mytable'
    set @sql = 'Select * from ' + @TableName
    Exec sp_executesql @sql

【讨论】:

    【解决方案2】:

    这对我有用(Sql server 2012),虽然我不完全理解你想要实现的目标:

    CREATE PROCEDURE SP_1
    AS 
    BEGIN
    
        Create table #tmpTable (ID INT, Value INT)
    
        INSERT INTO #tmpTable(ID, Value)
        VALUES(1, 1), (2, 2)
    
        Select ID,Value from #tmpTable
    END
    GO
    
    CREATE PROCEDURE SP_2
    AS
    BEGIN
        Declare @tmpTable table (ID INT, Value INT)
    
        Insert into @tmpTable
        EXEC SP_1
    
        SELECT * FROM @tmpTable
    
    
    END
    GO
    
    EXEC SP_2
    GO
    
    DROP PROCEDURE SP_1
    DROP PROCEDURE SP_2
    

    【讨论】:

    • 只想补充一点,SP_1 可以为此任务返回带有或不带有表变量或临时表的结果集。 INSERT...EXEC 语句使用返回的结果集而不考虑源。此外,SP_ 前缀不应用于用户存储过程,因为它是为系统过程保留的,尽管这可能只是用于 @Sandeep 提供的示例的名称。
    • @Dan:完全同意。我只是使用了 Sandeep 示例中指定的 proc 名称。我希望这只是一个示例,而不是实际代码。另外,我相信在“选择”结果之前会有更多的处理。因此,我按原样放置了 Sandeep 示例中的代码。想法只是指出如何做到这一点。
    【解决方案3】:

    我更喜欢以 [xml] 的形式传递数据。和我一起工作更容易。您可以构建类似于以下代码的记录集,并在您的过程之间传递 [xml] 参数,然后将其解析出来,如图所示。

    声明@record_list [xml] = (选择 *
       来自   [sys].[objects]
       for xml path(N'record'), root(N'record_list'));
    选择@record_list;
    选择 t.c.value(N'(./schema_id/text())[1]', N'[sysname]')   作为 [schema_id]
           , t.c.value(N'(./name/text())[1]', N'[sysname]')      as [name]
           , t.c.value(N'(./object_id/text())[1]', N'[sysname]') 作为 [object_id]
    来自   @record_list.nodes(N'/record_list/record') 作为 t(c);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      • 1970-01-01
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      相关资源
      最近更新 更多