2011-12-21 5 views
2

Я удивлен, что этого не произошло раньше, но я ничего не нашел в поиске ни здесь, ни в другом месте. Я нашел что-то неопределенно похожее, что указывает на то, что проблема заключается в том, что команда Use в моем скрипте длится только для одной строки, но не было никаких указаний на то, как обойти это.Сценарий для создания схемы с использованием переменной

Что я пытаюсь сделать: Создайте общий скрипт для создания базы данных «шаблонов» со всеми моими общими схемами и таблицами. Все переменные (такие как имя базы данных) предназначены для установки в заголовке, чтобы их можно было изменять по мере необходимости, и скрипт можно просто запустить без необходимости выполнять какие-либо рискованные операции поиска и замены для изменения жестко закодированных значений.

В чем проблема: я не могу заставить схемы генерировать в правой базе данных; все они производятся в Мастере. Попытка явно установить базу данных не помогла; Я только что получил ошибки времени выполнения.

Мой уровень умения: длительное время Доступ к пользователю, но все еще в предгорьях изучения SQL Server. Я уверен (ну, надеюсь), это будет смехотворно легко для кого-то, кто продвинется по склону.

Кто-нибудь знает, как я могу сделать что-то подобное? (Существующий код, приведенный ниже.)

DECLARE @DBName NVARCHAR(50) = 'TheDBName'; 

-- Assume that there's a bunch of code to drop and create the database goes here. 
-- This code executes correctly. 

SET @SQL = 'Use [' + @DBName + ']'; 

Print @SQL; 

EXEC(@SQL); 

SET @Counter = 1; 

WHILE @Counter <=3 

    BEGIN 
     SET @SQL = 'CREATE SCHEMA [' + 
     CASE @Counter 
      WHEN 1 THEN 'Schema1' 
      WHEN 2 THEN 'Schema2' 
      WHEN 3 THEN 'Schema3' 
     END 

     SET @SQL = @SQL + '] AUTHORIZATION [dbo]'; 

     PRINT 'Creating Schemas, ' + @SQL; 

     Exec(@SQL); 

    SET @Counter = @Counter + 1;  
END 

ответ

4

Команда use только изменяет текущий db в области действия, в которой вы находитесь, и динамический SQL работает в своей собственной области.

Попробуйте из master

declare @SQL nvarchar(max) 
set @SQL = N'use tempdb; print db_name()' 
exec(@SQL) 
print db_name() 

Результат:

tempdb 
master 

Попробуйте это:

DECLARE @DBName NVARCHAR(50) = 'TheDBName'; 
DECLARE @SQL NVARCHAR(max) 
DECLARE @SQLMain NVARCHAR(max) 
DECLARE @Counter int 

SET @SQLMain = 'Use [' + @DBName + ']; exec(@SQL)'; 


SET @Counter = 1; 

WHILE @Counter <=3 
BEGIN 
    SET @SQL = 'CREATE SCHEMA [' + 
     CASE @Counter 
      WHEN 1 THEN 'Schema1' 
      WHEN 2 THEN 'Schema2' 
      WHEN 3 THEN 'Schema3' 
     END 

    SET @SQL = @SQL + '] AUTHORIZATION [dbo]'; 

    EXEC sp_executesql @SQLMain, N'@SQL nvarchar(max)', @SQL; 

    SET @Counter = @Counter + 1; 
END 
+1

Спасибо, что нашли время ответить, Я боюсь, что это не сработает. Линия выводится как Use [MYDBTEMPLATE]; CREATE SCHEMA [SCHEMA1] АВТОРИЗАЦИЯ [dbo] Сгенерированная ошибка «CREATE SCHEMA» должна быть первым оператором в пакете запросов. –

+1

@AlanK - Конечно. Не думал об этом. –

+0

Но ваш пересмотренный код работал блестяще! Благодарю вас, вы, да! –

0

Если вы бежите заявление USE внутри EXEC(), а затем запускать другие операторы также в EXEC()

но

вы должны использовать USE databasename STMT. в каждом EXEC()

+0

Thanks Oleg; Я думаю, это то, что указывал Микаэль, но затем я ударил по проблеме «должно быть первым заявлением» (о котором я забыл упомянуть в начальном посте, с которым я столкнулся раньше). –

0

Другие ответы объяснили вашу непосредственную проблему, но так как это действительно проблема развертывания, как общее решение, вы можете попробовать using SQLCMD variables, что вы можете установить во время выполнения из командной строки. Это позволит вам динамически передавать имя базы данных и/или имена схем в сценарии, чтобы затем можно было автоматизировать развертывание с использованием пакетных файлов или проектов базы данных VS.

+0

Спасибо за это; Я начал просматривать соответствующие файлы справки; которые могут быть полезны в будущем. –

Смежные вопросы