Sql-Server
在哪裡放單引號?
我正在嘗試執行以下語句,該語句創建一個名為 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 )' )
我得到正確的數據庫名稱和邏輯名稱。問題是我得到了錯誤的物理名稱:
‘service2019’.mdf
‘service2019’.ldf
有人可以向我解釋這些報價實際上是如何工作的嗎?有些部分很清楚,但有時很難弄清楚將這些引用放在哪裡。
在開發動態 SQL 時,我建議您從大量使用
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 )
service2019
如您所見,您的 mdf 和 ldf 文件路徑中有太多引號。經過進一步調查,您的字元串連接似乎也比必要的多。我建議你做的是將連接(即+
)限制在變數和靜態字元串之間轉換的時間。我也是格式化我的 DSQL 的粉絲,所以我還包括一個輸入/換行 (ie\r\n
) 和 Tab (ie\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 的詛咒和祝福。