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

发布于 2024-08-05 07:09:37 字数 603 浏览 5 评论 0原文

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 是一个临时表。

有什么想法吗???

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

This stored procedure returns values from first select statement, but I would like to have values from second select statement to be returned. Table @WunNumbers is a temporary table.

Any ideas???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

红尘作伴 2024-08-12 07:09:37

看看这段代码,

CREATE PROCEDURE Test

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

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN

Take a look at this code,

CREATE PROCEDURE Test

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

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN
红衣飘飘貌似仙 2024-08-12 07:09:37

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

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

您可以在此处找到示例

What version of SQL Server are you using? In SQL Server 2008 you can use Table Parameters and Table Types.

An alternative approach is to return a table variable from a user defined function but I am not a big fan of this method.

You can find an example here

烟织青萝梦 2024-08-12 07:09:37

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

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

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

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

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

  -- 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;

A temp table can be created in the caller and then populated from the called SP.

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

Some advantages of this approach over the "insert exec" is that it can be nested and that it can be used as input or output.

Some disadvantages are that the "argument" is not public, the table creation exists within each caller, and that the name of the table could collide with other temp objects. It helps when the temp table name closely matches the SP name and follows some convention.

Taking it a bit farther, for output only temp tables, the insert-exec approach and the temp table approach can be supported simultaneously by the called SP. This doesn't help too much for chaining SP's because the table still need to be defined in the caller but can help to simplify testing from the cmd line or when calling externally.

  -- 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;
情绪少女 2024-08-12 07:09:37

是的,您可以。

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

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

SELECT * FROM @tbRetour 

要执行存储过程,您可以编写:

USE [...]
GO

DECLARE @return_value int

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

GO

YES YOU CAN.

In your stored procedure, you fill the table @tbRetour.

At the very end of your stored procedure, you write:

SELECT * FROM @tbRetour 

To execute the stored procedure, you write:

USE [...]
GO

DECLARE @return_value int

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

GO
痴情 2024-08-12 07:09:37

过程的返回类型是 int。

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

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

编辑:

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

The return type of a procedure is int.

You can also return result sets (as your code currently does) (okay, you can also send messages, which are strings)

Those are the only "returns" you can make. Whilst you can add table-valued parameters to a procedure (see BOL), they're input only.

Edit:

(Or as another poster mentioned, you could also use a Table Valued Function, rather than a procedure)

一抹苦笑 2024-08-12 07:09:37

首先创建一个真实的永久表作为模板,该表具有返回的临时表所需的布局,使用将其标识为模板并将其符号链接到 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 检查临时文件是否存在
    表格以查看需要填写的内容。
  • 同样,如果进行了重大更改但您想保持倒退
    兼容性,可以有一个新的模板表和命​​名供以后使用
    版本,但仍然通过检查哪个温度来支持早期版本
    调用者创建的表。

First create a real, permanent table as a template that has the required layout for the returned temporary table, using a naming convention that identifies it as a template and links it symbolically to the SP, eg tmp_SPName_Output. This table will never contain any data.

In the SP, use INSERT to load data into a temp table following the same naming convention, e.g. #SPName_Output which is assumed to exist. You can test for its existence and return an error if it does not.

Before calling the sp use this simple select to create the temp table:

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

This has these distinct advantages:

  • The temp table is local to the current session, unlike ##, so will not clash with concurrent calls to the SP from
    different sessions. It is also dropped automatically when out of scope.
  • The template table is maintained alongside the SP, so if changes are
    made to the output (new columns added, for example) then pre-existing
    callers of the SP do not break. The caller does not need to be changed.
  • You can define any number of output tables with different naming for
    one SP and fill them all. You can also define alternative outputs
    with different naming and have the SP check the existence of the temp
    tables to see which need to be filled.
  • Similarly, if major changes are made but you want to keep backwards
    compatibility, you can have a new template table and naming for the later
    version but still support the earlier version by checking which temp
    table the caller has created.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文