【问题标题】:How do I preview a destructive SQL query?如何预览破坏性 SQL 查询?
【发布时间】:2009-01-21 12:28:24
【问题描述】:

在 SQL Server Management Studio 中编写破坏性查询(例如,DELETE 或 UPDATE)时,我总是希望自己能够在不实际运行的情况下预览查询结果。 Access 非常方便地允许您执行此操作,但我更喜欢手动编写我的 SQL,遗憾的是,Access 非常不擅长。

所以我的问题是双重的:

  1. 是否有用于 SSMS 的插件,或配备了良好的 SQL 手动编码工具的单独工具,也可以预览破坏性查询的结果,类似于 Access?

    李>
  2. 是否有任何“手动”预览的技术或最佳实践?例如,以某种方式使用交易?

在我看来,做这种事情从根本上来说很重要,但我似乎无法通过谷歌找到任何东西(我可能只是在寻找错误的东西——我对这件事非常无知)。目前,我正在采取一种相当多毛的腰带和大括号方法来评论输入和输出选择/删除/更新行并确保我进行备份。肯定有更好的方法吧?

谁能帮忙?

【问题讨论】:

标签: sql sql-server


【解决方案1】:

我会使用 SQL SERVER 2008 及以后版本中的 OUTPUT 子句...

OUTPUT Clause (Transact-SQL)

类似...

BEGIN TRANSACTION

DELETE [table] OUTPUT deleted.* WHERE [woof] 

ROLLBACK TRANSACTION

INSERT 和 UPDATE 也可以使用“插入”表。 MSDN 文章涵盖了所有内容。

编辑:

这就像在事务中的 SELECT 然后 DELETE 的其他建议一样,除了它实际上是一起做的。因此,您打开一个事务,使用 OUTPUT 子句删除/插入/更新,并且在输出所做的操作的同时进行更改。然后你可以选择回滚或提交。

【讨论】:

  • 我更喜欢 Kevin 的解决方案,因为您可以在不更改数据的情况下看到结果。选择 100000 条记录比删除 100000 条记录,输出删除后的结果,然后回滚,数据库性能要好得多。
  • 但是你仍然容易犯错误。就像忘记突出显示 where 子句等一样。在此示例中,您将开始一个事务,进行更改(您完全打算提交)输出更改,然后在事务打开的情况下保持连接打开。查看完输出后,您可以 COMMIT 或 ROLLBACK。这更安全、更可靠,因为它消除了更多的人为错误。这确实意味着桌子被锁定了,所以你仍然需要小心。
  • 订单需要:DELETE [table] OUTPUT deleted.* WHERE [woof]
【解决方案2】:

我害怕有人对我的数据库这样做,所以我总是要求我的团队执行以下操作:

BEGIN TRAN
 
DELETE FROM X
-- SELECT * FROM X
FROM Table A as X JOIN Table B ON Blah blah blah
WHERE blah blah blah
 
ROLLBACK TRAN
COMMIT TRAN

这样,如果您不小心按了 F5(完成了!),您将不会进行任何更改。您可以通过 SQL 语句的末尾突出显示 SELECT 部分,以查看将更改哪些记录(以及更改的数量)。然后,突出显示 BEGIN TRAN 和整个 Delete 语句并运行它。如果您删除了与预期相同数量的记录,请突出显示 COMMIT TRAN 并运行它。如果有任何东西看起来很奇怪,请突出显示 ROLLBACK TRAN 并运行它。

我使用任何 UPDATE 或 DELETE 语句来执行此操作。它救了我几次,但它总能让我安心。

【讨论】:

  • 我会将 DELETE 和 SELECT 放在相反的位置以增加安全性。
  • 我按列出的顺序执行此操作的原因是我可以同时突出显示 BEGIN TRAN 和 DELETE 语句。如果 DELETE 被注释掉,我必须单独做,但这只是开发人员的偏好。感谢您的评论。
  • 这一切正常,直到有人忘记提交 - 你最终阻止了其他用户。这种情况我见过太多次了,所以在使用这个策略时要小心。
【解决方案3】:

删除时:

BEGIN TRANSACTION

   DELETE FROM table1 
   OUTPUT deleted.*
   WHERE property1 = 99 

ROLLBACK TRANSACTION

更新/插入时:

BEGIN TRANSACTION

   UPDATE table1
   SET table1.property1 = 99
   OUTPUT inserted.*

ROLLBACK TRANSACTION

【讨论】:

    【解决方案4】:

    当您处于事务的上下文中时,您可以在事务提交之前的任何时间回滚更改。 (通过显式调用 commit tran 或如果出现会导致服务器隐式提交事务的条件)

    create table x (id int, val varchar(10))
    
    insert into x values (1,'xxx')
    begin tran
    
    delete from x
    select * from x
    
    rollback tran
    select * from x
    

    【讨论】:

      【解决方案5】:

      当我想查看要删除的内容时,我只需将“delete”语句更改为“select *”即可。我喜欢这个比使用事务更好,因为我不必担心锁定。

      【讨论】:

      • 我总是尝试以任何方式将事物放入事务中。以防万一。就像突出显示除 where 子句之外的所有内容,按 f5 然后茫然地盯着空的咖啡杯......
      猜你喜欢
      • 2011-01-19
      • 2015-05-11
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多