提问人:Erick Sasse 提问时间:4/8/2009 最后编辑:Peter MortensenErick Sasse 更新时间:12/15/2016 访问量:243948
如何在 T-SQL 中使用变量作为数据库名称?
How to use a variable for the database name in T-SQL?
问:
我在脚本中的多个位置使用了数据库名称,并且我希望能够快速更改它,因此我正在寻找类似以下内容的内容:
DECLARE @DBNAME VARCHAR(50)
SET @DBNAME = 'TEST'
CREATE DATABASE @DBNAME
GO
ALTER DATABASE @DBNAME SET COMPATIBILITY_LEVEL = 90
GO
ALTER DATABASE @DBNAME SET RECOVERY SIMPLE
GO
但它不起作用。那么编写这段代码的正确方法是什么呢?
答:
5赞
Andrew Hare
4/8/2009
#1
不能在 create table 语句中使用变量。我能建议的最好的事情是将整个查询编写为字符串并执行它。
尝试这样的事情:
declare @query varchar(max);
set @query = 'create database TEST...';
exec (@query);
13赞
Dillie-O
4/8/2009
#2
遗憾的是,您不能使用该格式的变量声明数据库名称。
对于您要完成的任务,您需要将语句包装在 EXEC() 语句中。所以你会有类似的东西:
DECLARE @Sql varchar(max) ='CREATE DATABASE ' + @DBNAME
然后调用
EXECUTE(@Sql) or sp_executesql(@Sql)
执行 SQL 字符串。
评论
0赞
Bob Blogge
7/19/2013
EXEC
查找存储过程。在这种情况下,是需要的。EXECUTE
2赞
Bob Blogge
7/19/2013
其实我需要道歉。事实证明,这是一样的。我是在失败和成功后发表的声明。虽然显然我真正的问题与两者都无关。EXEC
EXECUTE
EXEC
EXECUTE
2赞
Magic Octopus Urn
9/16/2017
不要在生产中这样做......曾。
0赞
Harsh Shankar
11/9/2018
@MagicOctopusUrn改变旧帖子和非常评论,但我很好奇,知道为什么不呢?它不应该是特定于需求的吗??
0赞
Isaac Reefman
5/23/2019
@MagicOctopusUrn 那是因为注射的潜力吗?
146赞
John Saunders
4/8/2009
#3
将整个脚本放入模板字符串中,并带有 {SERVERNAME} 占位符。然后使用以下命令编辑字符串:
SET @SQL_SCRIPT = REPLACE(@TEMPLATE, '{SERVERNAME}', @DBNAME)
然后用
EXECUTE (@SQL_SCRIPT)
很难相信,在三年的时间里,没有人注意到我的代码不起作用!
不能进行多个批次。 是批处理分隔符,而不是 T-SQL 语句。有必要构建三个单独的字符串,然后在替换后构建每个字符串。EXEC
GO
EXEC
我想人们可以做一些“聪明”的事情,通过将单个模板字符串拆分为多行来拆分;我已经在 ADO.NET 代码中做到了这一点。GO
我从哪里得到“SERVERNAME”这个词?
以下是我刚刚测试的一些代码(并且有效):
DECLARE @DBNAME VARCHAR(255)
SET @DBNAME = 'TestDB'
DECLARE @CREATE_TEMPLATE VARCHAR(MAX)
DECLARE @COMPAT_TEMPLATE VARCHAR(MAX)
DECLARE @RECOVERY_TEMPLATE VARCHAR(MAX)
SET @CREATE_TEMPLATE = 'CREATE DATABASE {DBNAME}'
SET @COMPAT_TEMPLATE='ALTER DATABASE {DBNAME} SET COMPATIBILITY_LEVEL = 90'
SET @RECOVERY_TEMPLATE='ALTER DATABASE {DBNAME} SET RECOVERY SIMPLE'
DECLARE @SQL_SCRIPT VARCHAR(MAX)
SET @SQL_SCRIPT = REPLACE(@CREATE_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(@COMPAT_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(@RECOVERY_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
评论
2赞
reSPAWNed
9/15/2011
+1 非常好的方法...你刚刚把我从大量的工作中解救出来,谢谢......虽然它应该是 EXECUTE(@SQL_SCRIPT),或者至少这对我有用。
2赞
usr
5/29/2013
不过,逃跑时需要小心。
4赞
Martin Smith
11/14/2013
SYSNAME
将是一个更合适的数据类型,而不是应该用于处理所有可能的数据库名称(并且可能根据名称的来源来防止 SQL 注入)VARCHAR(255)
QUOTENAME
1赞
Bomberlt
6/26/2015
如果我想在其他数据库中使用,则不起作用。架构在错误的数据库中创建;/CREATE SCHEMA
USE {DBNAME}
110赞
Martin Smith
2/11/2012
#4
还可以为此使用 sqlcmd
模式(在 Management Studio 的“查询”菜单上启用此功能)。
:setvar dbname "TEST"
CREATE DATABASE $(dbname)
GO
ALTER DATABASE $(dbname) SET COMPATIBILITY_LEVEL = 90
GO
ALTER DATABASE $(dbname) SET RECOVERY SIMPLE
GO
编辑:
查看此 MSDN 文章,了解如何通过 SQLCMD 工具设置参数。
评论
1赞
syclee
4/14/2015
此方法如何使用已声明的变量?您可以添加@dbName而不是“TEST”吗?我试过了,但没有成功
2赞
Martin Smith
4/14/2015
@syclee TSQL 变量?否,sqlcmd 替换是在将脚本发送到服务器之前执行的。
0赞
Kunal Kakkad
12/29/2015
@MartinSmith 嘿,我想要数据库名称作为 OUTPUT 命令。那么我如何使用SQLCMD来拥有它呢?
评论