{"id":426,"date":"2007-01-22T21:44:41","date_gmt":"2007-01-22T20:44:41","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/2007\/01\/22\/sql-talk\/sql-server-eigene-system-prozeduren"},"modified":"2007-01-22T21:44:41","modified_gmt":"2007-01-22T20:44:41","slug":"sql-server-eigene-system-prozeduren","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2007\/01\/22\/sql-talk\/sql-server-eigene-system-prozeduren","title":{"rendered":"SQL-Server: eigene System-Prozeduren"},"content":{"rendered":"<p>Im Artikel &quot;<a href=\"http:\/\/weblogs.sqlteam.com\/mladenp\/archive\/2007\/01\/18\/58287.aspx\">Running a master db residing stored procedure in current database context<\/a>&quot; beschreibt Mladen Prajdicand, wie man aus einer normalen Prozedur in der Master-Datenbank eine System-Prozedur machen kann. Das hat den Vorteil, dass sie aus jedem Datenbank-Kontext aus aufgerufen werden kann. Sie liest dabei immer die Informationen aus den Verwaltungstabellen der jeweiligen Datenbank. Er beschreibt dazu zwei Voraussetzungen, die am SQL Server 2005 notwendig sind:<\/p>\n<ul>\n<li>Die Prozedur beginnt mit &quot;sp_&quot; und <\/li>\n<li>sie wurde als Systemprozedur gekennzeichnet.<\/li>\n<\/ul>\n<p>Letzteres geht am SQL-Server-2005 mit &quot;EXEC sp_MS_marksystemobject <SP-Name>&quot;, ist aber nicht immer unbedingt notwendig, dazu sp&#228;ter mehr. Ich gebe zun&#228;chst mal ein Beispiel, damit klar wird, was gemeint ist:<\/p>\n<p>Wenn man zwei Tabellen gleichnamige anlegt, eine in der einen Datenbank, die andere in einer anderen, z.B. eine in der Master und die andere in der Nordwind, dann kann man beide Tabellen mit der gleichen Prozedur abfragen. <\/p>\n<p><code lang=\"sql\">-- Tabelle YouAreIn in Master anlegen und mit \"Master\" f&#252;llen<br \/>\ncreate table master.dbo.YouAreIn (dbname sysname not null);<br \/>\ninsert into master.dbo.YouAreIn (dbname) values (&#x0027;Master&#x0027;);<\/p>\n<p>&#8211; Tabelle YouAreIn in Nordwind anlegen und mit &quot;Northwind&quot; f&#252;llen<br \/>\ncreate table Northwind.dbo.YouAreIn (dbname sysname not null);<br \/>\ninsert into Northwind.dbo.YouAreIn (dbname) values (&#x0027;Northwind&#x0027;);<br \/>\ngo<br \/>\nuse master<br \/>\ngo<br \/>\ncreate procedure dbo.sp_where_am_i<br \/>\nas<br \/>\n\tselect\tdbname<br \/>\n\tfrom YouAreIn &#8211; hier keine Datenbank angeben<br \/>\ngo<br \/>\n&#8211; Als Systemprozedur markieren<br \/>\nEXEC sp_MS_marksystemobject &#x0027;sp_where_am_i&#x0027;<\/code><\/p>\n<p>Jetzt kann man in unterschiedlichen Datenbank-Kontexten die Prozedure aufrufen und es wird automatisch die &quot;richtige&quot; Tabelle gelesen:<br \/>\n<code lang=\"sql\"><br \/>\nuse master<br \/>\nexec sp_where_am_i<\/code><\/p>\n<p>Das liefert als Ergebnis &quot;Master&quot;. W&#228;hrend das untige Statement &quot;Northwind&quot; meldet:<\/p>\n<p><code lang=\"sql\">use Northwind<br \/>\nexec sp_where_am_i<\/code><\/p>\n<p>Spa&#223;igerweise haben die Systemprozeduren noch einen Insider-Hack: Wenn man den Datenbanknamen vor die Systemprozedur stellt, dann wird sie in dem Kontext ausgef&#252;hrt:<br \/>\n<code lang=\"sql\"><br \/>\nuse master<br \/>\nexec Northwind..sp_where_am_i<\/code><\/p>\n<p>Das liefert &quot;Northwind&quot;!<\/p>\n<p><strong>Keine Regel ohne Ausnahme&#8230;<\/strong><\/p>\n<p>Um abw&#228;rtskompatibel zu sein, gibt es auch hier eine Ausnahme&#8230; Auch ohne das Markieren als systemprozedur wird die Prozedur im Kontext der Datenbank ausgef&#252;hrt. Die Bindung zu den Tabellen bleibt aber zu den Tabellen in der Master bestehen.<\/p>\n<p>Beispielsweise liefert die folgende Prozedur (in der Master angelegt, nicht als Systemprozedur gekennzeichnet) immer den &quot;richtigen&quot; Datenbank-Kontext und immer den Inhalt der Tabelle aus der Master.<\/p>\n<p><code lang=\"sql\">create procedure sp_where_am_i_zwei<br \/>\nas<br \/>\n\tselect\tdb_name() as [DB-Kontext],<br \/>\n\t\t\tdbname as [Tabelle-Aus]<br \/>\n\tfrom YouAreIn<\/code><\/p>\n<p>Aber es gibt noch eine weitere Ausnahme: Wenn man lediglich vor hat aus den &quot;alten&quot; Systemtabelle, wie sysobjects, zu lesen, dann verh&#228;lt sich die Prozedur, wie ganz oben beschrieben. Wenn man aber aus den &quot;Neuen&quot; liest, wie bspw. &quot;sys.objects&quot;, dann muss sie &quot;markiert&quot; werden, um das Ziel zu erreichen&#8230;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Artikel &quot;Running a master db residing stored procedure in current database context&quot; beschreibt Mladen Prajdicand, wie man aus einer normalen Prozedur in der Master-Datenbank eine System-Prozedur machen kann. Das hat den Vorteil, dass sie aus jedem Datenbank-Kontext aus aufgerufen werden kann. Sie liest dabei immer die Informationen aus den Verwaltungstabellen der jeweiligen Datenbank. Er [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/426"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=426"}],"version-history":[{"count":0,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}