web-dev-qa-db-fra.com

instruction d'utilisation SQL avec variable

J'essaie de changer la base de données actuelle avec une instruction SQL ..__ J'ai essayé ce qui suit, mais toutes les tentatives ont échoué:

  1. USE @DatabaseName
  2. EXEC sp_sqlexec @Sql - où @Sql = 'USE [' + @DatabaseName + ']'

Pour ajouter un peu plus de détails.

EDIT: Je voudrais effectuer plusieurs choses sur deux bases de données distinctes, où les deux sont configurés avec une variable. Quelque chose comme ça:

USE Database1
SELECT * FROM Table1

USE Database2
SELECT * FROM Table2
24
Drejc

J'ai le même problème, je l'ai surmonté avec un ensemble de GOTO laids - mais utiles -.

La raison pour laquelle j’appelle le «script runner» avant tout, c’est que je veux cacher la complexité et l’approche laide à tout développeur qui souhaite simplement travailler avec le script réel. En même temps, je peux m'assurer que le script est exécuté exactement de la même manière dans les deux bases de données (extensibles à trois et plus).

GOTO ScriptRunner

ScriptExecutes:

--------------------ACTUAL SCRIPT--------------------
-------- Will be executed in DB1 and in DB2 ---------
--TODO: Your script right here

------------------ACTUAL SCRIPT ENDS-----------------

GOTO ScriptReturns

ScriptRunner:
    USE DB1
    GOTO ScriptExecutes

ScriptReturns:
    IF (db_name() = 'DB1')
    BEGIN
        USE DB2
        GOTO ScriptExecutes
    END

Avec cette approche, vous gardez vos variables et SQL Server ne vous fait pas peur si vous passez deux fois sur une instruction DECLARE.

10
Alpha
   exec sp_execsql @Sql

Le changement de base de données ne dure que le temps nécessaire pour terminer @sql

http://blog.sqlauthority.com/2007/07/02/sql-server-2005-comparison-sp_executesql-vs-executeexec/

10
Preet Sangha

Le problème avec l'ancien est que vous êtes en train de faire USE 'myDB' plutôt que USE myDB. Vous passez une chaîne; mais USE cherche une référence explicite.

Ce dernier exemple fonctionne pour moi.

declare @sql varchar(20)
select @sql = 'USE myDb'
EXEC sp_sqlexec @Sql

-- also works
select @sql = 'USE [myDb]'
EXEC sp_sqlexec @Sql
9
Joel Goodwin

Je voulais juste remercier KM pour sa précieuse solution . Je l’ai moi-même mis en œuvre pour réduire le nombre de lignes d’une requête shrinkdatabase sur SQLServer . Voici ma requête SQL si elle peut aider n’importe qui:

-- Declare the variable to be used
DECLARE @Query varchar (1000)
DECLARE @MyDBN varchar(11);
-- Initializing the @MyDBN variable (possible values : db1, db2, db3, ...)
SET @MyDBN = 'db1';
-- Creating the request to execute
SET @Query='use '+ @MyDBN +'; ALTER DATABASE '+ @MyDBN +' SET RECOVERY SIMPLE WITH NO_WAIT; DBCC SHRINKDATABASE ('+ @MyDBN +', 1, TRUNCATEONLY); ALTER DATABASE '+ @MyDBN +' SET RECOVERY FULL WITH NO_WAIT'
-- 
EXEC (@Query)
3
tmi

essaye ça:

DECLARE @Query         varchar(1000)
DECLARE @DatabaseName  varchar(500)

SET @DatabaseName='xyz'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table1'
EXEC (@Query)

SET @DatabaseName='abc'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table2'
EXEC (@Query)
2
KM.

J'affirme que quelqu'un a besoin d'une solution pour cela, en voici une:

si vous utilisez une instruction USE dynamique, toute votre requête doit être dynamique, car elle doit tout figurer dans le même contexte.

Vous pouvez essayer avec SYNONYM, c’est en gros un ALIAS pour une table spécifique, ce SYNONYM est inséré dans la table sys.synonym afin que vous puissiez y accéder depuis n’importe quel contexte

Regardez cette déclaration statique:

CREATE SYNONYM MASTER_SCHEMACOLUMNS FOR Master.INFORMATION_SCHEMA.COLUMNS
SELECT * FROM MASTER_SCHEMACOLUMNS

Maintenant dynamique:

DECLARE @SQL VARCHAR(200)
DECLARE @CATALOG VARCHAR(200) = 'Master'

IF EXISTS(SELECT * FROM  sys.synonyms s WHERE s.name = 'CURRENT_SCHEMACOLUMNS')
BEGIN
DROP SYNONYM CURRENT_SCHEMACOLUMNS
END

SELECT @SQL = 'CREATE SYNONYM CURRENT_SCHEMACOLUMNS FOR '+ @CATALOG +'.INFORMATION_SCHEMA.COLUMNS';
EXEC sp_sqlexec @SQL

--Your not dynamic Code
SELECT * FROM CURRENT_SCHEMACOLUMNS

Maintenant changez simplement la valeur de @CATALOG et vous pourrez lister la même table mais à partir d'un catalogue différent.

2
Hans Langer

Si SQLCMD est une option, il prend en charge les variables de script au-delà de ce que T-SQL peut faire directement. Par exemple: http://msdn.Microsoft.com/en-us/library/ms188714.aspx

1
onupdatecascade

Tu peux le faire:

Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';

Declare @SQL nvarchar(max);
select @SQL = 'USE ' + @dbName +'; {can put command(s) here}';
EXEC (@SQL);

{but not here!}

Cela signifie que vous pouvez faire une sélection récursive comme suit:

Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';
Declare @SQL nvarchar(max);

SELECT @SQL = 'USE ' + @dbName + '; ' +(Select ... {query here}
For XML Path(''),Type)
.value('text()[1]','nvarchar(max)');

Exec (@SQL)
0
Garry_G