Sonntag, 4. oktober 2009 7 04 /10 /2009 15:41

Der vorherige Blog Eintrag befasste sich mit dem Nachbau von "Create Or Alter" in MS_Sql-Server.
Da bei jener Lösung wird versucht, den Namen des Schema und den Namen des Objektes aus dem Statement zu parsen, was jedoch nur gelingt wenn das Statement einigermaßen vernünftig formatiert wird.
Der nun zweite Vorschlag umgeht das Probelm, indem drei weitere Parameter eingeführt werden, in denen der Name des Schema, der Name des Typen des Datenbankobjektes und der Name des Objektes angegeben werden muß. Dafür dürfen diese Angaben im SQL-Statement nicht mehr enthalten sein.

Im Kommentar am Anfang des Prozedur-textes werden verschiedene Kommentarkategorien in XML-Tags gesetzt, welche anschließend beim Beisepiel aus dem Quelltext der Prozedur kopiert weren, mit XML-Query analysiert werden und aausgeben, bzw. ausgeführt werden.

 

USE master;
IF ( SELECT OBJECT_ID ('dbo.sp_CreateOrAlter', 'P') ) IS NOT NULL
DROP PROCEDURE dbo.sp_CreateOrAlter;
GO
/*=======================================================================================
<Created> 26.09.2009 by Eberhard Meisel 2009 by Eberhard Meisel All rights preserved"
</Created>
<Idea> 25.09.2009 by Olaf Helper: http://olafhelper.over-blog.de/article-36504172.html
</Idea>
<Purpose> Create or Alter an T-SQL-Database-Object in dependency of its existence.
</Purpose>
<Remarks> Procedure is created in the master database with prefix "sp_", so that it
can be called from every other database on the server.
So you must have the right to create database-objects in the master database.
</Remarks>
<Changelog> -- 0001 03.10.2009 ENH EM Adding Documentation, Changelog and Example in XML -- 0000 26.09.2009 ADD EM created
</Changelog>
<Example> -- Example for dbo.sp_CreateOrAlter
BEGIN TRANSACTION; SET NOCOUNT ON;
DECLARE @Debug BIT; Set @Debug = 1;
USE AdventureWorks ;
SELECT * FROM Sys.Objects WHERE Name = 'spTestSp';
   EXEC sp_CreateOrAlter 
@Schema = dbo
, @Object = spTestSp
, @Type = [PROCEDURE]
, @Sql =
N' ( @AddressID INTEGER = NULL
) AS
BEGIN; SELECT *
FROM Person.Address WHERE AddressID = @AddressID
OR @AddressID IS NULL; RETURN; END; -- EOF PROCEDURE dbo.spTestSp ' , @Dbg = @Debug ;
SELECT * FROM Sys.Objects WHERE Name = 'spTestSp'; EXEC dbo.spTestSp;
ROLLBACK TRANSACTION;
</Example> -- Example dbo.sp_CreateOrAlter */ --======================================================================================
BEGIN; SET NOCOUNT ON;
DECLARE @SchemaObject NVARCHAR(257);
SET @SchemaObject = PARSENAME (@Schema, 1) + NCHAR(46) + PARSENAME (@Object,1);
-- in dependency of existence of the object CREATE or ALTER the object
SET @Sql = CASE WHEN ( SELECT OBJECT_ID (@SchemaObject) ) IS NULL
THEN N'CREATE ' ELSE N'ALTER '
END + @Type +SPACE(1)+ @SchemaObject +SPACE(1)+NCHAR(10)+NCHAR(13)+ @Sql;
IF @Dbg != 0 -- Debug ouptut when Parameter @Dbg is not 0
SELECT CAST ( (SELECT N'ObjectName = ' + QUOTENAME(@SchemaObject)
+ NCHAR(13)+NCHAR(13) + @Sql FOR XML PATH ('')
) AS XML) AS [Debug (sp_CreateOrAlter)];
EXEC sp_executeSQL @Statement = @SQL; -- Execute the statement
END; -- EOF PROCEDURE sp_CreateOrAlter
GO


