30

我想知道是否可以在事务中运行多个 DDL 语句。我对 SQL Server 特别感兴趣,尽管其他数据库(至少是 Oracle、PostgreSQL)的答案也可能很有趣。

我一直在为事务中创建的表做一些“CREATE TABLE”和“CREATE VIEW”,似乎有些不一致,我想知道 DDL 是否不应该在事务中完成......

我可能会将 DDL 移到事务之外,但我想为此获得一些参考。到目前为止我发现了什么:

  • 数据库引擎中的MSDN 页面隔离级别清楚地表明,在快照隔离下运行的显式事务中可以执行哪些 DDL 操作存在限制- 但我没有使用快照隔离,这应该会导致错误。
    • 这可以解释为可以在不同隔离级别下的显式事务中执行 DDL 操作吗?
  • Oracle® Database Gateway for SQL Server 用户指南#DDL 语句指出在给定事务中只能执行一个 DDL 语句- 这对于直接使用的 SQL Server 是否也有效?

对于甲骨文:

如果这很重要,我将通过 JTDS JDBC 驱动程序使用 Java 执行此操作。

br Touko

4

4 回答 4

14

我知道大多数数据库都有限制,但 Postgres 没有。您可以在事务中运行任何数量的表创建、列更改和索引更改,并且这些更改对其他用户不可见,单位 COMMIT 成功。数据库应该是这样的!:-)

至于 SQL Server,您可以在事务内部运行 DDL,但SQL Server 不版本 metadata,因此在事务提交之前更改对其他人是可见的。但是如果你在一个事务中,一些 DDL 语句可以回滚,但是对于哪些有效,哪些无效,你需要运行一些测试。

于 2010-07-29T15:55:22.127 回答
4

如果您正在动态创建表、视图等(除了表变量或临时表),您可能真的需要重新考虑您的设计。这不是通常应该从用户界面发生的事情。即使您必须允许一些自定义,DDL 语句也不应该与运行事务性插入/更新/删除同时发生。最好将这些功能分开。

当两个用户尝试同时更改同一个表的结构然后运行事务以插入数据时会发生什么,这也需要进行适当的考虑和测试。当您允许用户调整您的数据库结构时,可能会发生一些真正可怕的事情。

此外,某些 DDL 语句必须始终是批处理的第一条语句。运行它们时也要注意这一点。

于 2009-06-25T14:18:28.083 回答
1

难道是在 MS SQL 中,运行 DDL 和 DML 语句时会触发隐式事务。如果您将其关闭是否有帮助,请使用 SET IMPLICIT_TRANSACTIONS

编辑:另一种可能性 - 您不能将 CREATE VIEW 与同一批次中的其他语句结合起来。创建表没问题。你用 GO 分开批次。

EDIT2:您可以在一个事务中使用多个 DDL,只要用 GO 分隔来创建不同的批次。

于 2009-06-25T12:34:02.770 回答
1

对于一般情况和 IIRC,假设 DDL 语句是事务性的是不安全的。

也就是说,模式更改如何在事务中交互(假设确实如此)有很大的余地。我相信这可以由供应商或什至由特定安装(即,由 dba 决定)决定。所以至少,不要使用一个 DBMS 来假设其他人会认为 DDL 语句。

编辑:MySql 是一个根本不支持 DDL 事务的 DBMS 示例。此外,如果您有数据库复制/镜像,您必须非常小心复制服务(Sybase 的复制是常态,信不信由你)实际上会复制 DDL 语句。

于 2009-06-25T14:06:04.707 回答