【问题标题】:How to INSERT specified columns from stored procedure into #tempTable如何将存储过程中的指定列插入#tempTable
【发布时间】:2020-01-10 18:25:37
【问题描述】:

当需要从存储过程中插入数据时,所有示例都这样做:

INSERT INTO #tempTable
EXEC storedProcedureName @parameter1

我担心我想要的东西是不可能的......下面是我所追求的伪代码。我想在我的插入中包含我在调用存储过程时使用的参数。如果我可以选择不必插入存储过程返回的所有列,那就太好了:

INSERT INTO #tempTable (sp_column1, sp_column2, @parameter1)
    EXEC storedProcedureName @parameter1 (column1, column2)

或者使用 VALUES 关键字可能看起来像这样:

INSERT INTO #tempTable (sp_column1, sp_column2, @parameter1)
    EXEC storedProcedureName @parameter1 VALUES (column1, column2)

【问题讨论】:

  • 这里有几个解决这个问题的方法:stackoverflow.com/questions/653714/…
  • @sql_knievel 是的......我一直在关注那个帖子。在我提出问题之前,我在那篇文章中看到的答案是使用 OPENROWSET。我绝对不能使用 OPENROWSET,所以我想我会发布我的问题,希望有另一种方法。
  • 简短回答 - 不。执行存储过程会返回固定数量的列的结果集。您可以在使用您为执行提供的参数执行存储过程后更新行。您可以为“参数”列添加或修改默认约束。我可以想到其他选择——所有这些都需要的不仅仅是你的单一陈述。当然,您可以更改存储过程以将参数作为结果集的一部分返回 - 但您似乎已经忽略了这种方法。
  • @SMor 你知道如何在存储过程插入后立即更新#tempTable 吗?基本上......是否有某种构造来捕获插入的最后一条记录以便我更新它......而不是寻找#tempTable中存在的ID......类似于UPDATE #tempTable SET = param1 WHERE lastInsertedRecord
  • 您可以为引用 SESSION_CONTEXT 的额外列设置具有默认约束的临时表,然后将该值设置为插入之前的参数值。所以不需要动态删除和创建默认值

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


【解决方案1】:

为了从存储过程中INSERT 并添加/删除从该存储过程返回的列,我需要使用两个临时表。从存储过程执行时,无法向INSERT 添加或选择列。

代码解释

我想创建一个通用功能示例来模拟存储过程的使用。这段代码和我的生产代码的唯一区别是我用模拟数据代替了我的存储过程。我使用一个名为#StoredProc 的临时表来管理它,并在其中插入了一些带有 ID 的假数据。

1:用于实际概念验证和测试的第一个临时表称为#Report。它用于存储存储过程返回的默认列。这些列必须完全匹配 1 到 1,这部分是我面临的问题。存储过程将FieldID 作为其参数,但是返回的结果集不包括FieldID 或任何其他ID。这就是我最初的问题所在,因为我想将结果以及用于获取该数据的任何参数都存储在我的临时表中。

2: 第二个临时表#ReportwithID 用于存储来自#Report 临时表的数据。当数据移动到#ReportwithID 临时表时,我可以包含参数。当插入#ReportwithID 表时,我将FieldID 参数包含在游标while 循环内的@ReportID 变量中。有了这个,我终于有了从存储过程中提取的数据以及我想要捕获的任何其他列......在这种情况下,我希望查看每个返回的记录以及获取此数据的参数。

最后:当光标 while 循环完成遍历所有 ID 并将数据存储到 #ReportwithID 临时表中时,我将 SELECT * 的数据从中取出,以便我可以查看它。

下面的代码块可以在任何 SQL Server 数据库中运行,前提是您拥有执行此操作的所有适当权限,例如创建临时表...等。

/* --- BEGIN Create fake data to simulate the data being pulled back by a stored procedure --- */
DROP TABLE IF EXISTS #StoredProc;

CREATE TABLE #StoredProc
(
    fieldID INT,
    fName   VARCHAR(200),
    lName   VARCHAR(50),
);
GO

