Rau*_*DBA 0 sql-server dynamic-sql t-sql sql-server-2014 quoted-identifier
我正在尝试执行以下语句,该语句创建一个名为 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 )'
)
Run Code Online (Sandbox Code Playgroud)
我得到了正确的数据库名称和逻辑名称。问题是我得到了错误的物理名称:
'service2019'.mdf
'service2019'.ldf
有人可以向我解释这些报价实际上是如何工作的吗?有一些部分很清楚,但有时找出这些引号的位置是一个挑战。
在开发动态 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
Run Code Online (Sandbox Code Playgroud)
输出以下内容:
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 )
Run Code Online (Sandbox Code Playgroud)
如您所见,您service2019
的 mdf 和 ldf 文件路径中有太多引号。经过进一步调查,看起来您的字符串连接数量也多于必要。我建议您做的是将连接(即+
)限制在您在变量和静态字符串之间转换的时间。我也是格式化我的 DSQL 的粉丝,所以我还包括一个回车/换行(即\r\n
)和制表符(即\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 */
Run Code Online (Sandbox Code Playgroud)
有关更多格式化建议、DSQL 附带陷阱的讨论以及几乎任何其他内容,我将向您指出(我认为 DSQL 的事实上的指南)Erland Sommarskog 撰写的 The Curse and Blessings of Dynamic SQL。
归档时间: |
|
查看次数: |
68 次 |
最近记录: |