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");
}

輕鬆搞定。

Tips of how to execute T-SQL scripts generated by SSMS which containing GO commands.


Comments

Be the first to post a comment

Post a comment