Come modificare dinamicamente il database usando TSQL


11

Sto riscontrando problemi nel tentativo di modificare dinamicamente il contesto di SSMS nel database specificato in SQL dinamico:

EXEC sys.sp_executesql N'USE db1 ' ;

Viene eseguito correttamente, tuttavia il contesto del database di SSMS non cambia.

Ho provato una leggera modifica a quanto sopra in questo modo

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

Ancora una volta, viene eseguito correttamente, ma il database non cambia.


4
Non è possibile modificare il contesto in uno sp_executesql per la sessione che si sta utilizzando in SSMS. Il contesto è valido solo durante la sessione SQL dinamica, non per la sessione SSMS.
Lothar Kraner,

Risposte:


7

SSMS NON RIPETTERO, NON PASSERÀ AL CONTESTO DI UN COMANDO DI UTILIZZO ESEGUITO IN SQL DINAMICO.

Se l'obiettivo finale è quello di eseguire qualche altro SQL dinamico all'interno del database scelto, questo è abbastanza semplice:

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;

Se è necessario passare parametri, nessun problema:

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;

Se l'obiettivo è eseguire un SQL statico all'interno del database scelto, forse dovresti considerare di archiviare tale SQL statico in una procedura memorizzata in ciascun database e chiamarlo in modo dinamico in questo modo:

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;

E speriamo che l'obiettivo finale non sia quello di eseguire tutto questo codice in SSMS solo in modo che SSMS sia ora nel contesto di @db... Daniel lo gradirebbe davvero se affermassi esplicitamente che ciò non è possibile, come ha anche affermato il commento di @ Lothar.


Questo è fantastico, grazie Aaron Bertrand. E no, l'obiettivo finale non è quello di eseguire tutto questo codice in SSMS solo in modo che SSMS sia ora nel contesto di @db
Mazhar

2

DynamicSQL non viene effettivamente eseguito specificamente in linea con il resto del codice è un'entità separata (anche se viene eseguito come se fosse in linea

Se esegui il codice: SET @sql = N'Use ' + @db + '; select DB_NAME(); select @@spid'a dispetto del tuo set corrente noterai che i risultati che ritornano indicano che hai spostato il database attivo, ma sei ancora in esecuzione con la stessa connessione.

Se si desidera modificare la selezione del database in linea, il modo migliore è fare qualcosa del genere:

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

Non è carino o pulito e richiede due righe per ogni potenziale database ma eseguirà il lavoro (non eseguirlo in SQL dinamico o finirai comunque con lo stesso problema del thread principale che non viene modificato)

Si noti tuttavia che l'uso di comandi USE è proibito nelle procedure / funzioni

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.