Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用;围棋;在交易中_.net_Sql_Sql Server_Tsql_Transactions - Fatal编程技术网

.net 使用;围棋;在交易中

.net 使用;围棋;在交易中,.net,sql,sql-server,tsql,transactions,.net,Sql,Sql Server,Tsql,Transactions,我正在构建一个web应用程序,尝试在app_Start上安装/升级数据库。 安装过程的一部分是确保数据库已安装asp.net功能。为此,我使用System.Web.Management.SqlServices对象 我的意图是在一个SQL事务中完成所有数据库工作,如果其中任何一个事务失败,则回滚该事务并保持数据库不变 SqlServices对象有一个方法“Install”,该方法接受ConnectionString,但不接受事务。因此,我使用SqlServices.GenerateApplicat

我正在构建一个web应用程序,尝试在app_Start上安装/升级数据库。 安装过程的一部分是确保数据库已安装asp.net功能。为此,我使用System.Web.Management.SqlServices对象

我的意图是在一个SQL事务中完成所有数据库工作,如果其中任何一个事务失败,则回滚该事务并保持数据库不变

SqlServices对象有一个方法“Install”,该方法接受ConnectionString,但不接受事务。因此,我使用SqlServices.GenerateApplicationServicesScripts,如下所示:

string script = SqlServices.GenerateApplicationServicesScripts(true, SqlFeatures.All, _connection.Database);
SqlHelper.ExecuteNonQuery(transaction, CommandType.Text, script, ...);
然后我使用企业库中的SqlHelper

但这会引发一个异常,其中包含大量错误,下面是一些错误

Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'USE'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near 'GO'.
The variable name '@cmd' has already been declared. Variable names must be unique within a query batch or stored procedure.
我认为在SQL事务中使用GO语句可能有问题


以这种方式执行时,如何使生成的脚本工作。

GO不是SQL关键字

它是客户端工具(如SSM)使用的一个批处理分隔符,用于将整个脚本分成批


您必须自己将脚本分解成批,或者使用“-c GO”或osql之类的东西来处理“GO”

编辑,正如下面指出的,我指定了批处理实际上是正确的tran

问题不在于不能在事务中使用GO,因为GO表示批处理的结束,而且它本身不是一个T-SQL命令。您可以使用SQLCMD执行整个脚本,也可以在运行时拆分脚本,然后依次执行每个批

测试脚本:

  • 在备份服务器上恢复生产备份
  • 使用GOs运行脚本
安装脚本:

  • 关闭应用程序
  • 转到单用户模式
  • 备份数据库
  • 在故障恢复备份时使用GOs运行脚本
  • 返回到多用户模式
  • 重新启动应用程序

    • 可怜的人解决这一问题的方法:拆分SQL on the GO语句。比如:

      private static List<string> getCommands(string testDataSql)
      {
          string[] splitcommands = File.ReadAllText(testDataSql).Split(new string[]{"GO\r\n"}, StringSplitOptions.RemoveEmptyEntries);
          List<string> commandList = new List<string>(splitcommands);
          return commandList;
      }
      
      private static List getCommands(字符串testDataSql)
      {
      string[]splitcommands=File.ReadAllText(testDataSql.Split)(新字符串[]{“GO\r\n”},StringSplitOptions.RemoveEmptyEntries);
      List commandList=新列表(拆分命令);
      返回命令列表;
      }
      
      [这实际上是从我现在正在开发的应用程序中复制出来的。我非常喜欢这段代码]

      然后,只需对列表执行
      ExecuteNonQuery()
      。获得花式体验并使用交易获得奖励积分

      ################ 如何处理事务位实际上取决于操作目标。基本上,您可以通过两种方式完成:

      a) 将整个执行过程封装在一个事务中,如果您真的希望所有事情要么执行,要么失败,这将是有意义的(更好的选项IMHO)


      b) 将对
      ExecuteNonQuery()
      的每个调用包装在其自己的事务中。实际上,每个调用都是它自己的事务。但是您可以捕获异常并继续下一项。当然,如果这是典型的生成DDL的东西,通常下一个部分取决于上一个部分,因此一个部分失败可能会给整个狗带来麻烦。

      我只是想在这里添加我的解决方案。。。将“GO”替换为ExecuteOnQuery理解的分隔符,即“;”操作人员使用此函数修复脚本:

      private static string FixGoDelimitedSqlScript(string script)
      {
          return script.Replace("\r\nGO\r\n", "\r\n;\r\n");
      }
      
      它可能不适用于带有“;”的复杂嵌套T-SQL运算符,但为我和我的脚本工作。我本来会使用上面列出的拆分方法,但我受到所用库的限制,所以我必须找到另一种解决方法。 希望这对别人有帮助


      注:我知道“;”运算符是语句分隔符,“GO”运算符是批处理分隔符,因此任何高级脚本都可能不会被此分隔符修复。

      我只想补充一点,如果您命名事务,您可以在in中包含多个GO部分,它们将作为一个单元回滚。例如:

      BEGIN TRANSACTION TransactionWithGos;
      GO
      
      SET XACT_ABORT ON; -- Roll back everything if error occurs in script
      GO
      
      -- do stuff
      GO
      
      COMMIT TRANSACTION TransactionWithGos;
      GO
      

      实际上,在使用Microsoft.SqlServer.Management.Smo扩展时,可以使用GO语句:

          var script = GetScript(databaseName);
          var conn = new SqlConnection(connectionString.ConnectionString);
          var svrConnection = new ServerConnection(conn);
          var server = new Server(svrConnection);
          server.ConnectionContext.ExecuteNonQuery(script);
      

      您只需要从以下位置部署SQL CLR类型和SQL管理对象包:
      (SQL 2012版)

      GO是SQL中的批处理分隔符。这意味着完成一整批。例如,一个批@ID中定义的变量不能在'GO'语句之后访问。请参考下面的代码以了解

      Declare @ID nvarchar(5);
      set @ID = 5;
      select @ID
      GO
      select @ID
      

      不要混淆事务和批处理-go语句指定了一批命令,其中可能包括一个或多个数据库事务。如果愿意,请向下投票,但您不会在一个事务中获得多个go。根据OP错误,脚本中存在需要GOs的创建。如果中途出了问题,唯一的方法就是这个方法。我不清楚为什么这个方法被否决了。这当然是一个很大的工作,但它似乎击中了这个想法,并允许回滚(与其他一些方法不同…)被否决的b/c它没有回答OP的问题——就像试图在应用程序中运行它一样。此外,让应用离线是如此丑陋。公平地说,KM的解决方案是100%准确和最安全的。我只使用适当的差异工具和适当的SQL客户机工具。对于第三方应用程序,我不记得曾经见过OP升级数据库的解决方案:它总是SQL脚本和批处理文件。@Wayatt Barnett说“而且,让应用程序离线太难看了。”,在数据库启动和运行时,用一个无法回滚的失败脚本弄乱数据库,“太难看了”如果脚本的某个部分出现错误,您将如何回滚更改?我计划使用单个事务访问所有语句来回滚整个过程。干杯例如,如果您有包含单词GO(后跟新行)等的注释,则上面可能会错误地拆分sql脚本,因此请小心使用。或者,您可以使用类似于以下的东西,这是一个StringReader实现,它将读取和拆分SQL,并且对注释等敏感:@