2016-10-27 11 views
2

Я использую динамический SQL, чтобы создать базу данных в таблицы"USE [DB]" Динамический SQL не работал

это SQL скрипт

DECLARE @DatabaseName VARCHAR(50) = N'test'; 
EXECUTE ('CREATE DATABASE [' [email protected]+']'); 
EXECUTE('USE ' + @DatabaseName) 
GO 
CREATE SCHEMA [Framework] 
GO 

ошибка я получаю

Msg 2714, Level 16, State 6, Line 1 
There is already an object named 'Framework' in the database. 
Msg 2759, Level 16, State 0, Line 1 
CREATE SCHEMA failed due to previous errors 

.

эта ошибка, потому что EXECUTE ('USE' + @DatabaseName) не работает

Я пытаюсь использовать

SET @SQL02 = 'USE ['+ convert(nvarchar(50),@DatabaseName) +']; SELECT DB_NAME();' 
exec sp_executesql @SQL02 

но не работает

что я могу сделать?

+0

Пометьте используемые вами dbms. (Возможно, SQL-Server?) – jarlh

+0

Я использовал SQL-версию 2012 – Jala

+2

Выполняет запуск в своем собственном экземпляре. У вас должны быть все действия в той же команде EXECUTE для правильной работы 'USE ''. – Jens

ответ

2
DECLARE @Query VARCHAR(200); 
SET @Query = CONCAT('USE ', QUOTENAME('<MyDatabase>'), '; ', 'select DB_NAME();'); 

EXECUTE (@Query); 

Это вернет <MyDatabase> до тех пор, пока вы остаетесь в пределах одного EXECUTE.

1

Попробуйте это: (если вы используете выполнить, контекст дб изменится только для этого выполнить только)

DECLARE @DatabaseName VARCHAR(50) = N'test'; 
EXECUTE ('CREATE DATABASE [' [email protected]+']'); 
use [test] 
go 
CREATE SCHEMA [Framework] 
GO 
2

Я предпочитаю эту форму для удаленного выполнения:

declare @sql nvarchar(max) = N'select Db_Name()'; 

<DatabaseName>.sys.sp_executesql @sql; 

Вы можете поместить это логики в более удобную форму путем внесения в хранимую процедуру:

create procedure dbo.usp_ExecuteSqlCommand (
    @databaseName sysname 
    , @sqlCommand nvarchar(max) 
) 
as 
begin; 
    set nocount on; 
    set xact_abort on; 

    declare @innerStatement nvarchar(max) = @sqlCommand; 
    declare @outerStatement nvarchar(max); 

    set @databaseName = QuoteName(ParseName(@databaseName, 1), N'['); 
    set @outerStatement = @databaseName + N'.sys.sp_executesql @stmt = @innerStatement;'; 

    execute sys.sp_executesql 
     @stmt = @outerStatement 
     , @params = N'@innerStatement nvarchar(max)' 
     , @innerStatement = @innerStatement; 
end; 

Использование очевидно:

execute dbo.usp_ExecuteSqlCommand 
    @databaseName = N'master' 
    , @sqlCommand = N'select Db_Name();'; 
+0

Очень элегантное решение. Ницца. – Jens