【问题标题】:How to select values from temp table and pass them as parameter to SP如何从临时表中选择值并将它们作为参数传递给 SP
【发布时间】:2012-03-28 23:44:24
【问题描述】:

我有一个 SelectSP,它返回我存储在临时表中的结果集。现在我想调用另一个名为 InsertSP 的 SP,并将这个临时表中的值作为参数传递给它。

这是我目前的代码:

CREATE TABLE #tempTable
(
    Field1 VARCHAR(255),
    Field2 VARCHAR(255),
    Field3 VARCHAR(255),
    Field4 VARCHAR(255),
    Field5 VARCHAR(255),
    Field6 VARCHAR(255),
    Field7 VARCHAR(255)
        .
        .
        .

)

INSERT INTO #tempTable exec 
usp_SelectSP 'p1' ,'p2', 'p3'

现在我想再执行一个 SP 并将 tempTable 的 Field1、Field2、Field3 作为参数传递给该 SP。

我在想这样的事情

usp_InsertSP
  @param1 = Field1
  @Param2 = Field2
  @Param3 = Field3

FROM #tempTable.

最好的方法是什么?

【问题讨论】:

  • 您是要为单行调用存储过程,还是需要多次调用该过程,每行一次?为什么被调用的过程不能只是SELECT values FROM #temp?被调用者应该可以看到调用者创建的#temp 表。
  • 我需要多次调用它
  • 我无法更改 InsertSP。我已经给它传递了参数。
  • 你能提供一些关于第二个存储过程对正在传递的参数做什么的线索吗?
  • 执行一些业务逻辑,往表中插入数据

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


【解决方案1】:

如果您无法更改被调用的 SP,那么最简单的方法可能是光标:

DECLARE @f1 VARCHAR(255), @f2 VARCHAR(255) --, ...

DECLARE c CURSOR 
  LOCAL STATIC READ_ONLY FORWARD_ONLY
  FOR SELECT Field1, Field2 --, ...
    FROM #tempTable;

OPEN c;

FETCH NEXT FROM c INTO @f1, @f2 --, ...

WHILE @@FETCH_STATUS <> -1
BEGIN
  EXEC usp_InsertSP
    @param1 = @f1,
    @param2 = @f2 --, ...

  FETCH NEXT FROM c INTO @f1, @f2 --, ...
END

CLOSE c;
DEALLOCATE c;

但是我强烈建议您更改被调用的过程。如果您可以将调用的过程更改为直接使用它,那么几乎绝对有一种更有效的方法来处理此#temp 表中的数据。

编辑

证明被调用的proc可以看到调用者创建的#temp表。

CREATE PROCEDURE dbo.proc1
AS
BEGIN
    SET NOCOUNT ON;

    CREATE TABLE #t1(a INT);

    INSERT #t1 SELECT 1 UNION SELECT 2;

    EXEC dbo.proc2;

    DROP TABLE #t1;
END
GO

CREATE PROCEDURE dbo.proc2
AS
BEGIN
    SET NOCOUNT ON;

    SELECT a FROM #t1;
END
GO

EXEC dbo.proc1;

结果:

a
-
1
2

【讨论】:

  • 我可以尝试让 DBA 更改 SP。我是否应该要求他们进行条件插入,如果 #tempTable 存在,则不要从参数中插入数据?
  • 不,他们应该能够做的只是INSERT dbo.table(col1, col2, ...) SELECT field1, field2, ... FROM #tempTable; - 因为被调用的SP可以看到#temp表!
  • 还有其他地方调用 InsertSP 并将参数传递给它。我希望它也能正常工作。
  • 嗯,你有几个选择,你可以只使用光标并做得很糟糕,你可以修复所有调用 InsertSP 的地方,或者你可以创建一个特殊版本的 InsertSP 以获得更多高效的基于集合的方法。
  • 如果我检查 IF object_id('tempdb..#tempTable') IS NOT NULL,如果有多个用户使用相同的登录信息连接到系统,这会影响什么吗?只需确认我知道它会为每个会话创建临时表。
【解决方案2】:

只需分享#TEMP 表!!!

你需要阅读How to Share Data between Stored Procedures by Erland Sommarskog

在父存储过程中创建的所有#temp 表都可供所有嵌套调用过程访问,请参阅:Sharing a Temp Table from the article listed above

来自文章:

The method itself is as simple as this:

CREATE PROCEDURE called_procedure @par1 int,
                                  @par2 bit,
                                  ... AS
   ...
   INSERT/UPDATE/DELETE #tmp
go
CREATE PROCEDURE caller AS
   DECLARE ...
   CREATE TABLE #mytemp (col1 int     NOT NULL,
                         col2 char(5) NULL,
                        ...)
   ...
   EXEC called_procedure @par1, @par2 ...
   SELECT * FROM #mytemp
go

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多