Sql server 创建数据库脚本中的变量声明
我有一个大型数据库创建查询,其开头如下:Sql server 创建数据库脚本中的变量声明,sql-server,variables,sqlcmd,Sql Server,Variables,Sqlcmd,我有一个大型数据库创建查询,其开头如下: USE Master GO IF EXISTS(SELECT * FROM sys.sysdatabases where name = 'MyDatabase') DROP DATABASE MyDatabase GO CREATE DATABASE MyDatabase GO USE MyDatabase GO 我想在开头声明一个变量,如下所示: DECLARE @MainDB VARCHAR(30) = NULL USE Master G
USE Master
GO
IF EXISTS(SELECT * FROM sys.sysdatabases where name = 'MyDatabase')
DROP DATABASE MyDatabase
GO
CREATE DATABASE MyDatabase
GO
USE MyDatabase
GO
我想在开头声明一个变量,如下所示:
DECLARE @MainDB VARCHAR(30) = NULL
USE Master
GO
IF EXISTS(SELECT * FROM sys.sysdatabases where name = @MainDB)
DROP DATABASE @MainDB
GO
CREATE DATABASE @MainDB
GO
USE @MainDB
GO
我将从命令行执行此查询,并使用sqlcmd工具指定新的数据库名称。但是sql告诉我没有声明变量@MainDB。这是我能做的吗?如果不是,你会建议我如何解决这个问题?这个问题有点重复
简而言之,您不能有一个可变的数据库名称。您必须将T-SQL放入字符串/VARCHAR(MAX)中,进行查找和替换,然后执行它。抱歉,但您不能这样做,因为SQL变量只有“batch”范围,而那些“GO”命令指示批的边界。因此,每次通过GO时,所有变量都会被删除(甚至不再声明它们) 有几种方法可以解决这个问题:
哎呀,我错过了其中的“变量数据库名称”部分。这也可以做到,但您必须将动态SQL添加到组合中。您有多个问题。。。
GO
结束当前批次。因此,您的变量不再可见。你需要移动申报单。此外,您不能删除DATABASE@MainDB
,必须使用动态查询。比如说,
GO
DECLARE @MainDB VARCHAR(30) = 'MyDB';
IF EXISTS(SELECT * FROM sys.sysdatabases where name = @MainDB)
BEGIN
EXECUTE ('DROP DATABASE '+@MainDB);
END;
您说您需要从命令行运行它,因此如果您有大量代码,这取决于您已经构建的结构,那么您可以执行以下操作:
set obj = CreateObject("Scriptlet.TypeLib")
tempsqlfile = obj.GUID & ".sql" 'get a new name for your sql file
set fso = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile(tempsqlfile, ForReading) 'open the template file
strSQLText = objFile.ReadAll
objFile.Close
strNewSQLText = Replace(strSQLText, "@MainDB", Wscript.Arguments(1)) 'replace the db name
Set objFile = objFSO.OpenTextFile(tempsqlfile, ForWriting)
objFile.WriteLine strNewText 'write the new file
objFile.Close
Set Shell = WScript.CreateObject("WScript.Shell")
commandLine = "osql -E -i " & Wscript.Arguments(0) & -o " & tempsqlfile & ".rpt"
Set oExec = Shell.Exec(commandLine)
为变量名道歉-我从不同的地方剪切和粘贴了一些片段,但你应该了解要点
(另外-对于从所有这些选项中选择VBScript表示歉意,请注意,检查缺少的参数时没有错误)
如上所述,如果将该脚本另存为“runmystuff.vbs”,则可以执行以下操作:
runmystuff.vbs sqlfile.sql MagicNewDB
这将在脚本中的任何地方用MagicNewDB替换@MainDB,然后使用osql运行它。找到了一种使cmdline变量等于t-sql变量的方法
USE master
GO
DECLARE @Mydb VARCHAR(30) = "$(mydb)"
IF EXISTS(SELECT * FROM sys.sysdatabases where name = @Mydb)
print @Mydb
Execute('create database ' + @Mydb)
我从中运行的批处理文件如下所示
sqlcmd -S %1 -i CreateDatabases.sql -v mydb="%2"
我现在可以从sqlcmd运行并输入%1的服务器和%2所需的DB名称
感谢所有人的回复,他们都帮助我找到了正确的解决方案。另请参见,变量范围仅限于单个查询批处理(两个GO语句之间的所有内容)。仅供参考:LastCoder答案中的链接显示了如何执行上面的#1,这也适用于动态SQL要求。