2012-05-16 9 views
21

Zdaję sobie sprawę, że jest to bardzo podobne pytanie do Stop SSMS from scripting SPs using sp_executesql?Jak zatrzymać SSMS 2012 z SP skryptów przy użyciu sp_executesql

Jednak wydaje się, że zmienił zachowanie z SSMS 2012.

Jeśli masz „Sprawdź dla opcji istnienia”wybrany, na przykład:

enter image description here

... to teraz generuje IF NOT EXISTS do proc, który ma być utworzony, także jako I F istnieje dla poprzedniego rozwijanej proc, jeśli, jak zwykle zrobić, to wybrać spadku i STWÓRZ opcję:

enter image description here

To zmusza go do skryptu CREATE użyciu sp_executesql. To nie ma sensu, ponieważ nie potrzebujesz testu IF NOT EXISTS na CREATE, jeśli Drop został właśnie upuszczony.

Nie wydaje się możliwe posiadanie jednego bez drugiego.

Wszelkie pomysły?

Odpowiedz

8

Nie można tego zrobić bez dynamicznego SQL, ponieważ procedura składowana musi być we własnej partii. Dlatego nie można powiedzieć:

IF <some condition> 
    <start a new batch> 

Jedynym sposobem, aby zachować to w tej samej partii jest użycie sp_executesql.

Jeśli zamierzasz jednocześnie skryptować DROP i CREATE, po prostu rób to bez sprawdzania istnienia obiektu. To daje:

DROP PROCEDURE ...; 
GO 
CREATE PROCEDURE ...; 
GO 

Kogo to obchodzi, jeśli DROP się nie powiedzie? (Nie powinien, bo po prostu z niego scenariusza!)

Jeśli skryptów to dla innego systemu, który potęga mieć obiektu, otrzymasz komunikat o błędzie dla DROP kiedy nie , ale CREATE nadal będzie działał, więc możesz zignorować błędy DROP. Jeśli naprawdę chcesz, możesz ręcznie zawijać instrukcje DROP w TRY/CATCH, ale nie sądzę, że jest to konieczne.

Jeśli potrzebujesz tego do wielu procedur lub naprawdę potrzebujesz procesu, aby nie generować łagodnych błędów, sugeruję, abyś zrezygnował z pierwotnych opcji skryptu Management Studio i użył do tego narzędzia innego producenta. Oni już poradzili sobie z wieloma problemami, z którymi jeszcze się nie spotkałeś, ale będą. I napisał o tym:

http://bertrandaaron.wordpress.com/2012/04/20/re-blog-the-cost-of-reinventing-the-wheel/

+0

Dzięki za to - podejrzewałem tak samo. To, czego naprawdę chcę, to opcja zarówno dla IF EXISTS, jak i IF NOT EXISTS. Mogę teraz zignorować błąd DROP, ale te skrypty są uruchamiane przez automatyczny proces iw pewnym momencie będę musiał przeanalizować logi skryptów, aby sprawdzić błędy. Wydaje się, że po tej zmianie wykonali jeden z kroków wstecz. – ChrisA

+0

Zaktualizowali treść (co może być częściowo moją winą). Zobacz http://connect.microsoft.com/SQLServer/feedback/details/624075/include-if-not-exists-clause-impacts-drop-scripting http://connect.microsoft.com/SQLServer/feedback/details/ 242799/ssms-sure-scripting-options-yield-dynamic-sql i https://connect.microsoft.com/SQLServer/feedback/details/242795/ssms-certain-scripting-options-do-notwork-for- zmodyfikuj –

+3

Tak, nie przejmuję się tym sformułowaniem. Chodzi o to, że jeśli chcę IF IF EXISTS (aby zapobiec błędowi DROP), jestem zmuszony również mieć IF NOT EXISTS w utworze, co z kolei zmusza kreację do argumentu sp_executesql, którą również nie chcę - ponieważ każda nieumyślna literówka nie spowoduje oczywistych błędów. To było w porządku wcześniej - IF EXISTS było tam domyślnie i nie miałem włączonego IF NOT EXISTS. W * nie * posiadanie opcji IF EXISTS jest osobną opcją, dla mnie jest teraz gorsze niż w przypadku SQL08. – ChrisA

