J'ai besoin de migrer une base de données SQL Server 2017 sur site vers une base de données Azure SQL, et je suis confronté à certains défis car il y a un certain nombre de limitations à traverser.
En particulier, étant donné qu'une base de données Azure SQL ne fonctionne qu'en heure UTC (pas de fuseau horaire) et que nous avons besoin de l'heure locale, nous devons changer l'utilisation de GETDATE()
partout dans la base de données, ce qui s'est avéré être plus de travail que je ne l'avais prévu.
J'ai créé une fonction définie par l'utilisateur pour obtenir l'heure locale qui fonctionne correctement pour mon fuseau horaire:
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
Le problème qui me pose problème est de modifier GETDATE()
cette fonction dans chaque vue, procédure stockée, colonnes calculées, valeurs par défaut, autres contraintes, etc.
Quelle serait la meilleure façon de mettre en œuvre ce changement?
Nous sommes dans l'aperçu public des instances gérées . Il a toujours le même problème GETDATE()
, il n'aide donc pas avec ce problème. Le passage à Azure est une exigence. Cette base de données est utilisée (et sera utilisée) toujours dans ce fuseau horaire.
Je travaillerais dans l'autre sens. Convertissez tous vos horodatages de la base de données en UTC, et utilisez simplement UTC et suivez le flux. Si vous avez besoin d'un horodatage dans un autre tz, vous pouvez créer une colonne générée en utilisant
AT TIME ZONE
(comme vous l'avez fait ci-dessus) qui rend l'horodatage dans ce TZ spécifié (pour l'application). Mais, j'envisagerais sérieusement de simplement retourner UTC dans l'application et d'écrire cette logique - la logique d'affichage - dans l'application.la source
Plutôt que d'exporter, de modifier manuellement et de réexécuter, vous pouvez essayer de faire le travail directement dans la base de données avec quelque chose comme:
bien sûr, l'étendre pour gérer les fonctions, les déclencheurs, etc.
Il y a quelques mises en garde:
Vous devrez peut-être être un peu plus lumineux et gérer des espaces blancs différents / supplémentaires entre
CREATE
etPROCEDURE
/VIEW
/<other>
. Plutôt que leREPLACE
pour cela, vous préféreriez peut-être laisser leCREATE
en place et en exécuter unDROP
premier, mais cela risque de laisser lessys.depends
amis hors de portée, ce quiALTER
peut ne pas être le cas, également en cas d'ALTER
échec, vous avez au moins l'objet existant toujours en place où avecDROP
+CREATE
vous pouvez ne pas.Si votre code a des odeurs "intelligentes" comme la modification de son propre schéma avec TSQL ad hoc, vous devrez vous assurer que la recherche et le remplacement de
CREATE
->ALTER
n'interfèrent pas avec cela.Vous souhaiterez tester la régression de la ou des applications entières après l'opération, que vous utilisiez le curseur ou les méthodes d'exportation + édition + exécution.
J'ai utilisé cette méthode pour effectuer des mises à jour similaires à l'échelle du schéma dans le passé. C'est un peu un hack et semble assez moche, mais parfois c'est le moyen le plus simple / le plus rapide.
Les valeurs par défaut et autres contraintes peuvent également être modifiées de la même manière, bien que celles-ci puissent uniquement être supprimées et recréées plutôt que modifiées. Quelque chose comme:
Un peu plus de plaisir auquel vous devrez peut-être faire face: si vous partitionnez en fonction du temps, ces parties peuvent également avoir besoin d'être modifiées. Bien que le partitionnement à l'heure de manière plus granulaire que le jour soit rare, vous pouvez avoir des problèmes où les
DATETIME
s sont interprétés par la fonction de partitionnement comme étant le jour précédent ou suivant selon le fuseau horaire, laissant vos partitions non alignées avec vos requêtes habituelles.la source
sys
schéma et modifiées par programme.CREATE OR ALTER PROCEDURE
aide à résoudre certains problèmes de génération de code; il peut encore y avoir des problèmes car la définition stockée se liraCREATE PROCEDURE
(trois! espaces) et cela ne correspondCREATE PROCEDURE
ni àCREATE OR ALTER PROCEDURE
… ._.CREATE
qui ne se trouve pas dans un commentaire et la remplace. Je n'ai pas ceci / similaire dans le passé mais je n'ai pas le code de la fonction à portée de main pour le moment. Ou si vous pouvez garantir qu'aucune de vos définitions d'objet n'a de commentaires précédentsCREATE
, ignorez le problème des commentaires et recherchez et remplacez simplement la première instance deCREATE
.J'aime vraiment la réponse de David et j'ai voté pour une manière programmatique de faire les choses.
Mais vous pouvez essayer cela aujourd'hui pour une exécution de test dans Azure via SSMS:
Faites un clic droit sur votre base de données -> Tâches -> Générer des scripts.
[Back Story] nous avions un DBA junior qui a mis à niveau tous nos environnements de test vers SQL 2008 R2 alors que nos environnements de production étaient à SQL 2008. C'est un changement qui me fait grincer des dents à ce jour. Pour migrer vers la production, à partir du test, nous avons dû générer des scripts dans SQL, en utilisant des scripts de génération, et dans les options avancées, nous avons utilisé l'option `` Type de données à script: schéma et données '' pour générer un fichier texte massif. Nous avons réussi à déplacer nos bases de données de test R2 vers nos serveurs SQL 2008 hérités - où une restauration de base de données vers une version inférieure n'aurait pas fonctionné. Nous avons utilisé sqlcmd pour entrer le gros fichier - car les fichiers étaient souvent trop gros pour le tampon de texte SSMS.
Ce que je dis ici, c'est que cette option fonctionnerait probablement aussi pour vous. Vous aurez juste besoin de faire une étape supplémentaire et de rechercher et remplacer getdate () par [dbo] .getlocaldate dans le fichier texte généré. (Je mettrais cependant votre fonction dans la base de données avant la migration).
(Je n'ai jamais voulu maîtriser ce pansement de restauration de base de données, mais pendant un certain temps, c'est devenu une façon de faire de facto. Et, cela a fonctionné à chaque fois.)
Si vous choisissez cette route, assurez-vous et sélectionnez le bouton Avancé et sélectionnez toutes les options dont vous avez besoin (lisez chacune) pour passer de l'ancienne base de données à la nouvelle base de données - comme les valeurs par défaut que vous avez mentionnées. Mais essayez-le quelques fois dans Azure. Je parie que vous constaterez que c'est une solution qui fonctionne - avec un minimum d'effort.
la source
Remarquez les sysobjects commentés Condition de colonne de type. Mon script ne modifie que proc et UDF.
Ce script va modifier tout
Default Constraint
ce qui contientGetDate()
la source
J'ai voté pour la réponse d'Evan Carrolls, car je pense que c'est la meilleure solution. Je n'ai pas réussi à convaincre mes collègues qu'ils devraient changer beaucoup de code C #, j'ai donc dû utiliser le code que David Spillett a écrit. J'ai corrigé quelques problèmes avec les FDU, Dynamic SQL et les schémas (tous les codes n'utilisent pas "dbo") comme ceci:
et les contraintes par défaut comme ceci:
UDF
La suggestion d'utiliser un UDF qui retourne la date et l'heure d'aujourd'hui semble agréable, mais je pense qu'il y a encore suffisamment de problèmes de performances avec les UDF, j'ai donc choisi d'utiliser la très longue et laide solution AT TIME ZONE.
la source