如何使用SqlConnection使用注释和GO语句执行SQL?

我似乎无法执行使用DbCommand对象创建数据库的SQL。 我究竟做错了什么? 这是我的代码:

DbConnection connection; // initialized and opened elsewhere DbCommand cmd = connection.CreateCommand(); cmd.CommandText = sql; cmd.ExecuteNonQuery(); 

这是错误:

查询语法无效。,在术语“/”,第1行,第2列附近。说明:在执行当前Web请求期间发生了未处理的exception。 请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

exception详细信息:System.Data.EntitySqlException:查询语法无效。,在术语“/”,第1行,第2列附近。

这是文件的第一部分。 仅针对第一行的注释抛出exception:

 /****** Object: Table [dbo].[User] Script Date: 10/08/2009 12:14:29 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[User]( [Id] [int] IDENTITY(1,1) NOT NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [EmailAddress] [nvarchar](100) NULL, CONSTRAINT [PK_User] 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 

这个相同的SQL脚本从SQL Management Studio Express执行得很好(实际上该应用程序生成了这个脚本!)。 它只是Visual Studio自己的Server Explorer查询视图,而且我自己的代码似乎失败了。

您需要使用SQL管理类而不是普通的SqlCommand。 此页面显示了如何执行此操作。 如果您尝试自己解析SQL,那么总会有您错过的边缘情况。 例如,如果代码中的字符串包含带有前导和尾随回车的单词“GO”,该怎么办?

添加以下参考:

  • Microsoft.SqlServer.Smo
  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Management.Sdk.Sfc (编辑:不需要此引用)

然后你可以使用这段代码:

 string connectionString, scriptText; SqlConnection sqlConnection = new SqlConnection(connectionString); ServerConnection svrConnection = new ServerConnection(sqlConnection); Server server = new Server(svrConnection); server.ConnectionContext.ExecuteNonQuery(scriptText); 

这是我前一段时间在我的博客上发布的可能解决此问题的代码片段:

 private static void RunScript(SqlConnection connection, string script) { Regex regex = new Regex(@"\r{0,1}\nGO\r{0,1}\n"); string[] commands = regex.Split(script); for (int i = 0; i < commands.Length; i++) { if (commands[i] != string.Empty) { using(SqlCommand command = new SqlCommand(commands[i], connection)) { command.ExecuteNonQuery(); command.Dispose(); } } } } 

它将SQL脚本拆分为单独的命令并执行它们中的每一个。 我经常使用它来设置生成的SQL脚本的测试数据库。

我发现你得到一个EntitySqlException很奇怪……

您可以选择的另一个解决方案是通过osql命令行工具执行此脚本。 您可以创建一个System.Diagnostics.Process实例,并使用此过程调用osql,然后执行该脚本。

 System.Diagnostics.Process p = new System.Diagnostics.Process (); p.StartInfo.FileName = Environment.GetEnvironmentVariable ("COMSPEC"); p.StartInfo.UseShellExecute = false; p.StartInfo.ErrorDialog = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardOutput = true; p.Start (); p.StandardInput.WriteLine ("echo off"); string command = @"osql -U -b -e -S " + servername + " -d " + databasename + " -i \'" + filename + "\'"; p.StandardInput.WriteLine (command); p.StandardInput.WriteLine ("exit"); p.WaitForExit (); 

在SQL Server中,您可以使用简单的空格分隔符连接任意数量的查询,但为此您需要删除“GO”。
例子:

 设置ARETABORT上的BEGIN TRANSACTION SET QUOTED_IDENTIFIER设置NUMERIC_ROUNDABORT OFF设置CONCAT_NULL_YIELDS_NULL设置ANSI_NULLS设置ANSI_PADDING设置ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION $删除此GO这里$ CREATE TABLE dbo.Tmp_Tralala(ERRID numeric(18,0)NOT NULL))ON [主要] $删除此GO这里$ IF EXISTS(SELECT * FROM dbo.Tralala)EXEC('INSERT INTO ..etc