在.NET中,GO语句破坏了SQL的执行。
在.NET中,GO语句破坏了SQL的执行。
我有一个非常简单的C#命令行应用程序,用于执行由SQL Server生成的脚本模拟模式和数据。它在"GO"语句上出现问题。错误消息如下:
附近的语法不正确'GO'。
这是完整的SQL脚本:
/****** 对象:表[gym]。[MembershipStatus] 脚本日期:2013年9月3日9:24:01 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [gym]。[MembershipStatus]( [MembershipStatusID] [tinyint] IDENTITY(1,1) NOT NULL, [Name] [varchar](75) NOT NULL, [Description] [varchar](400) NOT NULL, [AllowCheckin] [bit] NOT NULL, [IncludeInCollections] [bit] NOT NULL, [ScheduleFutureInvoices] [bit] NOT NULL, CONSTRAINT [MembershipStatus_PK] PRIMARY KEY CLUSTERED ( [MembershipStatusID] 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 SET IDENTITY_INSERT [gym]。[MembershipStatus] ON INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (1, N'Active', N'Active', 1, 1, 1) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (2, N'Cancelled', N'Cancelled', 0, 1, 0) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (3, N'Collection', N'Collection', 0, 0, 0) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (4, N'Deleted', N'Deleted', 0, 0, 0) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (5, N'Expired', N'Expired', 1, 1, 1) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (6, N'Freeze', N'Freeze', 0, 1, 0) INSERT [gym]。[MembershipStatus] ([MembershipStatusID], [Name], [Description], [AllowCheckin], [IncludeInCollections], [ScheduleFutureInvoices]) VALUES (7, N'Inactive', N'Inactive', 0, 1, 1) SET IDENTITY_INSERT [gym]。[MembershipStatus] OFF ALTER TABLE [gym]。[MembershipStatus] ADD DEFAULT ('') FOR [Name] GO ALTER TABLE [gym]。[MembershipStatus] ADD DEFAULT ('') FOR [Description] GO ALTER TABLE [gym]。[MembershipStatus] ADD DEFAULT ((0)) FOR [AllowCheckin] GO ALTER TABLE [gym]。[MembershipStatus] ADD DEFAULT ((0)) FOR [IncludeInCollections] GO ALTER TABLE [gym]。[MembershipStatus] ADD DEFAULT ((0)) FOR [ScheduleFutureInvoices] GO
我的代码的相关部分如下所示:
SqlCommand command = new SqlCommand(script, connection); command.CommandType = CommandType.Text; command.ExecuteNonQuery();
有什么想法吗?
在.NET中,使用GO
语句会导致SQL执行失败的问题。出现这个问题的原因是在SQL脚本中使用了GO
语句,而在.NET中,GO
并不是SQL的一部分,它是SQL Server Management Studio(SSMS)的扩展,用于分隔多个SQL语句。因此,在使用GO
语句时,需要进行处理。
为了解决这个问题,可以使用正则表达式将SQL脚本按照GO
语句进行分割。同时,需要注意以下情况:
- SQL脚本中可能存在其他部分包含"GO"
的文本,需要进行排除。
- GO
语句前后可能存在空格或注释,需要进行处理。
下面是一个用于分割SQL语句的方法的示例代码:
private static IEnumerable<string> SplitSqlStatements(string sqlScript) { // 将行结束符统一为\n,以匹配RegexOptions.Multiline sqlScript = Regex.Replace(sqlScript, @"(\r\n|\n\r|\n|\r)", "\n"); // 按照"GO"语句进行分割 var statements = Regex.Split( sqlScript, @"^[ \t]*GO[ \t]*\d*[ \t]*(?:--.*)?$", RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase); // 移除空语句,进行修剪并返回 return statements .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.Trim(' ', '\n')); }
这个方法首先将行结束符统一为\n,然后使用正则表达式将SQL脚本按照GO
语句进行分割。最后,移除空语句并进行修剪,返回分割后的SQL语句。
需要注意的是,这个方法并不适用于包含字符串拼接的情况,例如:"SELECT * FROM " + "SomeTable; GO " + "SELECT * FROM SomeOtherTable; GO"
。因为GO
语句不能与其他语句拼接在同一行上。
以上是解决在.NET中使用GO
语句导致SQL执行失败的方法。可以根据实际情况进行调整和优化。
使用GO
语句会导致.NET中的SQL执行问题。出现这个问题的原因是缺少必要的dll文件,并且在.NET 4+版本中需要在App.config文件中添加一个标志来解决这个问题。解决方法是引用以下dll文件:Microsoft.SqlServer.ConnectionInfo.dll、Microsoft.SqlServer.Management.Sdk.Sfc.dll、Microsoft.SqlServer.Smo.dll、Microsoft.SqlServer.SqlEnum.dll,并在代码中执行以下操作:
using (SqlConnection conn = new SqlConnection(connection)) { Server db = new Server(new ServerConnection(conn)); string script = File.ReadAllText(scriptPath); db.ConnectionContext.ExecuteNonQuery(script); }
此解决方法可以正确执行包含"GO"关键字和跨越"GO"语句的"BEGIN TRANSACTIONS/COMMIT"的脚本。但需要注意,这可能会限制数据库版本和安装。此外,虽然有一个非官方的NuGet包支持这些程序集,但不能保证未来的支持,因此在使用时要谨慎。另外,还有一些其他的解决方法,如引用ms.sql.batchparserclient.dll文件或使用最新的.NET 6版本。
在.NET中,使用GO
语句执行SQL会导致问题。这是由于GO
不是SQL的一部分,而是SQL Server Management Studio用来分割脚本的。解决方法是将查询读入一个字符串,然后按独立的GO
行进行分割(可以使用正则表达式进行分割)。
以下是解决方法的示例代码:
//最好释放SqlCommand,我还切换了构造函数,这样可以重用SqlCommand。 using(SqlCommand command = new SqlCommand()) { command.Connection = connection; var scripts = Regex.Split(script, @"^\w+GO$", RegexOptions.Multiline); foreach(var splitScript in scripts) { command.CommandText = splitScript; command.ExecuteNonQuery(); } }
可以参考Matt Johnson的回答了解一个更好的GO
分割的实现方法。