INSERT INTO #StoredProc
    SELECT 1 AS fieldID, 'Jimmy'      AS fName, 'Fallon'   AS lName UNION ALL
    SELECT 2 AS fieldID, 'Jason'      AS fName, 'Fick'     AS lName UNION ALL
    SELECT 3 AS fieldID, 'Dilly'      AS fName, 'Dally'    AS lName UNION ALL
    SELECT 4 AS fieldID, 'Jim'        AS fName, 'Jacko'    AS lName UNION ALL
    SELECT 5 AS fieldID, 'Brina'      AS fName, 'Burton'   AS lName UNION ALL
    SELECT 6 AS fieldID, 'Tim'        AS fName, 'McMally'  AS lName UNION ALL
    SELECT 7 AS fieldID, 'Sam'        AS fName, 'Bateman'  AS lName UNION ALL
    SELECT 8 AS fieldID, 'Nelly'      AS fName, 'Newsome'  AS lName UNION ALL
    SELECT 9 AS fieldID, 'J-Schwilly' AS fName, 'McNilly'  AS lName
GO
/* --- END Creating Fake stored procedure data --- */

/* If the temp tables exists we want to remove it before we start inserting records. */
DROP TABLE IF EXISTS #Report;
DROP TABLE IF EXISTS #ReportwithID;

/* Stored procedure Physician Report Fields for Temp Table */
CREATE TABLE #Report
(
    fName VARCHAR(200),
    lName VARCHAR(50),
);

/* Stored procedure Physician Report Fields for Temp Table */
CREATE TABLE #ReportwithID
(
    fieldID INT,
    fName   VARCHAR(200),
    lName   VARCHAR(50),
);

/* Turns Off the Servers return of the Rows affected back to the Client */
SET NOCOUNT ON;

/* --- CURSOR STUFF --- */
/* Declare Variables to store data retrieved back from the Cursor */
DECLARE @RecordID   INT;

/* Declare Cursor */
DECLARE cur_FakeReportData CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY --In order to make my cursors as efficient as possible, Use the following declarations
FOR /* Build up Fake IDs to Loop Over */
    SELECT 1 AS fieldID UNION ALL
    SELECT 2 AS fieldID UNION ALL
    SELECT 3 AS fieldID UNION ALL
    SELECT 4 AS fieldID UNION ALL
    SELECT 5 AS fieldID UNION ALL
    SELECT 6 AS fieldID UNION ALL
    SELECT 7 AS fieldID UNION ALL
    SELECT 8 AS fieldID UNION ALL
    SELECT 9 AS fieldID
;

/* When we are ready to use the Cursor we must first OPEN it */
OPEN cur_FakeReportData;

/* Fetch a row from the cursor into one or more variables */
FETCH NEXT FROM cur_FakeReportData INTO @RecordID;

PRINT 'Fetch_Status: ' + CAST(@@FETCH_STATUS AS Varchar);

/* While Loop: If the Previous Fetch Was successful enter the Loop.
 |  0   The FETCH statement was successful.
 | -1   The FETCH statement failed or the row was beyond the result set.
 | -2   The row fetched is missing.
 | -9   The cursor is not performing a fetch operation.
*/
WHILE @@FETCH_STATUS = 0

    BEGIN
        BEGIN TRY
            PRINT(@RecordID);
            INSERT INTO #Report
            --EXEC report.Report @RecordID;
            SELECT fName, lName FROM #StoredProc WHERE fieldID = @RecordID; /* Simulating pulling data from a STORED Proc */

            INSERT INTO #ReportwithID
            SELECT @RecordID AS fieldID, r.*
            FROM #Report r;

            DELETE FROM #Report;

        END TRY
        BEGIN CATCH
            SELECT  
                  ERROR_NUMBER()    AS ErrorNumber  
                , ERROR_SEVERITY()  AS ErrorSeverity  
                , ERROR_STATE()     AS ErrorState  
                , ERROR_PROCEDURE() AS ErrorProcedure  
                , ERROR_LINE()      AS ErrorLine  
                , ERROR_MESSAGE()   AS ErrorMessage
                , @RecordID         AS RecordID;
        END CATCH

        /* FETCH NEXT Record FROM Cursor */
        FETCH NEXT FROM cur_FakeReportData INTO @RecordID;
    END
;

PRINT 'Fetch_Status: ' + CAST(@@FETCH_STATUS AS Varchar) +' Rows: '+ CAST(@@CURSOR_ROWS AS Varchar)

/* Use the below to View status of ALL Cursors by Session ID */
--SELECT * FROM sys.dm_exec_cursors(@@SPID) -- Use 0 to view ALL Sessions

/* When you are done with the Cursor be sure to CLOSE it */
CLOSE cur_FakeReportData;
/* Deallocate the cursor to release it from memory. */
DEALlOCATE cur_FakeReportData;

--SELECT * FROM #Report;

SELECT *
FROM #ReportwithID
;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2011-07-23
    相关资源
    最近更新 更多