[英]Multiple SQL commands executed via “ExecuteReader” in a system I can only manipulate SQL statements
我必須配置一個為我提供輸入SQL語句的區域的系統。
請務必注意,我們無法修改正在配置的系統。
我相信系統是用C#構建的(肯定是.net,但C#是一個猜測)。
無論如何,我正在嘗試創建一個腳本,該腳本將:
就像是:
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.