Mode SQLCMD dalam ekspansi variabel SSMS dan @@

8

Saat menggunakan mode SQLCMD dengan SSMS (bukan dari commandline), apakah ada cara untuk menetapkan server saat ini dan instance ke variabel? Ini berbeda dan berbeda dari menetapkan variabel TSQL biasa.

Definisi masalah

Saya ingin menggunakan kekuatan ekspansi variabel SQLCMD untuk menggantikan nilai-nilai khusus lingkungan dalam skrip deploy kami alih-alih tumbuk string bangunan tsql yang sudah ada. Dengan satu pengecualian dari lingkungan saat ini, penggunaan SQLCMD untuk menangani penyebaran telah berjalan sangat baik.

--
-- 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

Dan itu menghasilkan hasil sebagai berikut.

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

Meat Loaf mengatakan 2 dari 3 tidak buruk , tetapi saya lebih suka memiliki 3 dari 3 solusi. Ketika skrip itu digunakan server pengujian, saya tidak ingin mempercayai orang-orang deployment dengan mengedit skrip.

Jika satu-satunya solusi untuk menggunakan SQLCMD adalah dengan memanggil skrip sepenuhnya dari baris perintah, saya bisa menerimanya tetapi ingin membuang ini di sini karena saya hijau untuk menggunakan SQLCMD.

Output yang diinginkan

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

Hasil

worked
DEVA\DEV2

Pengejaran tanpa hasil

Tautan BOL pertama menunjukkan janji, yang harus saya lakukan adalah menggunakan SQLCMDSERVER tetapi tidak berhasil. Jalankan dalam konteks SSMS dalam mode SQLCMD, itu akan menimbulkan kesalahan skrip yang fatal

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

Pembaruan Tumbleweed

2011-08-12 Dalam upaya untuk mengurangi masalah saya ke bentuk paling sederhana, berdasarkan jawaban, saya menyederhanakan pertanyaan saya (permintaan maaf saya). Sebagian dari kueri yang saya gunakan ada di bawah. Kedua reponders benar dalam jawaban mereka yang mengidentifikasi membungkus @@ servername dalam tanda centang menghasilkan nilai literal dan untuk mendapatkan nilai yang diperluas, saya perlu membukanya dari tanda kutip. Keinginan saya adalah untuk menggunakan substitusi variabel sqlcmd daripada membangun string yang akan terbuka.

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

Doa baris perintah berfungsi (seperti yang diharapkan)

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

Saya sudah mencoba dan membuang permutasi lain dari: setvar x @@ servername dalam upaya untuk mendapatkan nilai yang dievaluasi dari variabel database yang disimpan ke dalam variabel SQLCMD. Pada titik ini, saya cukup yakin variabel sqlcmd susbstituted dalam query sebelum kompilasi permintaan tetapi akan senang terbukti salah.

Referensi BOL

billinkc
sumber

Jawaban:

3

Variabel SQL-CMD dievaluasi sebelum batch berjalan. Jadi, Anda tidak dapat menetapkan nilai variabel t-sql ke variabel CMD.

Stefan Wilms
sumber
Jelas terlihat seperti itu. Apakah Anda mengetahui adanya dokumentasi yang menyatakan demikian?
billinkc
3

Kecuali saya kehilangan sesuatu, bukankah ini bekerja, tanpa tanda kutip ?:

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

Ia mengembalikan SERVER \ INSTANCE untuk saya dalam mode SQLCMD melalui SSMS.

Sunting 02/12/2018 Setelah menemukan jawaban saya untuk pertanyaan lain, dan meninjau, saya dapat melihat masalah ini, saya yakin ini mengarah ke ini:

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

Ini output @@ servername , dan output yang diinginkan adalah nilai servername @@. Satu-satunya cara saya melakukan ini adalah dalam jawaban yang diterima di sini

SqlACID
sumber
1
Anda hanya mengganti string @@servernameuntuk $(dbNotServer)jadi SQL yang dikirim untuk mengeksekusi adalah SELECT @@servername AS worked. Tidak ada penetapan nilai @@servername untuk variabel sqlcmd seperti yang diminta.
Martin Smith
1

Di bawah "Output yang Diinginkan", T-SQL yang menuju ke server menjadi:

SELECT '@@servername' AS worked

Menempatkan tanda kutip tunggal @@servernamemenjadikannya string literal dan tidak akan diganti dengan nama sebenarnya, itulah sebabnya Anda melihat @@servernamesebagai nilainya.

Jika Anda ingin menampilkan nama server, hapus tanda kutip tunggal, buat T-SQL Anda:

SELECT @@servername AS worked

Saya tidak sepenuhnya jelas saya mengerti pertanyaannya, tetapi ini adalah bagaimana Anda akan mendapatkan apa yang ada dalam "Output yang Diinginkan".

Pavel
sumber