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?

Dokter Jones
sumber
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.

Eli
sumber
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
HLGEM
sumber
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