SET NOCOUNT ON;
DECLARE @Procid INTEGER; SET @Procid = OBJECT_ID ('master..sp_CreateOrAlter')
DECLARE @Comments TABLE
( Created NVARCHAR(128)
, Idea NVARCHAR(333)
, Purpose NVARCHAR(4000)
, Remarks NVARCHAR(4000)
, Example NVARCHAR(MAX)
, Changelog NVARCHAR(MAX)
);
DECLARE @Comment XML ;
SET @Comment =
( SELECT CAST (N'<Comments>' + Z.Comment + N'</Comments>' AS XML) AS Comment
FROM (SELECT CASE WHEN x.Start > 0
THEN SUBSTRING (x.Def, x.Start, x.[End]-X.Start)
ELSE 'No Comments found'
END AS Comment
FROM ( SELECT y.Def
, CHARINDEX (Y.STag, y.Def, 1) AS Start
, CHARINDEX (Y.ETag, y.Def, 1) + LEN (Y.ETag) AS [End]
FROM (SELECT OBJECT_Definition (@ProcID) AS Def
, N'<Created>' AS STag
, N'</Example>' AS ETag
) AS Y
) AS X
) AS Z
);
SELECT @Comment;
INSERT INTO @Comments
SELECT x.value(N'Created[1]' , N'NVARCHAR(128)') AS Created
, x.value(N'Idea[1]' , N'NVARCHAR(333)') AS Idea
, x.value(N'Purpose[1]' , N'NVARCHAR(4000)') AS Purpose
, x.value(N'Remarks[1]' , N'NVARCHAR(4000)') AS Remarks
, x.value(N'Example[1]' , N'NVARCHAR(MAX)') AS Example
, x.value(N'Changelog[1]' , N'NVARCHAR(MAX)') AS Changelog
FROM @Comment.nodes('//Comments') n(x);

DECLARE
@Line SYSNAME ; SET @Line = REPLICATE (NCHAR(45), 100);
DECLARE @Test NVARCHAR(MAX);
SET @Test = @Line +NCHAR(13)
+ (SELECT N'-- Created: ' + Created FROM @Comments)+ + (SELECT N'-- Idea : ' + Idea FROM @Comments)+
+ (SELECT N'-- Purpose: ' + Purpose FROM @Comments)+
+ (SELECT N'-- Remarks: ' + REPLACE (SUBSTRING(Remarks, 1, LEN(Remarks)-1)
,NCHAR(10),NCHAR(13)+NCHAR(45)+NCHAR(45))
+ NCHAR(13) FROM @Comments)
+ @Line +NCHAR(13)
+ (SELECT Changelog FROM @Comments)+@Line;
PRINT @Test ;
SET @Test = REPLACE (REPLACE ( (SELECT Example FROM @Comments)
, NCHAR(10) , NCHAR(13))
,NCHAR(13)+NCHAR(13), NCHAR(13));
PRINT @Test;
EXEC sp_ExecuteSQL @Test;
GO

von Ebis - veröffentlicht in: MS-SQL - Community: SQL Scripter
Kommentar hinzufügen - Kommentare () - empfehlen
Samstag, 26. september 2009 6 26 /09 /2009 19:45

Olaf Helper beschreibt in  seinem  Blog unter „Create Or Alter“ für MS SQL Server eine Idee, um das in T-SQL fehlende aber aus anderen DBMS bekannte "Create or Altrer"-Konstrukt zu ersetzen...

Hier ist mein Vorschlag dafür:

CREATE PROCEDURE dbo.sp_CreateOrAlter
    ( @Sql NVARCHAR(MAX)
   , @Dbg TINYINT = 0
   ) AS
