2013-01-09 56 views
4

我試圖從C#Windows應用程序對數據庫執行腳本(.sql文件)。 SQL文件包含'GO'語句;這意味着我正在使用對象SMO。從C#執行SQL腳本並記錄錯誤

我想繼續錯誤日誌的任何錯誤可能腳本的數據庫上執行過程中發生的。有沒有辦法做到這一點?

這是我使用的代碼:

using (SqlConnection sqlConnection = new SqlConnection(connectionString)) 
{ 
    ServerConnection svrConnection = new ServerConnection(sqlConnection); 
    Server server = new Server(svrConnection); 

    string script = File.ReadAllText("upgradeDatabase.sql"); 

    try 
    { 
     server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError); 
    } 
    catch (Exception ex) 
    { 
     //handling and logging for the errors are done here 
    } 
} 

任何幫助表示讚賞!

回答

4

我想你這裏有兩個問題:

首先,你調用接受一個字符串ExecuteNonQuery方法,而不是一個StringCollection。我想這種方法不能識別用於分離批處理語句的GO。相反,接受StringCollection的方法ExecuteNonQuery的文檔聲明GOes已識別

第二個問題是ExecutionTypes.ContinueOnError通過。在這種情況下,相同的文檔指出,如果出現問題,您將無法收到異常。

我認爲最好的方法應該是在GO中拆分輸入文本,然後構建一個StringCollection以傳遞給ExecuteNonQuery方法並檢查返回的受影響行的數組。 像這樣(應進行測試)

using (SqlConnection sqlConnection = new SqlConnection(connectionString)) 
{ 
    ServerConnection svrConnection = new ServerConnection(sqlConnection); 
    Server server = new Server(svrConnection); 

    string script = File.ReadAllText("upgradeDatabase.sql"); 
    string[] singleCommand = Regex.Split(script, "^GO", RegexOptions.Multiline); 
    StringCollection scl = new StringCollection(); 
    foreach(string t in singleCommand) 
    { 
     if(t.Trim().Length > 0) scl.Add(t.Trim()); 
    } 
    try 
    { 
     int[] result = server.ConnectionContext.ExecuteNonQuery(scl, ExecutionTypes.ContinueOnError); 
     // Now check the result array to find any possible errors?? 
    } 
    catch (Exception ex) 
    { 
     //handling and logging for the errors are done here 
    } 
} 

當然另一種方法是在執行每個單個語句並取出ContinueOnError標誌。然後捕獲並記錄可能的例外情況。但是這肯定會變慢。

+0

在文本中與** GO **分離可能會破壞腳本,想象一下你必須選擇CATE ** GO ** RY FROM WHATEVER –

+1

您是否注意到我使用將GO固定到行首的正則表達式模式? http://msdn.microsoft.com/en-US/library/az24scfc(v=vs.90) – Steve

+0

謝謝史蒂夫你的解決方法。我正在執行每條單一語句,並在發生時捕獲任何錯誤。 – naregkar

0

可以使用smo庫,where是如何添加到項目

FileInfo file = new FileInfo("upgradeDatabase.sql"); 
string script = file.OpenText().ReadToEnd(); 
SqlConnection conn = new SqlConnection(sqlConnectionString); 
Server server = new Server(new ServerConnection(conn)); 
server.ConnectionContext.ExecuteNonQuery(script); 
+0

downvoter請發表評論 –

+0

隨着你的回答,腳本將停止執行第一個錯誤。我希望OP是畢竟的錯誤。(不downvoter) –

+0

啊,右@DavidWhite,感謝您的更正 –

0

我真的很喜歡這個變體,它使用InfoMessage事件和處理程序:

 using(SqlConnection sc = new SqlConnection(connStr)) 
     { 
      sc.InfoMessage += new SqlInfoMessageEventHandler(sc_InfoMessage); 
      Server db = new Server(new ServerConnection(sc)); 
      db.ConnectionContext.ExecuteNonQuery(commandFileText, ExecutionTypes.ContinueOnError); 
     } 

您將需要添加一個參考以下內容:

  • Microsoft.SqlServer.ConnectionInfo.dll
  • Microsoft.SqlServer.Management.Sdk.Sfc.dll
  • Microsoft.SqlServer.Smo.dll
  • Microsoft.SqlServer.SqlEnum.dll
0

我不是程序員(DBA),因此我不確定。 我認爲以下內容可能有幫助

svrConnection.FireInfoMessageEventOnUserErrors = true;