在.NET中,GO语句破坏了SQL的执行。

20 浏览
0 Comments

在.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();

有什么想法吗?

0
0 Comments

在.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执行失败的方法。可以根据实际情况进行调整和优化。

0
0 Comments

使用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版本。

0
0 Comments

在.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分割的实现方法。

原文链接:https://stackoverflow.com/a/18597052/80274

0