• <bdo id='QrdoA'></bdo><ul id='QrdoA'></ul>
    1. <tfoot id='QrdoA'></tfoot>
      <i id='QrdoA'><tr id='QrdoA'><dt id='QrdoA'><q id='QrdoA'><span id='QrdoA'><b id='QrdoA'><form id='QrdoA'><ins id='QrdoA'></ins><ul id='QrdoA'></ul><sub id='QrdoA'></sub></form><legend id='QrdoA'></legend><bdo id='QrdoA'><pre id='QrdoA'><center id='QrdoA'></center></pre></bdo></b><th id='QrdoA'></th></span></q></dt></tr></i><div id='QrdoA'><tfoot id='QrdoA'></tfoot><dl id='QrdoA'><fieldset id='QrdoA'></fieldset></dl></div>

      <legend id='QrdoA'><style id='QrdoA'><dir id='QrdoA'><q id='QrdoA'></q></dir></style></legend>

      <small id='QrdoA'></small><noframes id='QrdoA'>

      1. 将列添加到表中,然后在事务中更新它

        Add column to table and then update it inside transaction(将列添加到表中,然后在事务中更新它)

          <small id='jOgp0'></small><noframes id='jOgp0'>

              • <bdo id='jOgp0'></bdo><ul id='jOgp0'></ul>
                  <tbody id='jOgp0'></tbody>
                <tfoot id='jOgp0'></tfoot>
              • <i id='jOgp0'><tr id='jOgp0'><dt id='jOgp0'><q id='jOgp0'><span id='jOgp0'><b id='jOgp0'><form id='jOgp0'><ins id='jOgp0'></ins><ul id='jOgp0'></ul><sub id='jOgp0'></sub></form><legend id='jOgp0'></legend><bdo id='jOgp0'><pre id='jOgp0'><center id='jOgp0'></center></pre></bdo></b><th id='jOgp0'></th></span></q></dt></tr></i><div id='jOgp0'><tfoot id='jOgp0'></tfoot><dl id='jOgp0'><fieldset id='jOgp0'></fieldset></dl></div>
                <legend id='jOgp0'><style id='jOgp0'><dir id='jOgp0'><q id='jOgp0'></q></dir></style></legend>

                1. 本文介绍了将列添加到表中,然后在事务中更新它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在创建一个将在 MS SQL 服务器中运行的脚本.此脚本将运行多个语句并且需要是事务性的,如果其中一个语句失败,则停止整体执行并回滚任何更改.

                  I am creating a script that will be run in a MS SQL server. This script will run multiple statements and needs to be transactional, if one of the statement fails the overall execution is stopped and any changes are rolled back.

                  在发出 ALTER TABLE 语句以将列添加到表然后更新新添加的列时,我无法创建此事务模型.为了立即访问新添加的列,我使用 GO 命令执行 ALTER TABLE 语句,然后调用我的 UPDATE 语句.我面临的问题是我无法在 IF 语句中发出 GO 命令.IF 语句在我的事务模型中很重要.这是我尝试运行的脚本的示例代码.还要注意,发出GO命令,会丢弃@errorCode变量,使用前需要在代码中声明down(这不在下面的代码中).

                  I am having trouble creating this transactional model when issuing ALTER TABLE statements to add columns to a table and then updating the newly added column. In order to access the newly added column right away, I use a GO command to execute the ALTER TABLE statement, and then call my UPDATE statement. The problem I am facing is that I cannot issue a GO command inside an IF statement. The IF statement is important within my transactional model. This is a sample code of the script I am trying to run. Also notice that issuing a GO command, will discard the @errorCode variable, and will need to be declared down in the code before being used (This is not in the code below).

                  BEGIN TRANSACTION
                  
                  DECLARE @errorCode INT
                  SET @errorCode = @@ERROR
                  
                  -- **********************************
                  -- * Settings
                  -- **********************************
                  IF @errorCode = 0
                  BEGIN
                   BEGIN TRY
                    ALTER TABLE Color ADD [CodeID] [uniqueidentifier] NOT NULL DEFAULT ('{00000000-0000-0000-0000-000000000000}')
                    GO
                   END TRY
                   BEGIN CATCH
                    SET @errorCode = @@ERROR
                   END CATCH
                  END
                  
                  IF @errorCode = 0
                  BEGIN
                   BEGIN TRY
                    UPDATE Color
                    SET CodeID= 'B6D266DC-B305-4153-A7AB-9109962255FC'
                    WHERE [Name] = 'Red'
                   END TRY
                   BEGIN CATCH
                    SET @errorCode = @@ERROR
                   END CATCH
                  END
                  
                  -- **********************************
                  -- * Check @errorCode to issue a COMMIT or a ROLLBACK
                  -- **********************************
                  IF @errorCode = 0
                  BEGIN
                   COMMIT
                   PRINT 'Success'
                  END
                  ELSE 
                  BEGIN
                   ROLLBACK
                   PRINT 'Failure'
                  END
                  

                  所以我想知道如何解决这个问题,发出 ALTER TABLE 语句来添加一列,然后更新该列,所有这些都在作为事务单元执行的脚本中进行.

                  So what I would like to know is how to go around this problem, issuing ALTER TABLE statements to add a column and then updating that column, all within a script executing as a transactional unit.

                  推荐答案

                  GO 不是 T-SQL 命令.是批处理分隔符.客户端工具(SSM、sqlcmd、osql 等)使用它在每个 GO 处有效地剪切文件并将各个批次发送到服务器.所以很明显你不能在 IF 中使用 GO,你也不能期望变量跨越批次的范围.

                  GO is not a T-SQL command. Is a batch delimiter. The client tool (SSM, sqlcmd, osql etc) uses it to effectively cut the file at each GO and send to the server the individual batches. So obviously you cannot use GO inside IF, nor can you expect variables to span scope across batches.

                  此外,如果不检查 XACT_STATE() 就无法捕获异常 以确保交易不会失败.

                  Also, you cannot catch exceptions without checking for the XACT_STATE() to ensure the transaction is not doomed.

                  使用 GUID 作为 ID 总是至少是可疑的.

                  Using GUIDs for IDs is always at least suspicious.

                  使用 NOT NULL 约束并提供像 '{00000000-0000-0000-0000-0000000000000}' 这样的默认guid"也不正确.

                  Using NOT NULL constraints and providing a default 'guid' like '{00000000-0000-0000-0000-000000000000}' also cannot be correct.

                  更新:

                  • 将 ALTER 和 UPDATE 分成两批.
                  • 使用 sqlcmd 扩展在出错时中断脚本.当 sqlcmd 模式打开时的 SSMS、sqlcmd 支持此功能,并且在客户端库中支持它也很简单:dbutilsqlcmd.
                  • 使用 XACT_ABORT 强制错误中断批处理.这经常用于维护脚本(架构更改).存储过程和应用程序逻辑脚本通常使用 TRY-CATCH 块,但要适当小心:异常处理和嵌套事务.
                  • Separate the ALTER and UPDATE into two batches.
                  • Use sqlcmd extensions to break the script on error. This is supported by SSMS when sqlcmd mode is on, sqlcmd, and is trivial to support it in client libraries too: dbutilsqlcmd.
                  • use XACT_ABORT to force error to interrupt the batch. This is frequently used in maintenance scripts (schema changes). Stored procedures and application logic scripts in general use TRY-CATCH blocks instead, but with proper care: Exception handling and nested transactions.

                  示例脚本:

                  :on error exit
                  
                  set xact_abort on;
                  go
                  
                  begin transaction;
                  go
                  
                  if columnproperty(object_id('Code'), 'ColorId', 'AllowsNull') is null
                  begin
                      alter table Code add ColorId uniqueidentifier null;
                  end
                  go
                  
                  update Code 
                    set ColorId = '...'
                    where ...
                  go
                  
                  commit;
                  go
                  

                  只有成功的脚本才能到达COMMIT.任何错误都会中止脚本并回滚.

                  Only a successful script will reach the COMMIT. Any error will abort the script and rollback.

                  我使用 COLUMNPROPERTY 来检查对于列存在,您可以使用任何您喜欢的方法(例如查找 sys.columns).

                  这篇关于将列添加到表中,然后在事务中更新它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How to delete duplicate records in mysql database?(如何删除mysql数据库中的重复记录?)
                  Python Pandas write to sql with NaN values(Python Pandas 使用 NaN 值写入 sql)
                  MySQL Insert amp; Joins(MySQL 插入 amp;加入)
                  MySQL concat() to create column names to be used in a query?(MySQL concat() 创建要在查询中使用的列名?)
                  NodeJS responded MySQL timezone is different when I fetch directly from MySQL(当我直接从 MySQL 获取时,NodeJS 响应 MySQL 时区不同)
                  WHERE datetime older than some time (eg. 15 minutes)(WHERE 日期时间早于某个时间(例如 15 分钟))
                    <bdo id='UbtzR'></bdo><ul id='UbtzR'></ul>

                        <i id='UbtzR'><tr id='UbtzR'><dt id='UbtzR'><q id='UbtzR'><span id='UbtzR'><b id='UbtzR'><form id='UbtzR'><ins id='UbtzR'></ins><ul id='UbtzR'></ul><sub id='UbtzR'></sub></form><legend id='UbtzR'></legend><bdo id='UbtzR'><pre id='UbtzR'><center id='UbtzR'></center></pre></bdo></b><th id='UbtzR'></th></span></q></dt></tr></i><div id='UbtzR'><tfoot id='UbtzR'></tfoot><dl id='UbtzR'><fieldset id='UbtzR'></fieldset></dl></div>

                        <small id='UbtzR'></small><noframes id='UbtzR'>

                          <tbody id='UbtzR'></tbody>
                        <tfoot id='UbtzR'></tfoot>
                        <legend id='UbtzR'><style id='UbtzR'><dir id='UbtzR'><q id='UbtzR'></q></dir></style></legend>