我需要找到一種 T-SQL 方法來從我從 .sql 檔案中讀取的腳本中洗掉 GO 命令。我正在使用類似于這種方法Execute SQL scripts from file,這非常適合我的需要,但是有些檔案包含 GO 命令并中斷執行,因為sp_executesql它不處理非 T-SQL 命令。如何創建一個REPLACE可以洗掉 GO 的 GO,它主要是單獨坐在一行中?或者我可以在這里申請的任何其他方法?請記住,腳本中可能還有其他 GO,它們實際上不是命令。
DECLARE @sql NVARCHAR(1000) =
'DECLARE @table AS TABLE(
[Id] INT,
[Info] NVARCHAR(100)
);
INSERT INTO @table
([Id],[Info])
VALUES
(1,''Info''),
(2,''Show must go on''),
(3,''GO'');
SELECT * FROM @table;
GO';
PRINT @sql;
EXEC sp_executesql @sql;
xp_cmdshell由于服務器安全限制,不能使用來執行腳本。SQLCMD這次也不是一個選擇。
uj5u.com熱心網友回復:
好吧,我不會聲稱這是應該這樣做的方式,但是將其記錄下來很有趣:
免責宣告:這是一個演示為什么 TSQL 是錯誤的工具 ??
我添加了更多以 GO 分隔的陳述句并在其中使用引號使其更加棘手:
DECLARE @sql NVARCHAR(1000) =
'DECLARE @table AS TABLE(
[Id] INT,
[Info] NVARCHAR(100)
);
INSERT INTO @table
([Id],[Info])
VALUES
(1,''Info''),
(2,''Show must go on''),
(3,''This includes a GO and some "quoted" text''),
(4,''GO'');
SELECT * FROM @table;
GO
SELECT TOP 10 * FROM sys.objects
GO
PRINT ''Each GO will be used to have separate patches''';
--讓我們從洗掉各種換行符開始
SET @sql = REPLACE(REPLACE(STRING_ESCAPE(@sql,'json'),'\r','\n'),'\n\n','\n');
-- 使用CS_AS-collat??ion 將避免采用“go”,因為我們(希望如此!)可以依賴“GO”:
DECLARE @json NVARCHAR(MAX) = CONCAT('["',REPLACE(REPLACE(@sql COLLATE Latin1_General_CS_AS,'GO' COLLATE Latin1_General_CS_AS,'","GO'),'\n','","'),'"]');
--上面我使用了每個大寫的“GO”和每個換行符來分隔字串。
--這樣做我們將您的字串轉換為一個json陣列--
現在我們可以將其填充到一個表中OPENJSON以讀取json陣列(省略空行)
DECLARE @tbl TABLE(RowIndex INT IDENTITY,fragment NVARCHAR(MAX));
INSERT INTO @tbl(fragment)
SELECT STRING_ESCAPE(A.[value],'json')
FROM OPENJSON(@json) A
WHERE LEN(TRIM(A.[value]))>0 AND TRIM(A.[value])!=NCHAR(9);
--我們需要這些游標變數
DECLARE @patch NVARCHAR(MAX);
-- 現在我打開一個游標 --
我們通過再次運行遞回 CTE 來構建一個 json 陣列來做到這一點。
--這次我們將在大寫的“GO”單獨位于其行中時將字串分開。
DECLARE cur CURSOR FOR
WITH cte AS
(
SELECT RowIndex, CAST(CONCAT('["',fragment) AS NVARCHAR(MAX)) growingString
FROM @tbl WHERE RowIndex=1
UNION ALL
SELECT n.RowIndex
,CONCAT(cte.growingString,CASE WHEN TRIM(n.fragment) COLLATE Latin1_General_CS_AS=N'GO' THEN N'","' ELSE n.fragment END)
FROM @tbl n
INNER JOIN cte ON n.RowIndex=cte.RowIndex 1
)
,thePatches AS
(
SELECT TOP 1 CONCAT(growingString,'"]') AS jsonArray
FROM cte ORDER BY RowIndex DESC
)
SELECT A.[value] AS patch
FROM thePatches p
CROSS APPLY OPENJSON(p.jsonArray) A;
--我們可以 - 最后 - 走下補丁并一一執行
OPEN cur;
FETCH NEXT FROM cur INTO @patch;
WHILE @@FETCH_STATUS=0
BEGIN
PRINT @patch; --PRINT out for visual control before execution!
--EXEC(@patch);
FETCH NEXT FROM cur INTO @patch;
END
CLOSE cur;
DEALLOCATE cur;
有數以百萬計的事情(例如內容中的換行符、評論部分、最大遞回)可以破壞這種方法。所以很明顯不要遵循這個建議:-)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/377494.html
標籤:sql-server 查询语句
上一篇:T-SQL計算多列中不同值的數量
