T-SQL Ninja #43

SP_RENAME

Was ist SP_RENAME?

Wenn ihr in eurer Datenbank Objekte habt, die ihr umbenennen möchtet, dann könnt ihr im SQL Server Management Studio mit Rechtsklick auf das Objekt eine Umbenennung durchführen. Wenn ihr das Umbenennen aber ein wenig kontrollierter und am besten noch verteilbar machen möchtet, dann kommt ihr um das Skripten des Vorgangs nicht herum und benötigt die Prozedur SP_RENAME nicht herum.

Wie könnt ihr SP_RENAME verwenden?

SP_RENAME benennt also vom Benutzer erzeugte Objekte um, das kann dabei nahezu jedes Objekt sein von der Datenbank über Tabellen und Indexe bis hin zum CLR-Typen (vorausgesetzt ihr besitzt ALTER-Rechte für die Objekte). Die Verwendung von SP_RENAME ist dabei recht einfach, doch Vorsicht, wenn ihr die folgenden Beispiele ausführt, könnt ihr damit eure Datenbanken nachhaltig zerstören, also wie immer im Dojo, bitte verwendet eine unkritische Spiel-Datenbank, bei der es nichts macht, wenn die eine oder andere View nicht mehr funktioniert. Wir verwenden die WideWorldImporters-Datenbank im Docker-Container. Der einfachste Aufruf ist, zunächst einmal die WideWorldImporters-Datenbank umzubenennen:

EXEC sp_rename 'WideWorldImporters', 'WWI', 'Database'

Ihr seht, dass SP_RENAME drei Argumente bekommt, den Namen des ursprünglichen Objekts (in unserem Fall „WideWorldImporters“), den neuen Namen für das Objekt (in unserem Fall „WWI“) und um was für ein Objekt es sich handelt. Der dritte Parameter wird weggelassen, wenn ihr Tabellen umbenennt, sonst müsst ihr immer angeben, was für ein Objekt ihr hier umbenennt.

Wechseln wir nun in unsere neu benannte Datenbank und benennen wir eine Tabelle um:

USE WWI;
EXEC sp_rename 'Purchasing.PurchaseOrderLines', 'POL'

Was ihr im Resultat beobachten könnt ist, dass die neue POL-Tabelle auch im Purchasing-Schema liegt. Wenn ihr aber versucht, das Schema beim ersten Argument, also der Tabelle, die umbenannt werden soll, wegzulassen, erhaltet ihr einen Fehler:

EXEC sp_rename 'POL', 'OrderLine'

No item by the name of 'POL' could be found in the current database 'WWI'.

Hier muss also das Schema angegeben werden, damit die Tabelle gefunden wird. Doch was passiert, wenn wir auch für das Zielobjekt das Schema mit angeben? Probieren wir es aus:

EXEC sp_rename 'Purchasing.POL', 'Purchasing.OrderLine'

Das Resultat ist, dass im Schema „Purchasing“ nun eine Tabelle mit dem Namen „Purchasing.OrderLine“ existiert, diese Müssten wir also, da der Tabellenname mit dem Punkt ein Sonderzeichen enthält, wie folgt abfragen:

SELECT TOP(10)
    PurchaseOrderLineID 
FROM Purchasing.[Purchasing.OrderLine]

Warum ist das so? Weil das ändern des Schemas kein Umbenennen der Tabelle ist, sondern eine Operation auf dem Schema. Wollen wir die Tabelle in ein neues Schema verschieben, so verwenden wir dafür ein ALTER SCHEMA ADD.

Benennen wir die Tabelle nun also erst einmal wieder vernünftig:

EXEC sp_rename 'Purchasing.[Purchasing.OrderLine]', 'OrderLine'

Sehen wir uns nun die Tabelle an, sie hat einen Primärschlüssel und einen dazugehörigen geclusterten Index mit dem Namen „PK_Purchasing_PurchaseOrderLines“ den wollen wir nun an den neuen Tabellennamen anpassen, benennen wir also den Index um:

