共用方式為


使用 sqlcmd 搭配腳本變數

適用於:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics分析平台系統(PDW)Microsoft Fabric 中的 SQL 資料庫

sqlcmd 公用程式可讓您輸入 Transact-SQL 語句、系統程式和腳本檔案。

Note

若要找出系統上已安裝哪些 sqlcmd 變體和版本,請參閱 檢查已安裝的 sqlcmd 公用程式版本。 如需如何取得 sqlcmd 的資訊,請參閱 下載並安裝 sqlcmd 公用程式

在 sqlcmd 中編寫變數腳本

用於指令碼中的變數稱為指令碼變數。 指令碼變數可讓一個指令碼使用於多個狀況中。 例如,如果您想要針對多個伺服器執行一個指令碼,而不針對每個伺服器修改指令碼,您可以使用指令碼變數來代表伺服器名稱。 只要變更提供給指令碼變數的伺服器名稱,相同的指令碼就可以在不同的伺服器上執行。

您可以使用 setvar 命令 明確定義腳本變數,或使用 sqlcmd -v 選項 以隱含方式定義。

本文也包含使用 SET在命令行定義環境變數的範例。

使用 setvar 命令設定指令碼變數

命令 setvar 會定義腳本變數。 使用 setvar 命令定義的變數會儲存在內部。 指令碼變數不應與在命令提示字元中使用 SET 所定義的環境變數產生混淆。 如果腳本參考不是環境變數或未使用 setvar定義的變數,則會傳回錯誤訊息,並停止執行腳本。 如需詳細資訊,請參閱 -b 中的 選項。

變數優先順序 (由低至高)

如果有多個類型的變數具有相同的名稱,會使用具有最高優先順序的變數。

  1. 系統層級環境變數
  2. 使用者層級環境變數
  3. 命令殼層 (SET X=Y) 在啟動 sqlcmd 之前於命令提示字元設定
  4. sqlcmd -v X=Y
  5. :Setvar X Y

Note

若要檢視 Windows 11 上的環境變數,請開啟 [ 設定],然後流覽至 [系統>關於],然後選取 [ 進階系統設定 ] 連結。 在 [系統屬性] 視窗中,選取 [ 環境變數]。 在 Linux 上,在命令列輸入 printenv ,然後在 macOS 中輸入 env

隱式設定指令碼變數

當您透過含有 sqlcmd 相關變數的選項啟動 sqlcmd 時,會將 sqlcmd 變數隱含設定為使用該選項所指定的值。 在下列範例中, sqlcmd 透過 -l 選項啟動。 這將會隱含地設定 SQLLOGINTIMEOUT 變數。

sqlcmd -l 60

您也可以使用 -v 選項來設定存在於指令碼中的指令碼變數。 在下列指令碼 (檔名為 testscript.sql) 中, ColumnName 為指令碼變數。

USE AdventureWorks2022;

SELECT x.$(ColumnName)
FROM Person.Person x
WHERE x.BusinessEntityID < 5;

您可以接著指定要使用 -v 選項傳回的資料行名稱:

sqlcmd -v ColumnName ="FirstName" -i c:\testscript.sql

若要使用相同的指令碼傳回不同的資料行,請變更 ColumnName 指令碼變數的值。

sqlcmd -v ColumnName ="LastName" -i c:\testscript.sql

腳本變數名稱和值的指南

當您為指令碼變數命名時,請考慮下列指導方針:

  • 變數名稱不能包含空白字元或引號。

  • 變數名稱的格式不能和變數運算式的格式相同,例如 $(var)

  • 指令碼變數不區分大小寫。

    Note

    如果未指定任何值給 sqlcmd 環境變數,則會移除該變數。 不使用 :setvar VarName 值即可清除變數。

當您指定指令碼變數的值時,請考慮下列指導方針:

  • 使用 setvar-v 選項定義的變數值,如果字串值包含空格,則必須以引號括住。
  • 如果引號是變數值的一部分,則必須逸出。 例如:setvar MyVar "spac""e"

Cmd.exe SET 命令變數名稱和值的使用指導方針

使用 SET 所定義的變數是 Cmd.exe 環境的一部分,並且可供 sqlcmd 參考。 請參考下列指引:

  • 變數名稱不能包含空白字元或引號。
  • 變數值可能包含空格或引號。

sqlcmd 指令碼變數

Variable 相關選項 R/W Default
SQLCMDUSER 1 -U R 2 ""
SQLCMDPASSWORD 1 -P -- ""
SQLCMDSERVER 1 -S R 2 "DefaultLocalInstance"
SQLCMDWORKSTATION -H R 2 "ComputerName"
SQLCMDDBNAME -d R 2 ""
SQLCMDLOGINTIMEOUT -l R/W 3 “8”(秒)
SQLCMDSTATTIMEOUT -t R/W 3 "0" = 永遠等候
SQLCMDHEADERS -h R/W 3 "0"
SQLCMDCOLSEP -s R/W 3 " "
SQLCMDCOLWIDTH -w R/W 3 "0"
SQLCMDPACKETSIZE -a R 2 "4096"
SQLCMDERRORLEVEL -m R/W 3 "0"
SQLCMDMAXVARTYPEWIDTH -y R/W 3 "256"
SQLCMDMAXFIXEDTYPEWIDTH -Y R/W 3 "0" = 無限制
SQLCMDEDITOR R/W 3 "edit.com"
SQLCMDINI R 2 ""

1SQLCMDUSER、SQLCMDPASSWORD 和 SQLCMDSERVER 會在使用 :Connect 時設定。

