TSQL kullanarak veritabanını dinamik olarak değiştirme


11

Dinamik SQL'de belirtilen veritabanına SSMS içeriğini dinamik olarak değiştirmeye çalışırken sorun yaşıyorum:

EXEC sys.sp_executesql N'USE db1 ' ;

Başarılı bir şekilde yürütülür ancak SSMS'nin veritabanı içeriği değişmez.

Yukarıdaki gibi küçük bir değişiklik denedim

DECLARE @sql NVARCHAR(100) DECLARE @db NVARCHAR(50)
SET @db = N'db1' SET @sql = N'Use ' + @db
EXEC sp_executesql @sql

Yine, başarıyla yürütülür, ancak veritabanı değişmez.


4
SSMS'de kullandığınız oturum için bir sp_executesql içindeki içeriği değiştiremezsiniz. Bağlam yalnızca dinamik SQL oturumunuz sırasında geçerlidir - SSMS oturumu için geçerli değildir.
Lothar Kraner

Yanıtlar:


7

SSMS DİNAMİK SQL'DE ÇALIŞTIĞINIZ BİR KULLANIM KOMUTUNUN BAĞLAMACAĞINI TEKRAR ETMEYECEKTİR .

Nihai hedef, seçilen veritabanı içinde başka bir dinamik SQL yürütmekse, bu yeterince kolaydır:

DECLARE @db sysname = N'db1';

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'SELECT DB_NAME();';

EXEC @exec @sql;

Parametreleri geçmeniz gerekiyorsa, sorun yok:

DECLARE @db sysname = N'db1', @i int = 1;

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'SELECT DB_NAME(), @i;';

EXEC @exec @sql, N'@i int', @i;

Hedef, seçilen veritabanı içinde bazı statik SQL yürütmekse , belki bu statik SQL'i her veritabanındaki saklı yordamda saklamayı ve dinamik olarak şöyle çağırmayı düşünmelisiniz:

DECLARE @db sysname = N'db1';

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'EXEC dbo.procedurename;';

EXEC @exec @sql;

Ve umarım nihai hedef SSMS'de tüm bu kodları çalıştırmak değildir, böylece SSMS şu an bağlamdadır @db...


Harika, teşekkürler Aaron Bertrand. Ve hayır, nihai hedef SSMS'de tüm bu kodları çalıştırmak değil, SSMS'nin @db bağlamında olması
Mazhar

2

DynamicSQL aslında kodunuzun geri kalanı ile özel olarak yürütülmez (ayrı bir varlıktır (hatta satırdaymış gibi çalışsa bile)

Kodu çalıştırırsanız: SET @sql = N'Use ' + @db + '; select DB_NAME(); select @@spid'mevcut kümenizin yerine geri dönen sonuçların etkin veritabanını taşıdığınızı, ancak yine de aynı bağlantı altında çalıştığınızı gösterirsiniz.

Satır içi veritabanı seçimini değiştirmek istiyorsanız, en iyi yol böyle bir şey yapmaktır:

IF @db = 'db1'
    USE db1
ELSE IF @db = 'db2'
    USE db2

Güzel veya temiz değil ve potansiyel veritabanı başına iki satır gerektirir, ancak işi bitirir (dinamik SQL'de çalıştırmayın veya yine de ana iş parçacığının aynı sorunu değiştirilmeyecektir)

Prosedürlerde / fonksiyonlarda USE komutlarının kullanılmasının yasak olduğunu unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.