Utwórz widok w określonej bazie danych z dynamicznym SQL?

16

Piszę dynamiczny SQL, aby upuścić i utworzyć widok w innej bazie danych.

Więc napisałem:

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

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

Daje mi błąd:

„UTWÓRZ WIDOK” musi być pierwszą instrukcją w partii zapytania.

Jeśli usunę instrukcję USE DATABASE, będzie działać poprawnie, ale baza danych nie będzie już podawana ...

Jak mogę rozwiązać ten problem?

King Chan
źródło

Odpowiedzi:

25

Możesz używać EXECpołączeń zagnieżdżonych . Kontekst bazy danych zmieniony przez USEtrwa do wsadu potomnego.

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
źródło
1
+1 - Jeśli tworzysz scenariusze za pomocą SMO, tak samo robi to framework - definicje są wykonywane w dynamicznym SQL, aby obejść to ograniczenie
JNK
1
@KingChan - możesz zarówno głosować, jak i akceptować, FYI;)
JNK
@JNK +1 oczywiście ~ :)
King Chan
zdecydowanie działało !! chociaż go użyłem, z wieloma zmiennymi w zapytaniu zagnieżdżonym, więc byłem kłopotliwy z powodu obsługi cytatów! świetne rozwiązanie!
Jesteś bohaterem. Nazwie po tobie moje pierworodne dziecko.
Jens
-1

Jednym ze sposobów, które poradziłem sobie, gdy wpadłem na tę skrzynkę, jest umieszczenie instrukcji GO po użyciu.

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

  SELECT ........something'
exec (@CreateViewStatement)
sgojgini
źródło
Po prostu wiesz, że statystyka GO nie będzie działać w exec
King Chan
2
To nie zadziała w kontekście dynamicznego SQL. GOjest ogranicznikiem wsadowym w narzędziach klienta, a nie słowem kluczowym TSQL.
Martin Smith