Ich muss eine lokale SQL Server 2017-Datenbank auf eine Azure SQL-Datenbank migrieren und stehe vor einigen Herausforderungen, da einige Einschränkungen zu beachten sind.
Insbesondere, da eine Azure SQL-Datenbank nur in UTC-Zeit (keine Zeitzonen) funktioniert und wir die Ortszeit benötigen, müssen wir die Verwendung von GETDATE()
überall in der Datenbank ändern , was sich als arbeitsintensiver herausgestellt hat, als ich erwartet hatte.
Ich habe eine benutzerdefinierte Funktion erstellt, um die Ortszeit zu ermitteln, die für meine Zeitzone korrekt funktioniert:
CREATE FUNCTION [dbo].[getlocaldate]()
RETURNS datetime
AS
BEGIN
DECLARE @D datetimeoffset;
SET @D = CONVERT(datetimeoffset, SYSDATETIMEOFFSET()) AT TIME ZONE 'Pacific SA Standard Time';
RETURN(CONVERT(datetime,@D));
END
Das Problem, mit dem ich Probleme habe, besteht darin, GETDATE()
diese Funktion in jeder Ansicht, gespeicherten Prozedur, berechneten Spalten, Standardwerten, anderen Einschränkungen usw. zu ändern .
Was wäre der beste Weg, um diese Änderung umzusetzen?
Wir befinden uns in der öffentlichen Vorschau von verwalteten Instanzen . Es hat immer noch das gleiche Problem GETDATE()
, daher hilft es bei diesem Problem nicht. Der Wechsel zu Azure ist eine Voraussetzung. Diese Datenbank wird immer in dieser Zeitzone verwendet (und wird auch verwendet).
Ich würde umgekehrt arbeiten. Konvertieren Sie alle Ihre Zeitstempel in der Datenbank in UTC, und verwenden Sie einfach UTC. Wenn Sie einen Zeitstempel in einem anderen tz benötigen, können Sie eine generierte Spalte erstellen, indem Sie
AT TIME ZONE
(wie oben beschrieben) den Zeitstempel in der angegebenen TZ (für die App) rendern. Aber ich würde ernsthaft in Betracht ziehen, nur UTC in die App zurückzubringen und diese Logik - die Anzeigelogik - in die App zu schreiben.quelle
Anstatt den Job zu exportieren, manuell zu bearbeiten und erneut auszuführen, können Sie den Job auch direkt in der Datenbank ausführen.
Natürlich auch um Funktionen, Trigger und so weiter zu erweitern.
Es gibt ein paar Einschränkungen:
Möglicherweise müssen Sie etwas heller sein und mit unterschiedlichen / zusätzlichen Leerzeichen zwischen
CREATE
undPROCEDURE
/VIEW
/ umgehen<other>
. AnstattREPLACE
deswegen könnten Sie es vorziehen, stattdessen denCREATE
Platz zu belassen und einenDROP
ersten auszuführen , aber dies birgt die Gefahr, dasssys.depends
Freunde außer Kontrolle geraten, woALTER
nicht, auch wenn diesALTER
fehlschlägt. Sie haben zumindest das vorhandene Objekt noch an Ort und Stelle, wo Sie mitDROP
+CREATE
können nicht.Wenn Ihr Code nach dem Modifizieren seines eigenen Schemas mit Ad-hoc-TSQL riecht, müssen Sie sicherstellen, dass das Suchen und Ersetzen von
CREATE
->ALTER
das nicht beeinträchtigt.Sie möchten nach der Operation die gesamte (n) Anwendung (en) einer Regression unterziehen, unabhängig davon, ob Sie den Cursor verwenden oder die Methoden Exportieren + Bearbeiten + Ausführen.
Ich habe diese Methode in der Vergangenheit verwendet, um ähnliche schemaweite Aktualisierungen vorzunehmen. Es ist ein bisschen hässlich und fühlt sich ziemlich hässlich an, aber manchmal ist es der einfachste / schnellste Weg.
Standardeinstellungen und andere Einschränkungen können auf ähnliche Weise geändert werden. Diese können jedoch nur gelöscht und neu erstellt werden, anstatt sie zu ändern. So etwas wie:
Noch ein bisschen mehr Spaß, mit dem Sie möglicherweise zu kämpfen haben: Wenn Sie nach Zeit partitionieren, müssen diese Teile möglicherweise ebenfalls geändert werden. Wenngleich eine genauere Partitionierung der Zeit als am Tag selten vorkommt, können Probleme auftreten, bei denen
DATETIME
die Partitionierungsfunktion je nach Zeitrahmen den vorherigen oder den nächsten Tag angibt, sodass die Partitionen nicht mit den üblichen Abfragen abgeglichen werden.quelle
sys
Schema gesucht und programmgesteuert geändert werden.CREATE OR ALTER PROCEDURE
hilft das Ersetzen durch z. B. bei Problemen mit der Codegenerierung. Es kann jedoch Probleme geben, da die gespeicherte DefinitionCREATE PROCEDURE
(drei! Leerzeichen) lautet und dies weder mitCREATE PROCEDURE
noch mitCREATE OR ALTER PROCEDURE
... übereinstimmt.CREATE
, die sich nicht in einem Kommentar befindet und diese ersetzt. Ich habe dies / ähnliches in der Vergangenheit nicht getan, aber ich habe den Funktionscode gerade nicht zum Posten zur Hand. Wenn Sie garantieren können, dass keiner Ihrer Objektdefinitionen Kommentare vorangestellt sindCREATE
, ignorieren Sie das Kommentarproblem und suchen und ersetzen Sie einfach die erste Instanz vonCREATE
.Ich mag Davids Antwort sehr und habe sie für eine programmatische Vorgehensweise empfohlen.
Sie können dies jedoch heute für einen Testlauf in Azure über SSMS versuchen:
Klicken Sie mit der rechten Maustaste auf Ihre Datenbank -> Aufgaben -> Skripte erstellen.
[Back Story] Wir hatten einen Junior-DBA, der alle unsere Testumgebungen auf SQL 2008 R2 aktualisiert hat, während sich unsere Produktionsumgebungen auf SQL 2008 befanden. Es ist eine Änderung, die mich bis heute erschreckt. Um vom Test in die Produktion zu migrieren, mussten wir Skripte in SQL mithilfe von Generierungsskripten generieren. In den erweiterten Optionen haben wir die Option "Zu skriptierender Datentyp: Schema und Daten" verwendet, um eine umfangreiche Textdatei zu generieren. Wir konnten unsere Test R2-Datenbanken erfolgreich auf unsere älteren SQL 2008-Server verlagern. Eine Datenbankwiederherstellung auf eine niedrigere Version hätte nicht funktioniert. Wir haben sqlcmd verwendet, um die große Datei einzugeben - da die Dateien oft zu groß für den SSMS-Textpuffer waren.
Was ich hier sage ist, dass diese Option wahrscheinlich auch für Sie funktionieren würde. Sie müssen nur einen weiteren Schritt ausführen und getdate () durch [dbo] .getlocaldate in der generierten Textdatei suchen und ersetzen. (Ich würde Ihre Funktion jedoch vor der Migration in die Datenbank stellen.)
(Ich wollte mich nie mit diesem Band-Aid einer Datenbankwiederherstellung auskennen, aber für eine Weile wurde es zu einer defakten Methode. Und es funktionierte jedes Mal.)
Wenn Sie sich für diese Route entscheiden, stellen Sie sicher, dass Sie auf die Schaltfläche Erweitert klicken und alle Optionen auswählen (jeweils lesen) , um von der alten Datenbank in die neue Datenbank zu wechseln - wie die von Ihnen erwähnten Standardeinstellungen. Probieren Sie es doch mal in Azure aus. Ich wette, Sie werden feststellen, dass dies eine Lösung ist, die funktioniert - mit ein wenig Aufwand.
quelle
Beachten Sie die kommentierten sysobjects. Geben Sie die Spaltenbedingung ein. Mein Skript ändert nur proc und UDF.
Dieses Skript ändert alle
Default Constraint
InhalteGetDate()
quelle
Ich habe die Antwort von Evan Carrolls positiv bewertet, da ich denke, dass dies die beste Lösung ist. Ich war nicht in der Lage, meine Kollegen davon zu überzeugen, dass sie viel C # -Code ändern sollten, daher musste ich den Code verwenden, den David Spillett schrieb. Ich habe einige Probleme mit UDFs, Dynamic SQL und Schemas behoben (nicht jeder Code verwendet "dbo"):
und die Standardbedingungen wie folgt:
UDFs
Der Vorschlag, eine UDF zu verwenden, die das heutige Datum und die aktuelle Uhrzeit zurückgibt, sieht gut aus, aber ich denke, es gibt immer noch genügend Leistungsprobleme mit UDFs, deshalb habe ich mich für die sehr lange und hässliche AT TIME ZONE-Lösung entschieden.
quelle