2 R 表示在程式初始化期間只能設定該值一次。

3 R/W 表示可以使用 命令來重設 setvar 值,而後續命令會使用新的值。

Examples

本文中的程式代碼範例會使用 AdventureWorks2025AdventureWorksDW2025 範例資料庫,您可以從 Microsoft SQL Server 範例和社群專案 首頁下載。

A. 在指令碼中使用 setvar 命令

許多 sqlcmd 選項可以在指令碼中使用 setvar 命令來控制。 下列範例會建立指令碼 test.sql ,其中的 SQLCMDLOGINTIMEOUT 變數設為 60 秒,而另一個指令碼變數 server則設為 testserver。 下列程式碼是在 test.sql中。

:setvar SQLCMDLOGINTIMEOUT 60
:setvar server "testserver"
:connect $(server) -l $(SQLCMDLOGINTIMEOUT)

USE AdventureWorks2022;

SELECT FirstName, LastName
FROM Person.Person;

隨後會使用 sqlcmd 呼叫指令碼:

sqlcmd -i c:\test.sql

B. 以互動方式使用 setvar 命令

下列範例顯示如何使用 setvar 命令,以互動方式設定指令碼變數。

sqlcmd
:setvar MYDATABASE AdventureWorks2022
USE $(MYDATABASE);
GO

結果集如下所示。

Changed database context to 'AdventureWorks2022'
1>

C. 在 sqlcmd 內使用命令提示字元環境變數

在下列範例中,設定了四個環境變數 are ,然後從 sqlcmd 進行呼叫。

SET tablename=Person.Person
SET col1=FirstName
SET col2=LastName
SET title=Ms.
sqlcmd -d AdventureWorks2022
1> SELECT TOP 5 $(col1) + ' ' + $(col2) AS Name
2> FROM $(tablename)
3> WHERE Title ='$(title)'
4> GO

D. 在 sqlcmd 內使用使用者層級環境變數

下列範例在命令提示字元中設定了使用者層級環境變數 %Temp% ,並將其傳遞至 sqlcmd 輸入檔。 若要取得使用者層級環境變數,請在 [控制台] 中按兩下 [系統]。 選取 [進階] 索引標籤,然後選取 [環境變數]

下列程式碼是在輸入檔 C:\testscript.txt中:

:OUT $(MyTempDirectory)
USE AdventureWorks2022;

SELECT FirstName
FROM AdventureWorks2022.Person.Person
WHERE BusinessEntityID < 5;

下列程式碼是在命令提示字元中輸入的:

SET MyTempDirectory=%Temp%\output.txt
sqlcmd -i C:\testscript.txt

以下結果將被傳送到輸出檔案C:\Documents and Settings\<user>\Local Settings\Temp\output.txt

Changed database context to 'AdventureWorks2022'.
FirstName
--------------------------------------------------
Gustavo
Catherine
Kim
Humberto

(4 rows affected)

E. 使用啟動指令碼

啟動 sqlcmd 時,會執行 sqlcmd 啟動指令碼。 下列範例會設定環境變數 SQLCMDINI。 這是下者的內容: init.sql.

SET NOCOUNT ON
GO

DECLARE @nt_username nvarchar(128)
SET @nt_username = (SELECT rtrim(convert(nvarchar(128), nt_username))
FROM sys.dm_exec_sessions WHERE spid = @@SPID)
SELECT  @nt_username + ' is connected to ' +
rtrim(CONVERT(nvarchar(20), SERVERPROPERTY('servername'))) +
' (' +`
rtrim(CONVERT(nvarchar(20), SERVERPROPERTY('productversion'))) +
')'
:setvar SQLCMDMAXFIXEDTYPEWIDTH 100
SET NOCOUNT OFF
GO

:setvar SQLCMDMAXFIXEDTYPEWIDTH

這會在 init.sql 啟動時呼叫 sqlcmd 檔案。

SET sqlcmdini=c:\init.sql
sqlcmd

以下是輸出。

1> <user> is connected to <server> (9.00.2047.00)

Note

-X 選項會停用啟動指令碼功能。

F. 可變擴展

下列範例顯示如何以 sqlcmd 變數的形式來使用資料。

USE AdventureWorks2022;
GO
CREATE TABLE AdventureWorks2022.dbo.VariableTest (Col1 NVARCHAR(50));
GO

Col1dbo.VariableTest 中插入一個資料列,包含值 $(tablename)

INSERT INTO AdventureWorks2022.dbo.VariableTest (Col1)
VALUES ('$(tablename)');
GO

sqlcmd 提示字元中,當沒有任何變數設定等於 $(tablename) 時,下列陳述式會傳回資料列,同時傳回訊息「'tablename' 指令碼變數未定義」。預設不設定 sqlcmd 旗標 -b。 如果 -b 已設定,則 sqlcmd 會在「未定義變數」錯誤後終止。

sqlcmd
1> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = '$(tablename)';
2> GO
3> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = N'$(tablename)';
4> GO

結果集如下所示。

1> Col1
2> ------------------
3> $(tablename)
4>
5> (1 rows affected)

假使變數 MyVar 設定為 $(tablename)

6> :setvar MyVar $(tablename)

下列陳述式會傳回該資料列,而且還會傳回訊息「'tablename' 指令碼變數未定義」。

6> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = '$(tablename)';
7> GO

1> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = N'$(tablename)';
2> GO

這些陳述會傳回資料列。

1> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = '$(MyVar)';
2> GO
1> SELECT Col1 FROM dbo.VariableTest WHERE Col1 = N'$(MyVar)';
2> GO