EXEC sp_rename 
     'Purchasing.OrderLine.PK_Purchasing_PurchaseOrderLines'
    ,'PK_Purchasing_OrderLines'
    ,'Index'

Wenn ihr nun die Tabelle anseht, stellt ihr fest, dass SP_RENAME nicht nur den Index sondern auch die zugehörige Primärschlüssel-Constraint umbenannt hat. Das heißt, SP_RENAME hat hier dafür gesorgt, dass auch gleich „Ordnung“ in eurer Datenbank herrscht. Und auch die Statistiken hat SP_RENAME freundlicherweise gleich für euch angepasst.

Wie ist das, wenn wir es anders herum versuchen? Benennen wir also mal eine Statistik um, die zu einem Index und einem Fremdschlüssel gehört:

EXEC sp_rename
     'Purchasing.OrderLine.FK_Purchasing_PurchaseOrderLines_PackageTypeID'
    ,'FK_Purchasing_OrderLines_PackageTypeID'
    ,'Statistics'

In diesem Fall wurde der mit der Statistik verbundene Index auch gleich mit umbenannt, die Fremdschlüsselbeziehung allerdings nicht.

Und was passiert, wenn wir eine Spalte umbenennen mit den Indexen und Fremdschlüsselbeziehungen, in denen sie vorkommt? Probieren wir es aus:

EXEC sp_rename
     'Purchasing.OrderLine.PurchaseOrderLineID'
    ,'OrderLineID'
    ,'Column'

Wenn wir uns nun den Primärschlüssel oder den geclusterten Index ansehen, stellen wir fest, dass auch hier der korrekte neue Spaltenname übernommen wurde. Um zu prüfen, ob das auch bei Fremdschlüssel-Beziehungen funktioniert, benennen wir ein Objekt um, auf das die OrderLine referenziert:

EXEC sp_rename
     'Purchasing.PurchaseOrders.PurchaseOrderID'
    ,'OrderID'
    ,'Column'

Sehen wir uns nun die OrderLines-Tabelle an, dann sehen wir, dass die Fremdschlüsselbeziehung, die auf die Order verweist korrekterweise angepasst wurde:

ALTER TABLE [Purchasing].[OrderLine]  WITH CHECK 
ADD CONSTRAINT [FK_Purchasing_PurchaseOrderLines_PurchaseOrderID_Purchasing_PurchaseOrders]
FOREIGN KEY([PurchaseOrderID])
REFERENCES [Purchasing].[PurchaseOrders] ([OrderID])

Was ihr heute hoffentlich gelernt habt ist, dass es zwar wünschenswert wäre, ein Refactoring eurer Datenbank von vorne herein auszuschließen, das wäre aber leider überhaupt nicht realistisch. Wenn es also zum Refactoring kommt, dann ist die SP_RENAME Prozedur ein willkommenes Hilfsmittel, das an vielen Stellen einiges übernimmt, um dafür zu sorgen, dass ihr mit eurer Umbenennung zumindest nicht in einen Zustand lauft, wo eure Datenbank grundlegend defekt ist (Fremdschlüssel, die ins leere laufen und dadurch die referenzielle Integrität der Datenbank bedrohen). Trotzdem kann natürlich auch SP_RENAME nicht alles: für die Korrektheit eurer Anwendungen, Views, Skripte und Prozeduren müsst ihr nach dem Umbenennen immer noch selber sorgen. Seid also vorsichtig beim Umbenennen!

Referenzen

Ninja-Notebooks @ GitHub

Ein Gedanke zu „SP_RENAME

  1. Moin Ninjas,

    ggf als weiteren Tipp bzgl. sp_rename und das Views, Procs etc nicht angepasst werden: So einen Refactor am Bestern über die entsprechende Funktion im DB Projekt von VS Studio (wenn man denn dieses verwendet) nutzen. Dann hat man auch die Referenzprüfung und mein eigentlicher Code wird mit angepasst.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.