2009-10-14 57 views
3

我試圖創建一個方法來在SQL Server數據庫上運行.sql文件。使用C#在SQL Server上執行sql文件

的代碼,我是:

SqlConnection dbCon = new SqlConnection(connstr); 
FileInfo file = new FileInfo(Server.MapPath("~/Installer/JobTraksDB.sql")); 
StreamReader fileRead = file.OpenText(); 
string script = fileRead.ReadToEnd(); 
fileRead.Close(); 

SqlCommand command = new SqlCommand(script, dbCon); 
try 
{ 
    dbCon.Open(); 
    command.ExecuteNonQuery(); 
    dbCon.Close(); 
} 
catch (Exception ex) 
{ 
    throw new Exception("Failed to Update the Database, check your Permissions."); 
} 

但我不斷收到關於 「附近關鍵字 'GO' 不正確的語法」 錯誤 我的SQL文件開頭是這樣的:(從SQL Management Studio中生成)

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
CREATE TABLE [dbo].[Job_Types](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [varchar](50) NOT NULL, 
CONSTRAINT [PK_JobTypes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 

我應該如何執行這個腳本?

回答

5

這是我們如何做到這一點:

protected virtual void ExecuteScript(SqlConnection connection, string script) 
    { 
     string[] commandTextArray = System.Text.RegularExpressions.Regex.Split(script, "\r\n[\t ]*GO"); 

     SqlCommand _cmd = new SqlCommand(String.Empty, connection); 

     foreach (string commandText in commandTextArray) 
     { 
      if (commandText.Trim() == string.Empty) continue; 
      if ((commandText.Length >= 3) && (commandText.Substring(0, 3).ToUpper() == "USE")) 
      { 
       throw new Exception("Create-script contains USE-statement. Please provide non-database specific create-scripts!"); 
      } 

      _cmd.CommandText = commandText; 
      _cmd.ExecuteNonQuery(); 
     } 

    } 

裝入使用一些文件閱讀功能腳本的內容。

+1

我可以看到一個bug:假設我有一個名爲'sp'的過程,腳本是'「sp」'。 'commandText.Substring(0,3)'會拋出一個'IndexOutOfRangeException'。 –

+0

@Mehrdad:是的,常見的錯誤,假設String.Substring(0,xxx)與VB函數Left(xxx)完全相同。 :-) –

+0

@WowtaH:除此之外,做得很好。 :-) –

4

GO不是一個T-SQL語句。這是暗示sqlcmd或Management Studio等客戶端工具可以將語句拆分並將其作爲單獨的批次發送。他們在自己的行上使用GO命令作爲標記來指示批次的結束。您不應將整個文件發送到SQL Server。

備註:您可以使用File.ReadAllText方法來代替這三行。

+0

OK ,那麼執行批量創建表函數的最佳方法是什麼? (這是一個web安裝程序) – dkarzon

+0

天真的方法是通過包含'GO'命令的行拆分文件,並將每個部分以循環方式發送到SQL Server。不過,我認爲你正在重新發明輪子,因爲一些開源項目(例如DotNetNuke)使用類似的技術進行安裝。你可以檢查他們的來源。 –

+0

檢查我的答案。代碼示例完美地完成了這項工作 – WowtaH

0

如果你願意,包括一對夫婦的SMO的DLL,您可以用幾行代碼執行一個腳本:

using Microsoft.SqlServer.Management.Smo; 
using Microsoft.SqlServer.Management.Common; 

    public void Exec(string script) 
    { 
     using (var conn = new SqlConnection(ConnString)) 
     { 
      var server = new Server(new ServerConnection(conn)); 
      server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError); 
     } 
    } 

的SMO庫處理GO問題,所以你不必。您將需要參考以下組件:

Microsoft.SqlServer.ConnectionInfo.dll

Microsoft.SqlServer.Management.Sdk.Sfc.dll

Microsoft.SqlServer.Smo.dll

相關問題