Comment changer dynamiquement la base de données à l'aide de TSQL


11

J'ai du mal à essayer de changer dynamiquement le contexte de SSMS en base de données spécifiée dans SQL dynamique:

EXEC sys.sp_executesql N'USE db1 ' ;

Il s'exécute avec succès mais le contexte de base de données de SSMS ne change pas.

J'ai essayé une légère modification de ce qui précède comme ça

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

Encore une fois, il s'exécute avec succès, mais la base de données ne change pas.


4
Vous ne pouvez pas modifier le contexte dans un sp_executesql pour la session que vous utilisez dans le SSMS. Le contexte n'est valide que pendant votre session SQL dynamique - pas pour la session SSMS.
Lothar Kraner

Réponses:


7

SSMS NE SERA PAS, JE LE RÉPÈTE, PAS PASSÉ AU CONTEXTE D'UNE COMMANDE D'UTILISATION QUE VOUS EXÉCUTEZ EN DYNAMIC SQL.

Si le but ultime est d'exécuter un autre SQL dynamique dans la base de données choisie, c'est assez simple:

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;

Si vous devez passer des paramètres, pas de problème:

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;

Si le but est d'exécuter du SQL statique dans la base de données choisie, vous devriez peut-être envisager de stocker ce SQL statique dans une procédure stockée dans chaque base de données, et de l'appeler dynamiquement comme ceci:

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;

Et j'espère que le but ultime n'est pas d'exécuter tout ce code dans SSMS juste pour que SSMS soit maintenant dans le contexte de @db... Daniel aimerait vraiment que je déclare explicitement que ce n'est pas possible, comme l'a également déclaré le commentaire de @ Lothar.


C'est super, merci Aaron Bertrand. Et non, le but ultime n'est pas d'exécuter tout ce code dans SSMS juste pour que SSMS soit maintenant dans le contexte de @db
Mazhar

2

Le dynamicSQL n'est pas réellement exécuté spécifiquement en ligne avec le reste de votre code, c'est une entité distincte (même s'il est exécuté comme s'il était en ligne

Si vous exécutez le code: SET @sql = N'Use ' + @db + '; select DB_NAME(); select @@spid'à la vue de votre ensemble actuel, vous remarquerez que les résultats qui reviennent indiquent que vous avez déplacé la base de données active, mais que vous exécutez toujours sous la même connexion.

Si vous souhaitez modifier la sélection de la base de données en ligne, la meilleure façon est de faire quelque chose comme ceci:

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

Ce n'est pas agréable ou propre et nécessite deux lignes par base de données potentielle, mais cela fera le travail (ne l'exécutez pas en SQL dynamique ou vous vous retrouverez toujours avec le même problème de thread principal non modifié)

Notez cependant que l'utilisation des commandes USE est interdite dans les procédures / fonctions

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.