2012-05-25 50 views
0

我有,一個大的SQL文本文件,在那裏我有很多的SQL命令來創建表,列等奇怪的行爲從.NET執行SQL Server創建

實例行(S)表或列:

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'xcal_views') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) 
    CREATE TABLE xcal_views (lid INT NOT NULL); 
GO 

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'xcal_views_actors') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) 
    CREATE TABLE xcal_views_actors (lid INT NOT NULL); 
GO 

IF NOT EXISTS (SELECT * FROM dbo.syscolumns, dbo.sysobjects WHERE [dbo].[syscolumns].[name] = 'xlactor' AND [dbo].[sysobjects].[id] = [dbo].[syscolumns].[id] AND [dbo].[sysobjects].[id] = object_id(N'xcal_views_actors') AND OBJECTPROPERTY([dbo].[sysobjects].[id], N'IsUserTable') = 1) 
    ALTER TABLE [dbo].[xcal_views_actors] ADD xlactor INT NULL; 
GO 

IF NOT EXISTS (SELECT * FROM dbo.syscolumns, dbo.sysobjects WHERE [dbo].[syscolumns].[name] = 'lparentid' AND [dbo].[sysobjects].[id] = [dbo].[syscolumns].[id] AND [dbo].[sysobjects].[id] = object_id(N'xcal_views_actors') AND OBJECTPROPERTY([dbo].[sysobjects].[id], N'IsUserTable') = 1) 
    ALTER TABLE [dbo].[xcal_views_actors] ADD lparentid INT NULL; 
GO 

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE parent_obj = (SELECT id FROM dbo.sysobjects WHERE id = object_id(N'xcal_views_actors') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) AND OBJECTPROPERTY(id, N'IsPrimaryKey') = 1) 
    ALTER TABLE [dbo].[xcal_views_actors] 
    ADD CONSTRAINT [CT_00000501] PRIMARY KEY CLUSTERED (lid ASC); 
GO 

IF NOT EXISTS (SELECT * FROM [sys].[indexes] i INNER JOIN [sys].[objects] o ON o.object_id = i.object_id AND o.name = 'xcal_views_actors' WHERE i.name = 'parent_id') 
    CREATE INDEX parent_id ON xcal_views_actors (lparentid ASC) 
GO 

在每個命令之間我有一個額外的行GO來分隔命令。

如果我從SQL Server Management Studio運行整個patch.sql文件,所有命令都會執行並正常工作。

在.NET中,我讀取整個文本文件,然後用'GO'拆分它們,並對數據庫執行每條SQL命令。

現在奇怪的事情:一些命令不執行。我找不到原因。

這是做工作的方法:

private static void patchDatabase(string connection, string sqlfile) 
{ 
    var defaultEncoding = Encoding.Default; 
    using (FileStream fs = File.OpenRead(sqlfile)) 
    { 
    defaultEncoding = TextFileEncodingDetector.DetectTextFileEncoding(fs, defaultEncoding, 1024); 
    } 
    //Console.WriteLine(string.Format("File {0} using encoding: {1}",sqlfile, defaultEncoding)); 

    var dbPatch = new StreamReader(sqlfile, defaultEncoding); 
    string sqlPatch = dbPatch.ReadToEnd(); 
    dbPatch.Close(); 
    string[] stringSeparators = new[] {"GO"}; 
    string[] sqlPatches = sqlPatch.Split(stringSeparators, StringSplitOptions.None); 

    if (connection != null && sqlPatch.Length > 0) 
    { 
    Console.WriteLine(string.Format("Executing {0} statements from {1}", sqlPatches.Length, sqlfile)); 

    using (var cnn = new SqlConnection(connection)) 
    { 
     cnn.Open(); 
     foreach (var sql in sqlPatches) 
     { 
     if (String.IsNullOrEmpty(sql)) 
      continue; // Not a real sql statement, use next 

     using (var cmd = new SqlCommand(sql, cnn)) 
     { 
      try 
      { 
      cmd.CommandTimeout = 120; 
      cmd.ExecuteNonQuery(); 
      //int results = cmd.ExecuteNonQuery(); 
      //if (results < 1) 
      // Console.WriteLine(String.Format("Failed:\nResult: {0}\n{1}",results, sql)); 
      } 
      catch (Exception ex) 
      { 
      Console.WriteLine("Execution error!\n\n" + sql + "\n\n\n" + ex); 
      } 
     } 
     } 
     cnn.Close(); 
    } 

    } 
} 

它看起來像我的功能splutters ...

我目前的文本文件有大約6.000+線。

任何想法我做錯了什麼?

+0

奇怪你爲什麼有這個大腳本文件,可以作爲單個腳本運行,並且覺得需要通過GO分割它並獨立調用每個批處理?爲什麼不一次只運行整個腳本?此外,我不知道我明白爲什麼你不能弄清楚發生了什麼......你的Control.WriteLine輸出在哪裏?你怎麼知道一些命令沒有運行? –

+0

如果沒有單個語句需要成爲第一批,則可以用換行符替換NewLine + GO + NewLine並運行腳本;否則,你最好看看[這個SO回答](http://stackoverflow.com/questions/3102768/ado-net-and-executenonquery-how-to-use-ddl)。 –

+0

@AaronBertrand我將它分開,因爲我想執行每條語句並在失敗時得到結果。另外我想確保所有其他語句在一個語句失敗時繼續。該方法從cmd.exe行工具中調用,因此我得到結果或將其重定向到文本文件。另一個原因是超時。我的一些陳述也是更復雜的東西(比如需要更多時間的程序)。從管理工作室調用它只是爲了測試,通常所有的語句都是從我的命令工具調用的。 – YvesR

回答

0

看起來它根本不是編碼問題。

其實我產生了以下情況:

  • 我有一個數據庫「TEST_DB」

  • 我創建了一個用戶「test_db_user」,讓他的db_owner 他是SQL Server加入一般「安全 - 角色」與對象「test_db」作爲角色db_owner 他還以用戶身份添加到數據庫「test_db」 - security - user中。

  • 現在到了:我經過一些測試後再次恢復數據庫。 用戶不再列在「test_db」中 - 安全性 - 用戶 但通常仍配置爲db_owner。

不知何故,連接工作,但它並沒有不完全訪問數據庫的所有時間。真的不知道發生了什麼問題。 從管理工作室我曾經使用管理員帳戶啓動SQL批處理,這就是它一直在那裏工作的原因。

所以解決方案:確保安全設置是100%正確的,那麼它的工作原理:S

另一個問題是我的愚蠢:S!我有一些沒有dbo的創建表語句。表之前的模式,以便不同的用戶爲該表創建不同的模式名稱。

感謝所有的反饋意見。