SSMSのSQLCMDモードと@@ variable展開


8

(コマンドラインからではなく)SSMSでSQLCMDモードを使用する場合、現在のサーバーとインスタンスを変数に割り当てる方法はありますか?これは、通常のTSQL変数の割り当てとは異なります。

問題の定義

SQLCMDの変数拡張機能を使用して、導入した既存のtsql文字列構築マッシュの代わりに、配置スクリプトの環境固有の値を置き換えたいと思います。現在の環境の1つの例外を除いて、SQLCMDを使用してデプロイを処理することは非常にうまくいきました。

--
-- define 2 sqlcmd variables that will be expanded in scripts
--
:setvar dbServer "DEVA2\DEV2"
:setvar dbNotServer @@servername

SELECT
    '$(dbServer)' AS hard_coded_value
,   @@servername AS [servername]
,   '$(dbNotServer)' AS dbNotServer

そして、それは以下の結果を生成します。

hard_coded_value  servername  dbNotServer
DEVA2\DEV2        DEVA2\DEV2  @@servername

ミートローフは3分の2は悪くないと言っていますが、私は3分の3の解決策を持っていると思います。スクリプトがテストサーバーに展開されたとき、スクリプトの編集を展開担当者に任せたくありません。

SQLCMDを使用するための唯一の解決策がコマンドラインからスクリプトを完全に呼び出すことである場合、私はそれを受け入れることができますが、SQLCMDを使用するのは環境に優しいので、ここでこれを捨てたいと思います。

望ましい出力

:setvar dbNotServer @@servername
SELECT '$(dbNotServer)' AS worked

結果

worked
DEVA\DEV2

実りのない追求

最初のBOLリンクは約束を示しました。私がしなければならなかったのはSQLCMDSERVERを使用することだけでしたが、役に立ちませんでした。SQLSMSモードでSSMSのコンテキスト内で実行すると、致命的なスクリプトエラーがスローされます

-- A fatal scripting error occurred.
-- Variable SQLCMDSERVER is not defined.
SELECT '$(SQLCMDSERVER)' AS [FatalScriptingError]

タンブルウィード更新

2011-08-12答えに基づいて、問題を最も単純な形に減らすために、クエリを単純化しすぎました(私の謝罪)。使用したクエリの一部を以下に示します。2つのレスポンダは、@@ servernameをティックマークでラップすると結果としてリテラル値が得られ、拡張された値を取得するには、引用符からアンラップする必要があります。私の望みは、アンラップを伴う文字列の構築ではなく、sqlcmd変数置換を使用することでした。

INSERT INTO
    dbo.SSISCONFIG
(
    ConfigurationFilter
,   ConfiguredValue
,   PackagePath
,   ConfiguredValueType
,   Application
,   Category
,   Subcategory
,   Comment
)
SELECT
    'Default.Accounting' AS ConfigurationFilter
,   'Data Source=$(dbServer);Initial Catalog=Accounting;Provider=SQLNCLI10.1;Integrated Security=SSPI;Packet Size=32767;' AS ConfiguredValue
,   '\Package.Connections[Accounting].Properties[ConnectionString]' AS PackagePath
,   'String' AS ConfiguredValueType
,   'Defaults' AS Application
,   'Connection' AS Category
,   'Database' AS Subcategory
,   'Default connection string' AS Comment
SELECT
    'Default.$(sqlVersion).CorporateReporting' AS ConfigurationFilter
,   'Data Source=$(dwServer);Initial Catalog=CRDS;Provider=SQLNCLI10.1;Integrated Security=SSPI;Packet Size=32767;' AS ConfiguredValue
,   '\Package.Connections[CorporateReporting].Properties[ConnectionString]' AS PackagePath
,   'String' AS ConfiguredValueType
,   'Defaults' AS Application
,   'Connection' AS Category
,   'Database' AS Subcategory
,   'Default connection string' AS Comment

コマンドライン呼び出しは(期待どおりに)機能します

C:\>sqlcmd -E -d master -S DEVA2\DEV2 -Q "SELECT '$(SQLCMDSERVER)' AS [servername]"

SQLCMD変数に格納されているデータベース変数の評価値を取得するために、:setvar x @@ servernameの他の順列を試行して破棄しました。この時点で、クエリのコンパイル前にsqlcmd変数がクエリで代替されていることはほぼ確実ですが、間違っていることが証明されることを望んでいます。

BOLリファレンス

回答:


3

SQL-CMD変数は、バッチが実行される前に評価されます。したがって、t-sql変数の値をCMD変数に割り当てることはできません。


それは確かにそのように見えます。これがそうであると述べているドキュメントを知っていますか?
billinkc 2015年

3

私が何かを逃していない限り、アポストロフィなしでこれはうまくいきませんか?:

:setvar dbNotServer @@servername
SELECT $(dbNotServer) AS worked

SSMSを介してSQLCMDモードでSERVER \ INSTANCEを返します。

2018年12月12日編集別の質問に対する私の答えに出会い、確認した後、私は問題を見ることができます、それはこれに要約すると信じています:

:setvar dbNotServer @@servername
print '$(dbNotServer)'

これは@@ servernameを出力し、必要な出力は@@ servernameの値です。私がこれを行うために見た唯一の方法は、ここで受け入れられた答えにあります


1
実行するために送信されるSQLが@@servername$(dbNotServer)なるように、文字列を置き換えるだけですSELECT @@servername AS worked。要求されたsqlcmd変数への の割り当てはありません@@servername
マーティン・スミス

1

「必要な出力」の下で、サーバーに送信されるT-SQLは次のようになります。

SELECT '@@servername' AS worked

単一引用符で囲む@@servernameと、文字列リテラルになり、実際の名前に置き換えられません@@servername。そのため、値として表示されます。

サーバー名を表示する場合は、単一引用符を削除して、T-SQLを作成します。

SELECT @@servername AS worked

私は質問を理解していることは完全には明らかではありませんが、これが「望ましい出力」の内容をどのようにして得るかです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.