Overblog Folge diesem Blog
Edit post Administration Create my blog
Blog von Olaf Helper

„Create Or Alter“ für MS SQL Server

25. September 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

Bei Oracle und anderen DBMS gibt es die DDL Anweisung „Create Or Alter“ für Procedures, Functions und Views. Das ist praktisch, da man sich keine Gedanken machen muss, ob das Objekt schon vorhanden ist: Ist es vorhanden, wird es aktualisiert, sonst eben neu angelegt.

 

Im MS SQL Server gibt es so etwas leider nicht. Man behilft sich damit, dass man ein vorhandenes Objekt zunächst löscht (DROP) und dann wieder neu anlegt (CREATE). Das hat nur den großen Nachteil, dass alle vorhandenen Berechtigungen auch mit entfernt werden.

 

Dann gibt es noch zwei Möglichkeiten

-          Man pflegt die Berechtigungen im DROP/CREATE Script immer mit, was bei bei regelmäßigen Änderungen einen entsprechenden zusätzlichen Aufwand darstellt; und damit fehleranfällig. 

-          Man erstellt bei Design-Änderungen ein zusätzliches ALTER Script, nur wenn man eine neue Datenbank anlegt muss man daran denken, erst das CREATE und dann das ALTER Script auszuführen.

Beides nicht gerade komfortable und auch etwas fehlerträchtig.

 

Um „Create Or Alter“ nun doch noch abbilden zu können, habe ich mir folgendes überlegt

-          Wenn Objekt nicht vorhanden, dann mit „leerem“ Inhalt anlegen

-          Anschließend ein ALTER mit dem eigentlichen Design ausführen.

Dabei gibt es aber wieder ein kleines Problem, den die CREATE Anweisung muss die erste in einem Batch sein und somit kann man vorab nicht prüfen, ob das gewünschte Objekt bereits besteht. Aber das ist eben nur ein kleines Problem, dann legen über sp_executesqlmit einem SQL Script als Text an.

 

Beispiel:

 USE [AdventureWorks] 
 GO 
   
 IF OBJECT_ID('dbo.spTestSp', 'P ') IS NULL 
  EXEC sp_executesql N'CREATE PROCEDURE dbo.spTestSp AS SET NOCOUNT ON;' 
 GO 
   
 ALTER PROCEDURE dbo.spTestSp 
  @AddressID int 
 AS 
  SELECT * 
  FROM Person.Address 
  WHERE AddressID = @AddressID; 

 

Kein wirklicher Ersatz, aber mit T-SQL geht es halt nicht besser; zumindest nicht, das ich wüsste.

 

Diesen Post teilen

Repost 0

Kommentiere diesen Post

Ebis 10/02/2009 12:35


Hi Olaf,

klar, mein Vorschlag kommt nicht ohne Code-Einschränkungen aus...

Und CREATE-Statements für TABLE, INDEX, XML-Schema-Collections usw... muss man das dann eh weiterentwickeln..

Grüße Ebi


Ebis 09/26/2009 20:30


Hi Olaf,

Mein Vorschlag für sp_CreateORAlter siehe unter folgendem Link http://ebissql.over-blog.de/article-36554142.html

Grüße Ebi


Olaf Helper 09/27/2009 12:48


Hallo Ebis,

die Idee, das DDL Statement dynamisch anzupassenje nach dem, ob das Objekt vorhanden ist oder nicht, finde ich gut.
Allerdings finde ich es auch etwas schwierige & problematisch, das Statement selbst zu parsen und dann richtig abzuändern. Voraussetzung ist, das als erstes das CREATE kommt, und erst später
eine Kommentar bzw. die anderen Anwesiungen.
Der Testaufruf unten funktioniert schon mal nicht, weil es mit einem "dummen" Kommentar anfängt.

Eine Möglichkeit wäre auch noch, es in eine CLR Assemby auszulagern und dort die SqlParser.DLL (http://olafhelper.over-blog.de/article-34700638.html) zu verwenden, das erste Create rauszusuchen, es durch ALTER zu ersetzen und sich das
komplette Statement ausgeben & ausführen zu lassen.


EXEC


 


tempdb.dbo.sp_CreateOrAlter
     '-- Create Procedure for a Test
     CREATE PROCEDURE dbo.Test AS sp_CreateOrAlter
     '     ,1