Criar vista no banco de dados especificado com sql dinâmico?

16

Estou escrevendo um sql dinâmico para soltar e criar vista em banco de dados diferente.

Então eu escrevi:

set @CreateViewStatement = 
                '
                USE ['+ @DB +'];
                CREATE VIEW [dbo].[MyTable]
                AS

                SELECT ........something
exec (@CreateViewStatement)

Isso me dá erro:

'CREATE VIEW' deve ser a primeira instrução em um lote de consulta.

Se eu remover a instrução USE DATABASE, ela funcionará bem, mas o banco de dados não será mais especificado ....

Como posso resolver este problema?

King Chan
fonte

Respostas:

25

Você pode usar EXECchamadas aninhadas . O contexto do banco de dados alterado pelo USEpersistente para o lote filho.

DECLARE @DB SYSNAME

SET @DB = 'tempdb'

DECLARE @CreateViewStatement NVARCHAR(MAX) 
SET @CreateViewStatement = '
      USE '+ QUOTENAME(@DB) +';
      EXEC(''
             CREATE VIEW [dbo].[MyTable] AS
             SELECT 1 AS [Foo]
      '')

                          '
EXEC (@CreateViewStatement)
Martin Smith
fonte
11
1 - Se você roteiro fora exibições usando SMO é assim que o quadro não é tão bem - definições são executadas em SQL dinâmica para contornar a restrição
JNK
11
@KingChan - você pode votar e aceitar, FYI;)
JNK
@JNK +1 of course ~ :)
King Chan
definitivamente funcionou !! embora eu o tenha usado, com muitas variáveis ​​dentro da consulta aninhada, então eu estava com dor de cabeça porque o tratamento de cotações! ótima solução!
Você é um herói. Vou nomear meu primeiro filho depois de você.
Jens
-1

Uma maneira de lidar com esse caso é colocar a instrução GO after use.

set @CreateViewStatement = 
'
  USE ['+ @DB +']; GO
  CREATE VIEW [dbo].[MyTable]
  AS

  SELECT ........something'
exec (@CreateViewStatement)
sgojgini
fonte
Só para você saber, GO statment não será executado em exec
Rei Chan
2
Isso não funcionará no contexto de SQL dinâmico. GOé um delimitador de lote nas ferramentas do cliente, não uma palavra-chave TSQL.
Martin Smith