我有,一個大的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+線。
任何想法我做錯了什麼?
奇怪你爲什麼有這個大腳本文件,可以作爲單個腳本運行,並且覺得需要通過GO分割它並獨立調用每個批處理?爲什麼不一次只運行整個腳本?此外,我不知道我明白爲什麼你不能弄清楚發生了什麼......你的Control.WriteLine輸出在哪裏?你怎麼知道一些命令沒有運行? –
如果沒有單個語句需要成爲第一批,則可以用換行符替換NewLine + GO + NewLine並運行腳本;否則,你最好看看[這個SO回答](http://stackoverflow.com/questions/3102768/ado-net-and-executenonquery-how-to-use-ddl)。 –
@AaronBertrand我將它分開,因爲我想執行每條語句並在失敗時得到結果。另外我想確保所有其他語句在一個語句失敗時繼續。該方法從cmd.exe行工具中調用,因此我得到結果或將其重定向到文本文件。另一個原因是超時。我的一些陳述也是更復雜的東西(比如需要更多時間的程序)。從管理工作室調用它只是爲了測試,通常所有的語句都是從我的命令工具調用的。 – YvesR