我正在尝试执行以下语句,该语句创建一个名为service2019的数据库:
DECLARE @dbname VARCHAR(50);
SET @dbname = 'service' + CAST(YEAR(GETDATE()) AS VARCHAR(4));
EXEC (
'CREATE DATABASE ' + @dbname + ' ON PRIMARY
( NAME =' + '' + @dbname +'' + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''' + '''' + @dbname + '''' + '''.mdf''' + ', SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 100KB )
LOG ON
( NAME =' + '' + @dbname + '_log' + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''' + '''' + @dbname + ''''+'''.ldf''' + ', SIZE = 10MB , MAXSIZE = 2048GB , FILEGROWTH = 100KB )'
)我得到正确的数据库名称和逻辑名称。问题是我弄错了物名:
“服役2019年”..mdf
‘service2019’.
有人能给我解释一下这些名言是如何起作用的吗?有些地方是明确的,但有时它成为一个挑战,以找出这些引号放在哪里。
发布于 2019-12-16 14:50:52
在开发动态SQL时,我建议您从大量使用PRINT命令开始工作,而不是使用EXEC,因为动态SQL可能(而且经常会)出错。打印出语句,而不是实际运行它,将有助于您避免一些问题,如果你有语法正确的代码,在逻辑上是错误的。
在本例中,我将添加一个新参数@DSQL VARCHAR(MAX),使用命令设置该变量,并打印出来,如下所示:
DECLARE @dbname VARCHAR(50), @DSQL VARCHAR(MAX);
SET @dbname = 'service' + CAST(YEAR(GETDATE()) AS VARCHAR(4));
SET @DSQL = 'CREATE DATABASE ' + @dbname + ' ON PRIMARY
( NAME =' + '' + @dbname +'' + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''' + '''' + @dbname + '''' + '''.mdf''' + ', SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 100KB )
LOG ON
( NAME =' + '' + @dbname + '_log' + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''' + '''' + @dbname + ''''+'''.ldf''' + ', SIZE = 10MB , MAXSIZE = 2048GB , FILEGROWTH = 100KB )'
PRINT @DSQL其产出如下:
CREATE DATABASE service2019 ON PRIMARY
( NAME =service2019, FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''service2019''.mdf', SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 100KB )
LOG ON
( NAME =service2019_log, FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\''service2019''.ldf', SIZE = 10MB , MAXSIZE = 2048GB , FILEGROWTH = 100KB )如您所见,您的mdf和ldf文件中有太多关于service2019的引号。经过进一步的调查,似乎您的字符串连接比必要的还要多。我建议您做的是将连接(即+)限制在变量和静态字符串之间的转换时间上。我也很喜欢格式化我的DSQL,所以我还包括一个传输返回/行源(即\r\n)和Tab (即\t)变量,这样您的输出看起来就更干净了。删除不必要的连接(包括格式设置)和清除引号将使我获得以下信息:
DECLARE @dbname VARCHAR(50), @DSQL VARCHAR(MAX), @CRLF CHAR(2), @TAB CHAR(1);
SET @dbname = 'service' + CAST(YEAR(GETDATE()) AS VARCHAR(4));
SET @CRLF = CHAR(13) + CHAR(10)
SET @TAB = CHAR(9)
SET @DSQL = 'CREATE DATABASE ' + @dbname + ' ON PRIMARY
( NAME = ' + @dbname + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\' + @dbname + '.mdf'' , SIZE = 10MB , MAXSIZE = UNLIMITED, FILEGROWTH = 100KB )'
+ @CRLF + @TAB + 'LOG ON'
+ @CRLF + '( NAME = ' + @dbname + '_log' + ', FILENAME = ''C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014TEST\MSSQL\DATA\' + @dbname + '.ldf'' , SIZE = 10MB , MAXSIZE = 2048GB , FILEGROWTH = 100KB )'
PRINT @DSQL
--EXEC(@DSQL) /* <--- Uncomment out if you want to run this */关于更多的格式化建议、DSQL带来的陷阱的讨论以及几乎任何其他问题,我将向您指出(我认为DSQL的实际指南是什么) Erland Sommarskog动态SQL的诅咒与祝福。
https://dba.stackexchange.com/questions/255707
复制相似问题