Sql-Server

在哪裡放單引號?

  • December 16, 2019

我正在嘗試執行以下語句,該語句創建一個名為 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 時,我建議您從大量使用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 )

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 的詛咒和祝福

引用自:https://dba.stackexchange.com/questions/255707