16
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

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

有任何想法吗???

4

6 回答 6

31

看看这段代码,

CREATE PROCEDURE Test

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

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN
于 2009-09-18T10:50:56.323 回答
6

您使用的是什么版本的 SQL Server?在 SQL Server 2008 中,您可以使用表参数和表类型

另一种方法是从用户定义的函数返回一个表变量,但我不是这种方法的忠实粉丝。

你可以在这里找到一个例子

于 2009-09-18T10:29:57.940 回答
4

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

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

这种方法相对于“insert exec”的一些优点是它可以嵌套并且可以用作输入或输出。

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

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

  -- 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;
于 2012-07-03T17:50:26.633 回答
1

是的你可以。

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

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

SELECT * FROM @tbRetour 

要执行存储过程,请编写:

USE [...]
GO

DECLARE @return_value int

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

GO
于 2014-12-05T20:25:18.700 回答
0

过程的返回类型是 int。

您还可以返回结果集(就像您的代码当前所做的那样)(好吧,您也可以发送消息,它们是字符串)

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

编辑:

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

于 2009-09-18T11:09:47.620 回答
0

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

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

在调用 sp 之前,使用这个简单的选择来创建临时表:

SELECT TOP(0) * INTO #SPName_Output FROM tmp_SPName_Output;
EXEC SPName;
-- Now process records in #SPName_Output;

这具有以下明显优势:

  • 与## 不同,临时表是当前会话的本地表,因此不会与来自不同会话的对 SP 的并发调用发生冲突。它也会在超出范围时自动删除。
  • 模板表与 SP 一起维护,因此如果对输出进行更改(例如添加新列),则 SP 的预先存在的调用者不会中断。调用者不需要更改。
  • 您可以为一个 SP 定义任意数量的具有不同命名的输出表并将它们全部填充。您还可以定义具有不同命名的替代输出,并让 SP 检查临时表的存在以查看哪些需要填充。
  • 同样,如果进行了重大更改但您希望保持向后兼容性,您可以拥有一个新的模板表并为更高版本命名,但仍然通过检查调用者创建的临时表来支持早期版本。
于 2017-07-21T16:09:16.660 回答