Bagaimana cara menulis SQL portabel yang merujuk ke server yang ditautkan?


9

Saya punya prosedur tersimpan yang merujuk ke server yang ditautkan. Di beberapa tempat selama prosedur, saya memiliki sesuatu seperti berikut:

INSERT INTO [TableName]
(...Columns...)
SELECT ...Columns...
FROM [ServerName\InstanceName].[Catalogue].[dbo].[TableName]
WHERE TableNameID = @TableNameID

Prosedur ini ada di lingkungan Pengembangan saya, lingkungan Uji dan lingkungan Langsung.

Masalahnya adalah bahwa setiap salinan prosedur ini agak berbeda karena nama server berbeda untuk setiap lingkungan. Ini membuat mengelola penyebaran pembaruan skrip menjadi sulit.

Apakah ada cara untuk membuat prosedur ini portabel sehingga setiap lingkungan dapat menjalankan versi identiknya?

Jika tidak, adakah yang bisa saya lakukan untuk membuat penyebaran skrip kurang rentan terhadap kesalahan / kesalahan?


3
Apakah membuat tampilan yang berbeda pada setiap server merupakan opsi? Anda dapat mendefinisikan tampilan sebagai SELECT <fields> FROM <linked server>tetapi menggunakan nama tampilan yang sama di semua server untuk menjaga kode tetap dipertahankan
JNK

@ JNK itu bukan ide yang buruk, ada beberapa tabel meskipun, tapi setidaknya pandangan akan lebih mudah untuk mempertahankan daripada prosedur yang tersimpan dengan referensi server yang terhubung dibumbui di seluruh.
Dokter Jones

@ jnk, Anda harus menjawabnya.
HLGEM

Jawaban:


14

Nama server tertaut Anda tidak harus nama server. Anda dapat menggunakan nama generik.

EXEC master.dbo.sp_addlinkedserver
    @server = N'COMMONNAME',
    @srvproduct=N'MSDASQL',
    @provider=N'SQLNCLI',
    @provstr=N'DRIVER={SQL Server};SERVER=ACTUALSERVERNAME;UID=user1;PWD=rosebud567;', 
    @catalog=N'database1'

Siapkan server yang ditautkan pada setiap lingkungan dengan nama yang sama, tetapi sebenarnya arahkan mereka ke server yang berbeda.


0

Saya suka gagasan menggunakan nama server tertaut generik. Namun, di banyak lingkungan ini tidak mungkin, Dalam hal ini, Anda dapat menggunakan SQl dinamis di sp Anda.

declare @linkedservername nvarchar(200)
declare @sql nvarchar(4000)
SET @linkedservername =  CASE @@ServerName  
                            WHEN 'DevServer' THEN 'LinkedServerForDevEnvironment'
                            WHEN 'TestServer' THEN 'LinkedServerForTestEnvironment'
                            WHEN 'ProdServer' THEN 'LinkedServerForProdEnvironment'
                            ELSE Null
                        END   

set @sql = 'INSERT INTO [TableName] 
(...Columns...) 
SELECT ...Columns... 
FROM ' + @linkedservername + '.[Catalogue].[dbo].[TableName] 
WHERE TableNameID = @TableNameID'

Exec  @sql

1
Saya akan mencatat bahwa jika saya melakukan ini dalam kehidupan nyata, saya akan menggunakan blok coba tangkap dan memunculkan kesalahan jika @linkedservername nol setelah pernyataan yang ditetapkan untuk memperingatkan Anda bahwa ini dijalankan pada server yang salah.
HLGEM

1
Jika Anda mengambil pendekatan ini, saya pikir saya akan membungkus pernyataan KASUS dalam suatu fungsi jadi jika server berubah, saya hanya perlu memperbarui fungsi.
Eli

Baik titik @Eli
HLGEM
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.