5

使用 C#/PowerShell 執行 SSMS 所產生包含 GO 的 SQL Script

 3 years ago
source link: https://blog.darkthread.net/blog/exec-sql-script-with-go/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
使用 C#/PowerShell 執行 SSMS 所產生包含 GO 的 SQL Script-黑暗執行緒

SSMS 有個方便功能,在 Table、View、Function、Stored Procedure 等物件用右鍵選單可以產生建立該物件的 SQL Script。

產生的資料表 Script 連 Description 註解都有,拿到新資料庫執行可建立一模一樣的資料表,十分方便:

USE DB_NAME
GO

/****** Object:  Table [dbo].[Blogs]    Script Date: 2021/8/5 下午 09:20:17 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Blogs](
	[BlogId] [int] IDENTITY(1,1) NOT NULL,
	[Url] [nvarchar](max) NULL,
 CONSTRAINT [PK_Blogs] PRIMARY KEY CLUSTERED 
(
	[BlogId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'部落格代碼' , @level0type=N'SCHEMA',
        @level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Blogs', @level2type=N'COLUMN',@level2name=N'BlogId'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'網址' , @level0type=N'SCHEMA',@level0name=N'dbo', 
        @level1type=N'TABLE',@level1name=N'Blogs', @level2type=N'COLUMN',@level2name=N'Url'
GO

但有個小問題,如果這個指令檔不是用 SSMS 跑,而是交給 .NET 或 PowerShell 寫的批次程式用 ADO.NET 執行,其中的 GO 指令會出錯 - Incorrect syntax near 'GO.。

依據官方文件,GO 並不屬於 T-SQL,是 sqlcmd、osql 工具程式跟 SSMS 才認得的指令,用以區隔一個批次指令的範圍,類似一次 SqlCommand.ExecuteNonQuery() 動作。

依據這個原理,我們可以逐行解析,遇到 GO 之前串接 Script 內容,遇到 GO 時將累積的 Script 一次送出,便能實現跟 SSMS 類似的邏輯。

寫成程式碼的話會像這樣:

static void Main(string[] args)
{
    var lines = File.ReadAllLines("Create-Table.sql");
    using (var cn = new SqlConnection(cnStr))
    {
        cn.Open();
        var cmd = cn.CreateCommand();
        var sb = new StringBuilder();
        foreach (var line in lines)
        {
            if (line == "GO")
            {
                cmd.CommandText = sb.ToString();
                cmd.ExecuteNonQuery();
                sb.Clear();
            }
            else
            {
                sb.AppendLine(line);
            }
        }
    }
    Console.WriteLine("Done");
}

輕鬆搞定。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK