Sql server 如何从存储过程返回临时表

Sql server 如何从存储过程返回临时表,sql-server,stored-procedures,temp-tables,Sql Server,Stored Procedures,Temp Tables,此存储过程从第一个select语句返回值,但我希望从第二个select语句返回值。表@WunNumbers是一个临时表 有什么想法吗?您使用的是什么版本的SQL Server?在SQLServer2008中,您可以使用 另一种方法是从用户定义的函数返回表变量,但我不太喜欢这种方法 您可以找到一个示例看看这段代码 CREATE PROCEDURE [test].[proc] @ConfiguredContentId int, @NumberOfGames int AS BEGIN SET NOC

此存储过程从第一个select语句返回值,但我希望从第二个select语句返回值。表@WunNumbers是一个临时表


有什么想法吗?

您使用的是什么版本的SQL Server?在SQLServer2008中,您可以使用

另一种方法是从用户定义的函数返回表变量,但我不太喜欢这种方法


您可以找到一个示例

看看这段代码

CREATE PROCEDURE [test].[proc]
@ConfiguredContentId int,
@NumberOfGames int
AS
BEGIN
 SET NOCOUNT ON
 RETURN 
 @WunNumbers TABLE (WinNumb int)

    INSERT INTO @WunNumbers (WinNumb)
 SELECT TOP (@NumberOfGames) WinningNumber
 FROM [Game].[Game] g
 JOIN [Game].[RouletteResult] AS rr ON g.[Id] = rr.[gameId]
 WHERE g.[ConfiguredContentId] = @ConfiguredContentId
 ORDER BY g.[Stoptime] DESC

 SELECT WinNumb, COUNT (WinNumb) AS "Count"
 FROM @WunNumbers wn
 GROUP BY wn.[WinNumb]
END
GO

过程的返回类型为int

您还可以返回结果集(正如您的代码当前所做的那样)(好的,您还可以发送消息,这些消息是字符串)

这些是你能得到的唯一“回报”。虽然可以将表值参数添加到过程中(请参见BOL),但它们只是输入

编辑:


(或者如另一张海报所述,您也可以使用表值函数,而不是过程)

可以在调用者中创建临时表,然后从被调用的SP填充临时表

CREATE PROCEDURE Test

AS
    DECLARE @tab table (no int, name varchar(30))

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN
与“insert exec”相比,这种方法的一些优点是它可以嵌套,并且可以用作输入或输出

一些缺点是“参数”不是公共的,表的创建存在于每个调用程序中,并且表的名称可能与其他临时对象冲突。当临时表名称与SP名称紧密匹配并遵循某种约定时,它会有所帮助

再进一步说,对于仅输出的临时表,被调用的SP可以同时支持insert exec方法和temp table方法。这对链接SP没有太大帮助,因为仍然需要在调用者中定义该表,但可以帮助简化从cmd行或外部调用时的测试

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

是的,你可以。

在存储过程中,填写表
@tbRetour

在存储过程的最后,您将编写:

  -- The "called" SP
  declare
      @returnAsSelect bit = 0;

  if object_id('tempdb..#GetValuesOutputTable') is null
  begin
      set @returnAsSelect = 1;
      create table #GetValuesOutputTable(
         ...   
      );
  end

  -- populate the table

  if @returnAsSelect = 1
      select * from #GetValuesOutputTable;
要执行存储过程,请编写:

SELECT * FROM @tbRetour 

首先创建一个真实的永久表作为模板,该模板具有返回的临时表所需的布局,使用命名约定将其标识为模板并以符号方式将其链接到SP,例如tmp\u SPName\u输出。此表永远不会包含任何数据

在SP中,使用INSERT按照相同的命名约定将数据加载到临时表中,例如假定存在的#SPName_输出。您可以测试它是否存在,如果不存在,则返回错误

在调用sp之前,使用以下简单的选择创建临时表:

USE [...]
GO

DECLARE @return_value int

EXEC @return_value = [dbo].[getEnregistrementWithDetails]
@id_enregistrement_entete = '(guid)'

GO
这有以下明显的优点:

  • 与###不同,临时表是当前会话的本地表,因此不会与来自的对SP的并发调用冲突 不同的会议。它也会在超出范围时自动删除
  • 模板表与SP一起维护,因此如果需要更改 对输出(例如,添加新列)进行修改,然后预先存在 SP的呼叫者不会中断。调用方不需要更改
  • 您可以定义任意数量的具有不同名称的输出表 一个SP并将其全部填满。您还可以定义替代输出 使用不同的命名,并让SP检查是否存在临时 查看哪些需要填写的表格
  • 类似地,如果进行了重大更改,但您希望保持向后 兼容性,您可以有一个新的模板表,并为以后的命名 版本,但通过检查哪个临时版本仍支持早期版本 调用方已创建的表

请重新格式化您的sql代码。该代码不是有效的sql。如果“RETURN@WinNumbers”是“DECLARE@WinNumbers”,那么它的其余部分可能是正确的,返回最终结果集我现在看到了,我发布了错误的代码。存在“DECLARE@WinNumbers”,但它仍然不起作用。这将如何向调用者返回/输出表变量?它当前返回一个结果集。它返回select语句(实际问题)的结果,在本例中,该结果恰好是本地表变量@tab的内容。如果我执行
测试
如何访问@tab?我正在做类似的事情;当我在ManagementStudio中运行它时,我会看到我的结果集,但是当我使用ADO.net运行它时,SqlReader会得到一个空的结果集。
SELECT TOP(0) * INTO #SPName_Output FROM tmp_SPName_Output;
EXEC SPName;
-- Now process records in #SPName_Output;