如何使用正确的对象顺序编写 MS SQL Server 数据库脚本?

Posted

技术标签:

【中文标题】如何使用正确的对象顺序编写 MS SQL Server 数据库脚本?【英文标题】:How can I script an MS SQL Server database with proper object ordering? 【发布时间】:2010-10-13 19:05:02 【问题描述】:

我正在尝试将 MS SQL Server 2005 数据库编写到单个文件中。到目前为止,我已经尝试过使用 SQL Management Studio 和 MS 数据库发布向导。

这两个工具都可以毫无问题地为数据库对象编写脚本,尽管这两个工具都没有按照正确的创建顺序编写对象脚本。例如,该脚本可能会编写一个视图,该视图需要一个表,该表要到稍后才会创建。

您知道如何使用正确的对象创建顺序编写数据库架构脚本吗?

【问题讨论】:

【参考方案1】:

我们使用它来创建数据库脚本,我必须再次运行它以确保它首先创建对象依赖项......但我还没有遇到问题。 http://www.red-gate.com/products/SQL_Compare/index.htm

【讨论】:

感谢您的提示。我试用了试用版,看起来文件是按字母顺序生成的。如果在创建所有表之后建立外键约束,这实际上会很好,但事实并非如此。【参考方案2】:

我的回答会有点复杂,而且它只有在您编写整个数据库的脚本时才有效(即将所有内容都保存在 SQL 脚本中)。我们在一个大型项目中所做的是将脚本组织成以下结构:

_ddl:保存表的变化,例如新的列、索引、关系等。 _fn:存储函数 _prc:存储过程 _static:显然是“静态数据”,或者部署时必须在数据库中的数据 _tab:表格(创建脚本) _trg:触发器 _views:查看脚本

文件夹名称当然是我们随机选择的,您总是可以以不同的方式排列。之后,我们创建了一个批处理脚本,按以下顺序将所有这些文件合并到一个 SQL 中:

_tab _ddl _trg _views _fn _prc _静态

关键技巧是以可以运行一千次的方式编写脚本。这意味着:在创建过程之前删除它们,在创建表之前检查表是否存在,在静态添加之前检查行是否存在,等等。

它并不完美,但它可以完成工作。

【讨论】:

如果一个视图引用另一个视图,视图仍然必须按正确的顺序排列。 对于外键约束,表的顺序也需要正确。 哇,我敢打赌,加上一些蚕豆和漂亮的基安蒂,一切都会变得更好!【参考方案3】:

莱克特有一个很好的方法。您可以使用 powershell 脚本(或其他语言)连接这些脚本

运行脚本:

PS builddir:\> .\buildsql.ps1 -currentbuilddir "C:\Documents and Settings\sam\My Documents\svn\ticketing" -buildfile "sqlbuild.sql" -teardownfile
"teardown.sql"

powershell 脚本:

param($currentbuilddir,$buildfile1,$teardownfile)

new-psdrive -name builddir -PSProvider filesystem -Root (resolve-path $currentbuilddir)

cd builddir:

rm $buildfile1
rm $teardownfile


Get-item Scripts_Build_1* | ForEAch-object cat $_ >> $buildfile1; "GO --SYSTEM INSERTED GO--------------" >> $buildfile1 

Get-item Scripts_Build_3* | ForEAch-object cat $_ >> $teardownfile; "GO --SYSTEM INSERTED GO------------" >> $teardownfile 

在这里,我正在删除构建文件并拆除文件 - 我实际上正在将 sql 本机加密应用于数据库,因此拆除可能不适用。我将所有脚本都放在一个目录中,因此我认为您可能需要更改此脚本以进行递归。

【讨论】:

【参考方案4】:

您可以在http://www.xsqlsoftware.com/Product/Sql_Schema_Compare.aspx 尝试 xSQL 对象 它对我很有用。尽可能以正确的顺序创建脚本(在某些情况下生成的脚本无法直接执行,但在大多数情况下它可以工作)

【讨论】:

【参考方案5】:

有一种简单但非常有效的方法可以解决排序问题:继续运行每个脚本。单个脚本最终会工作(在首先运行其他脚本之后)或失败 > # of scripts(在这种情况下,它是一个坏脚本)。您可能能够更快/更轻松地检测到错误的脚本 - 但我从来不需要这样做。

如果您有 1 个巨型脚本,它可能会被 GO 语句分割。只要有唯一的 GO 语句,运行它就足够了。任何创建已存在对象的尝试都将失败,并中止批处理。下一批将不间断地运行。最终,您创建了必要的对象 - 重新运行整个脚本将创建依赖对象(并在已经创建的独立对象上失败)。但是,您永远不会让脚本在没有错误的情况下运行。

如果你想更高级一点,你可以把这个巨大的脚本分成单独的批次,单独运行。现在,您可以跟踪使它们工作所需的顺序。只需按该顺序重新组合它们,然后输出新脚本。它应该可以正常运行。

或者,花 500 美元购买已经具备此功能的工具(RedGate、Visual Studio Ultimate/Database Edition 等)。

【讨论】:

以上是关于如何使用正确的对象顺序编写 MS SQL Server 数据库脚本?的主要内容,如果未能解决你的问题,请参考以下文章

PCB MS SQL CLR聚合函数(函数作用,调用顺序,调用次数) CLR说明

Laravel 8 - MS SQL - 查询生成器 - 使用 DB Raw。尝试使代码正确,使其像工作的 MSSQL 代码一样工作

MS sql如何使用存储过程?

如何使 MS Access 直通查询在 SQL Server 中正确运行

带有管理工作室的 MS SQL Server - 如何使用其数据(作为插入语句)编写表的脚本? [复制]

使用 Spring Boot 应用程序正确设置 MS SQL Server?