--==================================================================================
-- Created: 26.09.2009 by Eberhard Meisel
-- Idea : http://olafhelper.over-blog.de/article-36504172.html
-- Purpose: Create or Alter an T-SQL-Database-Object in dependency of its existence.
-- Remarks: Procedure is created in the master database with prefix "sp_", so that
-- the procedure can be called from every other
database on the server.
------------------------------------------------------------------------------------
-- 0001 - 26.09.2009 - ADD - created
------------------------------------------------------------------------------------
/* -- Example for dbo.sp_CreateOrAlter
BEGIN TRANSACTION; SET NOCOUNT ON;
USE AdventureWorks ;

DECLARE @Debug BIT; Set @Debug = 1;
SELECT * FROM Sys.Objects WHERE Name = 'spTestSp';
EXEC sp_CreateOrAlter
@Dbg = @Debug
, @Sql =
N'CREATE PROCEDURE dbo.spTestSp
( @AddressID INTEGER = NULL
) AS
BEGIN;
SELECT *
FROM Person.Address
WHERE AddressID = @AddressID OR
@AddressID IS NULL;
RETURN;
END; -- EOF PROCEDURE dbo.spTestSp ' ;
   SELECT * FROM Sys.Objects WHERE Name = 'spTestSp';
EXEC dbo.spTestSp ;
ROLLBACK; 
*/ -- Example dbo.sp_CreateOrAlter
--==============================================================================
BEGIN ; SET NOCOUNT ON;
DECLARE @Name SYSNAME;
-- replace Tabs and LineFeeds
SET @Sql = REPLACE (REPLACE (@SQL, NCHAR(9), SPACE(3)), NCHAR(10), SPACE(0));
-- remove Create / Alter
SET @Sql = LTRIM (SUBSTRING (LTRIM(@Sql)
,
CHARINDEX (SPACE(1),LTRIM(@SQL),1)
,
128192000
) );
-- parsing ObjectName
SET @Name = (SELECT REPLACE (RTRIM (LTRIM (Y.Name)), NCHAR(13), SPACE(0))
FROM ( SELECT SUBSTRING(@Sql
,Start
,CHARINDEX(SPACE(1),@SQL,Start+1)- Start
) AS Name
FROM ( SELECT CHARINDEX (SPACE(1), @SQL, 1) AS Start
) AS X
) AS Y
);
-- in dependency of existence of the object CREATE or ALTER the object
SET @Sql = CASE WHEN ( SELECT OBJECT_ID (@Name) ) IS NULL
THEN N'CREATE '
ELSE N'ALTER '
END + @Sql ;
IF @Dbg != 0
-- output when Parameter @Dbg is not 0 for controlling the Statement
SELECT CAST ( (SELECT N'ObjectName = '
+ QUOTENAME(@Name)
+ NCHAR(13)+NCHAR(13)
+ @Sql FOR XML PATH ('')
) AS XML
) AS Debug;

-- Execute the statement
EXEC sp_executeSQL @Statement = @SQL;
END;
von Ebis - veröffentlicht in: MS-SQL - Community: SQL Scripter
Kommentar hinzufügen - Kommentare () - empfehlen
Samstag, 26. september 2009 6 26 /09 /2009 19:30

Dies ist der erste Artikel in Ihrem Blog. Er wurde automatisch erstellt um Ihnen bei der Orientierung auf Overblog zu helfen. Sie können ihn anpassen oder ihn über den Bereich "Veröffentlichen" in Ihrem Admin-Bereich löschen.

Frohes Bloggen

Das Team von Overblog

PS.: Bitte besuchen Sie fürs Einloggen in den Admin-Bereich Ihres Blogs das Portal von Overblog.

von Eberhard Meisel
Kommentar hinzufügen - Kommentare () - empfehlen

Über diesen Blog

Blog erstellen

Kalender

Februar 2010
M D M D F S S
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
             
<< < > >>
Erstellen Sie einen Blog auf de.over-blog.com - Kontakt - Nutzungsbedingungen - Missbrauch melden