5

najbliżej można dostać się do tej funkcji jest iść pod Narzędzia, Opcje, SQL Server Object Explorer, skrypty, a następnie ustawić kontrolę dla obiektu istniejącego na false.

Wadą jest to, że jeśli to zrobisz, wtedy spadnie i tworzy zawsze będzie próbować upuścić nawet jeśli obiekt nie istnieje. Idealnym rozwiązaniem byłoby ustawienie, które pozwoliłoby skryptowi wyglądać jak na poniższym przykładzie tworzenia widoków, procedur i funkcji zdefiniowanych przez użytkownika.

/****** Object: View [dbo].[vEmployees] Script Date: 9/14/2012 9:18:57 AM ******/ 
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vEmployees]')) 
DROP VIEW [dbo].[vEmployees] 
GO 

CREATE VIEW [dbo].[vEmployees] 
AS 
    SELECT DISTINCT 
     Employees.EmployeeID, 
     FirstName, 
     LastName 
    from 
     Employees 
      JOIN Sales on Employees.EmployeeID=Sales.EmployeeID 
GO 

W skrócie, jeżeli silnik skryptowy myśli o spadku i tworzyć razem w sprawdzanie istnienia obiektu to nie trzeba postawić warunek na tworzenie.

0

Ja także zmagałem się z tym samym problemem. Jeśli potrzebujesz skryptować obiekty dla całej bazy danych, możesz rozważyć skrypt ApexSQL. Wypróbowałem kilka narzędzi, a ApexSQL scryptował obiekty dokładnie tak, jak potrzebowałem. (jeśli obiekt istnieje, a następnie upuść, utwórz obiekt). Wierzę, że działa również z linii poleceń. Uwaga, jest to shareware; Użyłem tylko wersji testowej, ponieważ potrzebowałem jej tylko garść razy.

Poniżej znajduje się przykładowy wynik dla procedury po jakiejś konfiguracji.

IF (EXISTS(SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[myProcedure]') AND [type]='P')) 
DROP PROCEDURE [dbo].[myProcedure] 
GO 

SET ANSI_NULLS ON 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE PROCEDURE dbo.myProcedure 
AS 
    select 1 as a 
GO 
1

Znalazłem dobre rozwiązanie tego problemu. Podczas wykonywania skryptów musisz wykonać "dwa podania". Podczas pierwszego przejścia wybierz opcje, aby sprawdzić istnienie i tylko skrypt DROP. Następnie w drugim przejściu usuń zaznaczenie opcji Sprawdź istnienie i wybierz skrypt CREATE. Ponadto użyj opcji Dołącz do pliku. Następnie, uruchamiając generowanie skryptów w drugim przebiegu, odznacz opcję "Zastąp plik". Będzie działać tylko wtedy, gdy generujesz osobny plik dla każdego obiektu.

0

Wreszcie po wyszukaniu wiele artykułów i znaleźć rozwiązanie, które

należy dokonać „dwa karnety” gdy scripting. Podczas pierwszym przejeździe,

  • wybrać opcje, aby sprawdzić dla istnienia i tylko skryptu kropli.
  • Następnie, na drugim przejściu, de-select, opcja Sprawdź istnienie i wybierz skrypt CREATE.
    • Dodatkowo użyj opcji Append To File. Następnie podczas uruchamiania generowania skryptów na drugim przebiegu , odznacz opcję "Overwrite File". Będzie działać tylko wtedy, gdy generujesz osobny plik dla każdego obiektu.
+0

To jest identyczna z poprzednią odpowiedzią – Pedro

Powiązane problemy