2010-02-02 2 views
4

Я получил это T-SQL сниппет:заявление «USE @dbname» не работает, почему? Как это сделать?

DECLARE @db_name varchar(255); 
SET @db_name = 'MY_DATABASE'; -- assuming there is database called 'my_database' 
USE @db_name -- this line ends with error "Incorrect syntax near '@db'." 

Но ИСПОЛЬЗОВАТЬ с переменной (третьей строке фрагмента кода) не работает. Почему это не работает?

+0

Лично я бы сказал, что у вас проблема с дизайном, если вы изменяете имена баз данных на лету в запросах (если только вы не выполняете работу администратора). Почему вы хотите динамически указывать имя базы данных? Может быть, если бы мы поняли, почему мы могли бы получить лучшее решение, чем динамический SQL (чего следует избегать в производственном коде, если это возможно по многим причинам). – HLGEM

+0

Я просто хотел легко перебрать несколько наборов баз данных и выполнить некоторую обработку (задача, связанная с администратором). Вид этого в псевдокоде: DatabaseList = { "DB1", "DB2", "DB3"} Еогеасп (дБ базы данных в DatabaseList) { ИСПОЛЬЗОВАНИЯ дБ; INSERT INTO table VALUES (value1, value2) } –

+0

'TSQL' считается инструментом для работы с базами данных, а не с мета-базами данных. Обычно задачи метабазы ​​(например, описанные вами) выполняются с использованием внешнего инструмента, такого как скрипт Perl или PHP, который будет подключаться к каждой базе данных по отдельности и запускать требуемый запрос. – Quassnoi

ответ

8

Вы не можете указать имя базы данных для оператора USE в переменной.

+1

@Quassnoi: Почему бы и нет? и есть ли прогулка? – Sung

3

SQL Server не принимает оператор USE с переменной.

Чтобы использовать имена баз данных динамически, вы должны создавать динамические операторы SQL с (почти) полностью квалифицированных имен следующим образом:

Declare @SQL VarChar (100) 

SET @SQL = 'SELECT * FROM ' + @DatabaseName + '.dbo.TableName' 

а затем выполнить его с помощью sp_SQLExec

+1

Остерегайтесь SQL-инъекций, когда я прокомментировал ответ Йорна. –

4

Как вы уже заметили, оператор USE не принимает переменную в качестве параметра. Единственная альтернатива, которая быстро приходит на ум, является довольно грубым и очень подвержен ошибкам, но здесь вы идете:

EXEC ('USE ' + @db_name + ' 
     SELECT * FROM some_table 
     INSERT INTO some_table VALUES (1)') 

Я надеюсь, что кто-то может сделать лучше :-)

+1

Также довольно подвержен SQL-инъекции. Посмотрите, что (а также функция QUOTENAME(), которая может помочь во многих случаях). –

+2

Действительно. В зависимости от варианта использования это может быть или не быть проблемой :) –

1

так, как я сделать это с a if:

if @DBName = 'DB1' 
    <query with DB1> 
else 
    <query with DB2> 
Смежные вопросы