簡體   English   中英

在系統中,通過“ ExecuteReader”執行的多個SQL命令我只能操作SQL語句

[英]Multiple SQL commands executed via “ExecuteReader” in a system I can only manipulate SQL statements

我必須配置一個為我提供輸入SQL語句的區域的系統。

請務必注意,我們無法修改正在配置的系統。

我相信系統是用C#構建的(肯定是.net,但C#是一個猜測)。

無論如何,我正在嘗試創建一個腳本,該腳本將:

  1. 創建一個臨時表
  2. 創建一個臨時過程(它將插入到創建的表中)
  3. 調用臨時程序4次
  4. 讀取臨時表作為對系統調用的響應。

就像是:

CREATE Procedure #myTempProcedure(
  @param1 nvarchar(max)
) as 
begin
  insert #tempTable (col1, col2) select aCol, bCol from table2 where col2 = @param1;
end;


CREATE TABLE #tempTable
(col1 nvarchar(512),
(col2 nvarchar(512));

EXEC #myTempProcedure N'val1';
EXEC #myTempProcedure N'val2';
EXEC #myTempProcedure N'val3';
EXEC #myTempProcedure N'val4';

select col1, col2 from #tempTable;

系統很可能通過C# SqlCommand.ExecuteReader()方法執行我的腳本。 因為我可以在我創建的簡單C#應用程序中模擬問題。

問題在於,執行該腳本時,系統(或SQL Server)假定過程主體為整個腳本,並且似乎無視my ; 在上面示例的第6行中。 我的目的是這樣; 標志着過程創建的結束。

在Management Studio中執行此腳本需要將GO放置在上面示例的第7行中,否則系統報告的相同問題將在Management Studio中發生。

我可以在此腳本中使用GO等效功能使其正常工作嗎?

還是有更好的方法編寫腳本?

我具有Oracle的背景,並且仍在使用SQL Server的常用技巧...除了此處的創建過程之外,系統還接受多個命令,因此我傾向於相信這里可以使用SQL Server的技巧。

先感謝您!

問題是,從語法上講,沒有方法可以創建一個過程,然后再在同一批處理中執行某些操作。 編譯器不知道它的結尾,分號之類的東西也無法解決(因為分號只能終止一條語句,而不能終止批處理)。

使用動態SQL(並修復一個語法錯誤)可以起作用:

EXEC('
    CREATE Procedure ##myTempProcedure(
        @param1 nvarchar(max)
    ) as 
    begin
      insert #tempTable (col1, col2) select aCol, bCol from table2 where col2 = @param1;
    end;
');


CREATE TABLE #tempTable
(
    col1 nvarchar(512),
    col2 nvarchar(512)
);

EXEC ##myTempProcedure N'val1';
EXEC ##myTempProcedure N'val2';
EXEC ##myTempProcedure N'val3';
EXEC ##myTempProcedure N'val4';

select col1, col2 from #tempTable;

EXEC('DROP PROC ##myTempProcedure;');

1)如果您無法更改或向系統添加任何內容,請查看許多人在服務器上存在的權利。 即,創建過程語句。

2)你可以做些小運動

使用SqlConnection()打開連接對象,使連接保持打開狀態,直到執行所有語句為止

即a)創建您的#table b)執行您的insert語句。 c)從#table中選擇*,這應該可以使您從臨時表中獲取要恢復的數據注意,我在這里跳過了整個過程。

您可以執行以半冒號分隔的sql語句,而不是創建存儲過程。 您可以通過這種方式執行多個語句。 另外,如果要創建臨時表並向其加載數據,則可以將同一連接與多個sql命令一起使用。

鑒於proc的定義沒有改變, 並且在此特定過程結束后proc中不存在任何實際危害,因此它很可能只是正好存在的常規(即非臨時)存儲過程在tempdb 使用在tempdb創建的常規存儲過程的好處是,使用全局臨時存儲過程時,您不必擔心潛在的名稱沖突。 該腳本僅需要確保存儲過程存在。 但是無需手動刪除存儲過程或自動清理存儲過程。

以下代碼改編自@RBarryYoung的答案

IF (OBJECT_ID(N'tempdb.dbo.myTempProcedure') IS NULL)
BEGIN
  USE [tempdb];

  EXEC('
      CREATE PROCEDURE dbo.myTempProcedure(
          @param1 NVARCHAR(MAX)
      ) AS 
      BEGIN
        INSERT INTO #tempTable (col1, col2)
          SELECT aCol, bCol
          FROM table2
          WHERE col2 = @param1;
      END;
');
END;

CREATE TABLE #tempTable
(
    col1 NVARCHAR(512),
    col2 NVARCHAR(512)
);

EXEC tempdb.dbo.myTempProcedure N'val1';
EXEC tempdb.dbo.myTempProcedure N'val2';
EXEC tempdb.dbo.myTempProcedure N'val3';
EXEC tempdb.dbo.myTempProcedure N'val4';

SELECT col1, col2 FROM #tempTable;

唯一的區別是,非臨時存儲過程不會在當前數據庫的上下文中執行,而是像其他任何非臨時存儲過程一樣,在存在該數據庫的上下文中運行,在這種情況下是tempdb 因此,從中選擇的表(即table2 )需要完全合格。 這意味着,如果proc需要在多個數據庫中運行並引用每個數據庫的本地對象,則此方法可能不是一種選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM