我现在正在使用sqlcmd
一段时间来更新我们项目的数据库。
在我们使用这样的脚本之前:
:setvar relativepath D:\Project1\Sql
:r $(relativepath)\Tables\CreateTable1.sql
:r $(relativepath)\SP\Table1.sql
Run Code Online (Sandbox Code Playgroud)
这是在开发和发布期间更新数据库的好方法。
但是现在我们使用不同的目录,这取决于我们是在开发分支还是生产分支(Subversion)。
我们希望避免错误,以防有人通过根据所选数据库名称设置路径将脚本提交到错误的目录。像这样的事情:
:setvar relativepath "D:\Project1\Prod\Sql"
if (DB_name() = 'Project1' OR DB_name() = 'Project1_Dev')
begin
:setvar relativepath "D:\Project1\Dev\Sql"
end
Run Code Online (Sandbox Code Playgroud)
我找不到办法做到这一点。有人有想法吗?
[更新] 解决方案:(坦克到 wBob)
我有一个名为的脚本: setRelativePath.sql
:out D:\Project1\SQL\Temp\temp.sql
go
declare @bdName varchar(15) = DB_name()
--Here the print got saved to D:\Project1\SQL\Temp\temp.sql
if @bdName = 'Project1' OR @bdName = 'Project1_DEV'
print ':setvar relativepath D:\Project1\DEV\Sql'
else if @bdName = 'Project1_PROD'
print ':setvar relativepath D:\Project1\PROD\Sql'
else
raiserror( 'Unknown value (%s) for sqlcmd variable relativepath.', 16, 1, @bdName )
go
:out stdout
go
!!REM Read the file to execute the setvar statement
:r D:\Project1\SQL\Temp\temp.sql
go
--Here the print is displayed then we execute the script
print 'Relative path set to $(relativepath)'
go
Run Code Online (Sandbox Code Playgroud)
然后我在我的脚本文件中使用它:
:r D:\Project1\SQL\setRelativePath.sql
:r $(relativepath)\SP\SomeStoredProcedure.sql
Run Code Online (Sandbox Code Playgroud)
D:\Project1\SQL\
在后备箱里。
的relativepath
varriable可使用的内SomeStoredProcedure.sql
给。
此脚本确保我们不会将开发脚本应用于生产并在我们将开发合并到生产时删除步骤。
您不能将sqlcmd
模式命令与 T-SQL 条件逻辑混合使用。有一种方法可以做到这一点,但至于是否可取是另一回事。
此技术涉及重定向stdout
、写出文件并在sqlcmd
模式下执行该文件以获得您需要的效果:
:out d:\temp\temp.sql
go
declare @x varchar(5) = 'dev'
if @x = 'dev'
print ':setvar testVar dev'
else if @x = 'prod'
print ':setvar testVar prod'
else raiserror( 'Unknown value (%s) for sqlcmd variable testVar.', 16, 1, @x )
go
:out stdout
go
!!REM Read the file to execute the setvar statement
:r d:\temp\temp.sql
go
select '$(testVar)' env
print 'it looks like this is the $(testvar) environment after all'
go
Run Code Online (Sandbox Code Playgroud)
显然,运行此方法的进程将需要访问临时目录和文件,并且此方法存在相关权限(和风险)。重定向输出时,GO 的位置很重要。
至于用法,我不会特别建议。我们对此进行了试验(因此我知道这种技术),但远离它,转而支持数据库项目(为您处理所有这些)或可重新运行的(幂等)脚本。不是在父脚本中加载条件逻辑,而是将每个对象脚本构建为可使用“如果不存在”检查重新运行,例如:
if not exists ( the table )
create the table
if not exists ( a column )
add the column
Run Code Online (Sandbox Code Playgroud)
那么我们是在 dev 还是 prod 中运行,或者我们运行脚本多少次都无关紧要。一段时间后,这些可能会变得有点笨拙。
归档时间: |
|
查看次数: |
4291 次 |
最近记录: |