【问题标题】:GO 'syntax error near GO' in SQL executionGO SQL 执行中的“GO 附近的语法错误”
【发布时间】:2015-02-02 18:10:55
【问题描述】:

我遇到了与 GO statements blowing up sql execution in .NET 相同的问题,并尝试实施 Matt Johnson 提供的解决方案,并寻求帮助以使其正常工作。我已经使用 C# 工作了几个月,所以我仍然很年轻。

  1. 这怎么称呼?我试过了

    var cmd = SplitSqlStatements(cmd);
    

    但得到一个错误:

    '不能将类型'System.Collections.Generic.IEnumerable'隐式转换为'string'

  2. 不完全理解 Regex.Split,但我的 GO 字符串是 "\r\nGO\r\n" 那么我可以将拆分从@"^\s*GO\s* ($ | \-\- .*$)" 更改为 @"^\r\nGO\r\n$ | \-\- .*$)" 吗?我不知道| \-\- .*$ 做了什么。

  3. 我的字符串与 + 连接,但我在开头看到 @"。这是否意味着我需要摆脱 + 连接?
  4. 我的字符串有 + '\n' + 我试图插入换行符的地方,可以用 System.Environment.Newline 替换它们还是应该完全删除它们?

代码:

private static IEnumerable<string> SplitSqlStatements(string sqlScript)
{
    // Split by "GO" statements
    var statements = Regex.Split(
        sqlScript,
        @"^\s*GO\s* ($ | \-\- .*$)",
        RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);

    // Remove empties, trim, and return
    return statements
        .Where(x => !string.IsNullOrWhiteSpace(x))
        .Select(x => x.Trim(' ', '\r', '\n'));
}

我的字符串示例:

string sqlHeader = " Use " + "R04_FDW  " + "\r\nGO\r\n" + "SET ANSI_NULLS ON" + "\r\nGO\r\n" + "SET QUOTED_IDENTIFIER ON" + "\r\nGO\r\n" + "SET ANSI_PADDING ON" + "\r\nGO\r\n";
string sqlName = "CREATE TABLE " + dwSchema + "." + dwTN + "  (" + '\n';
string sqlNonCluster = "CREATE UNIQUE NONCLUSTERED INDEX [ak_" + dwTN + "__Sta3n_PrimaryKeys]" + "  ON [" + dwSchema + "].[" + dwTN + "]" + '\n' + "(" + '\n';
SqlCommand cmd = new SqlCommand(sqlHeader + sqlName + sqlColumns + sqlFoot + sqlCluster + sqlNonCluster, vx130);

【问题讨论】:

  • 一旦字符串被分割,你需要在foreach循环中执行每个语句吗?你有发生这种情况的代码吗?
  • 如果您手动构建字符串,为什么还要麻烦包含 GO 语句只是为了删除它们?
  • 仅供参考,这些 SQL 都不需要“GO”来分隔批次。它都可以作为单个SqlCommand 运行。就像从“USE”到最后一样。除非您还创建 proc、函数或视图,否则这会使单个 exec 过于复杂。
  • srutzky 我想这是真的,但如果不是第一个批处理命令,如 CTE 之类的其他命令将无法正确执行。但你是对的,我没有做任何事情。我没有尝试我能做什么或不能做什么,而是遵循 SQL 脚本格式。这可能是重新审视习惯的好时机。

标签: c# regex tsql ado.net


【解决方案1】:
  1. 您正在重复使用相同的变量作为输入作为结果,所以 那不可能。使用var cmd = SplitSqlStatements(sqlAll) 或类似的。 var 声明一个新的变量类型 根据使用情况推断。
  2. 如果这些行上没有 SQL cmets,只需使用 "^\s*GO\s*$" 作为你的模式。剩下的就是处理这些 cmets。
  3. 没有。 @"" 只是减少字符串文字转义的一种方法;它不会影响您使用字符串(文字或其他)的方式。
  4. 如果您愿意,可以交换它们,但除非您将文字两字符序列 \n 传递给 SQL,否则这并不重要:它们只是空格。

【讨论】:

  • 谢谢,您的指点让我继续前进。最后一个问题。该链接警告脚本中的其他 GO。字符 GO 可能出现在列名中。如何防止它们被删除?
  • @ThomAsh:正则表达式中的 ^ 和 $ 分别锚定到一行的开头和结尾,所以除非你有一个名为 GO 的列都在它自己的行上,两边没有逗号或任何东西,这不会是一个问题。
猜你喜欢
  • 2017-09-23
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多