Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Dépannage des problèmes lors de l'utilisation de la date et de l'heure dans SQL Server

La base de données Microsoft SQL Server stocke les informations de date et d'heure dans divers formats. Les plus courants d'entre eux sont DateHeure , DateHeure2 , et date . Comme c'est le cas avec tous les types de données, des problèmes peuvent survenir à chaque fois. Dans cet article, nous nous concentrerons sur le dépannage de certains des problèmes les plus courants auxquels vous pourriez être confronté lorsque vous travaillez avec les types de données d'heure et de date SQL.

Problèmes liés aux formats de date régionaux différents

Le format des dates varie globalement. Par exemple, les Britanniques écrivent les dates au format jj-mm-aaaa, tandis que les Américains écrivent les dates au format mm-jj-aaaa. Ainsi, la même date, le 31 décembre 2020, s'écrit 31-12-2020 au format de date britannique et 12-31-2020 au format américain.

Des problèmes d'incapacité peuvent survenir si vous ne spécifiez pas la date dans un format correspondant aux paramètres de langue de votre instance SQL Server.

Le script suivant convertit la chaîne de texte avec les informations de date au format DATETIME. Les paramètres de langue sont définis sur BRITISH. La chaîne de texte contient 31-12-2020 04:25:30 .

Si vous convertissez cette chaîne au format DATETIME, 31 sera traité comme un jour, tandis que 12 sera un mois par défaut. Par conséquent, la conversion sera réussie comme indiqué à partir de la sortie :

SET LANGUAGE BRITISH;
DECLARE @date VARCHAR(50) = '31-12-2020 04:25:30';
SELECT CAST(@date AS DATETIME);

Cependant, si vous essayez de convertir la chaîne contenant la date 31-12-2020 au format DATETIME en utilisant US_ENGLISH paramètres de langue, vous recevrez une erreur comme indiqué ci-dessous :

SET LANGUAGE US_ENGLISH;
DECLARE @date VARCHAR(50) = '31-12-2020 04:25:30';
SELECT CAST(@date AS DATETIME);

L'erreur se produit car les paramètres de langue US_ENGLISH définissent 31 comme un mois au lieu d'un jour. Comme le mois la valeur ne peut pas être supérieure à 12, nous recevons l'erreur de valeur hors plage .

Si vous spécifiez la date 31-12-2020, puis convertissez la chaîne de date en DATETIME à l'aide des paramètres US_ENGLISH, vous verrez la conversion réussie :

SET LANGUAGE US_ENGLISH;
DECLARE @date VARCHAR(50) = '12-31-2020 04:25:30';
SELECT CAST(@date AS DATETIME);

De même, la conversion du 12-31-2020 la chaîne de date sous le paramètre de langue BRITISH provoque également une erreur - 31 est traité comme un mois, ce qui ne peut pas être le cas.

SET LANGUAGE BRITISH;
DECLARE @date VARCHAR(50) = '12-31-2020 04:25:30';
SELECT CAST(@date AS DATETIME);

Pour convertir votre date avec précision, quels que soient les paramètres de langue, vous pouvez utiliser la norme ISO 8601 pour le format de date. Pour se conformer à cette norme, spécifiez la date sous la forme aaaa-mm-jjThh:mm:ss .

Par exemple, la chaîne de date 2020-12-31T04:25:30 est convertie avec succès en type de données DATETIME sous les paramètres de langue BRITISH :

SET LANGUAGE BRITISH;
DECLARE @date VARCHAR(50) = '2020-12-31T04:25:30';
SELECT CAST(@date AS DATETIME);

Le script suivant montre la même chaîne convertie en DATETIME avec les paramètres US_ENGLISH :

SET LANGUAGE US_ENGLISH;
DECLARE @date VARCHAR(50) = '2020-12-31T04:25:30';
SELECT CAST(@date AS DATETIME);

Considérations sur le fuseau horaire

Vous souhaiterez peut-être développer des applications de base de données SQL Server pour le public mondial. Pour cela, vous devrez peut-être ajouter les informations de fuseau horaire aux types de données de date et d'heure.

Dans SQL Server, le type de données DATETIMEOFFSET stocke les informations de date et d'heure avec le décalage de fuseau horaire. Le décalage du fuseau horaire est spécifié sous la forme UTC +/- nombre d'heures.

Par exemple, le script suivant utilise la méthode SYSDATETIMEOFFSET() pour obtenir les informations de date, d'heure et de décalage du système exécutant votre instance SQL Server. Les valeurs renvoyées par la fonction SYSDATETIMEOFFSET() sont stockées dans la variable de type DATETIMEOFFSET @dateoffset. La valeur de la variable @dateoffset est imprimée à l'aide de l'instruction SELECT :

DECLARE @dateoffset DATETIMEOFFSET = SYSDATETIMEOFFSET();
SELECT @dateoffset

La sortie ci-dessous montre la date et l'heure actuelles et la valeur de décalage. Dans ce cas, il s'agit de +02:00.

Vous pouvez également obtenir uniquement la valeur de décalage à partir de la variable DATETIMEOFFSET. Pour ce faire, vous devez passer la variable de type DATETIMEOFFSET comme seconde valeur de paramètre à la fonction DATENAME(). Le premier paramètre de la méthode DATENAME() doit être tzoffset .

Le script suivant renvoie la partie décalage horaire de la date système actuelle :

DECLARE @dateoffset DATETIMEOFFSET = SYSDATETIMEOFFSET();
SELECT DATENAME(tzoffset, @dateoffset)

Pour créer une variable DATETIMEOFFSET personnalisée, spécifiez des valeurs pour les portions de date, d'heure et de décalage horaire. Par exemple, dans le script suivant, la valeur de la date est le 2015-02-22 , la valeur de la portion de temps est 23:59:59:999 , et la valeur de décalage horaire est +05:00 .

DECLARE @dateoffset DATETIMEOFFSET = '2015-02-22 23:59:59:999 +05:00';
SELECT @dateoffset

Enfin, vous pouvez également mettre à jour les informations de décalage horaire à l'aide de SWITCHOFFSET() fonction.

Vous devez passer le DATETIMEOFFSET tapez variable comme première valeur de paramètre et transmettez le nouveau décalage horaire comme deuxième valeur de paramètre à SWITCHOFFSET fonction.

Le script suivant met à jour la valeur de décalage horaire pour la variable DATETIMEOFFSET de +05:00 à +09:00.

DECLARE @dateoffset DATETIMEOFFSET = '2015-02-22 23:59:59:999 +05:00';
SELECT SWITCHOFFSET(@dateoffset, '+09:00');

Sélectionner des enregistrements à l'aide de l'opérateur BETWEEN avec DateTime

L'ENTRE L'opérateur du serveur SQL filtre les enregistrements entre la plage de valeurs qui lui est transmise.

Vous pouvez utiliser l'opérateur BETWEEN pour renvoyer des enregistrements entre deux dates. Cependant, vous devez être très prudent lorsque vous l'utilisez pour filtrer les enregistrements avec des dates.

Par exemple, le script suivant crée un Hostel factice base de données et ajoute un étudiant table dessus.

CREATE DATABASE Hostel

USE Hostel
CREATE TABLE Student

(
Id INT PRIMARY KEY IDENTITY(1,1),
Name VARCHAR (50) NOT NULL,
Gender VARCHAR (50),
BirthDate DateTime
)

Le script suivant ajoute des enregistrements factices à Student table. La date de naissance colonne de l'Étudiant la table stocke les dates. À partir de ce script, vous pouvez voir que deux étudiants, Sara et Nik, ont les mêmes dates de naissance. Cependant, l'heure de naissance est différente :

INSERT INTO Student
VALUES ('Jack', 'Male', '2017-06-30 16:30:35'),
('Sara', 'Female', '2015-02-22 00:00:00'),
('Elisa', 'Female',  '2020-03-16 22:24:39'),
('Nik', 'Male',  '2015-02-22 09:45:55'),
('Jos', 'Male',  '2015-03-25 11:55:20')

On pourrait penser que l'opérateur BETWEEN pourrait être utilisé pour récupérer les enregistrements de tous les étudiants nés le 2015-02-22.

SELECT * FROM Student
WHERE BirthDate BETWEEN '2015-02-22' AND '2015-02-22'

Mais si vous exécutez le script ci-dessus, vous verrez qu'un seul enregistrement est renvoyé, malgré le temps partie est également inclus.

La raison est que l'opérateur BETWEEN traite par défaut la valeur DATETIME de 2015-02-22 comme 2015-02-22 00:00:00 . Par conséquent, l'opérateur BETWEEN dans la requête ci-dessus a recherché les enregistrements avec la BirthDate valeur entre 2015-02-22 00:00:00 et 2015-02-22 00:00:00 .

Pour résoudre ce problème, nous devons spécifier la partie temporelle lors de l'utilisation de l'opérateur BETWEEN avec le type de données DATETIME.

Le script suivant renverra tous les enregistrements entre 2015-02-22 00:00:00 et 2015-02-22 23:59:59:999 . La portion horaire pour la limite de date supérieure est 23:59:999.

SELECT * FROM Student
WHERE BirthDate BETWEEN '2015-02-22' AND '2015-02-22 23:59:59:999';

Dans la sortie, nous obtenons deux enregistrements pour le BirthDate 2015-02-22 .

Problèmes liés aux plages de dates

Le type de données DATETIME ne prend en charge que les années 1753 à 9999. Par conséquent, si vous essayez de stocker une date avec une valeur d'année supérieure à 9999 ou inférieure à 1753, vous obtiendrez une erreur.

Le script suivant essaie de convertir le 1392-12-31 chaîne de date. 1392 est inférieur à 1753. Par conséquent, nous avons l'erreur de valeur hors plage.

DECLARE @date VARCHAR(50) = '1392-12-31 04:25:30';
SELECT CAST(@date AS DATETIME);

Pour stocker des valeurs d'année inférieures à 1753 , vous pouvez utiliser le DATETIME2 Type de données. Il stocke les valeurs d'année de 0000 à 9999.

Le script suivant convertit avec succès la chaîne de date 1392-12-31 en type de données DATETIME2 :

DECLARE @date VARCHAR(50) = '1392-12-31 04:25:30';
SELECT CAST(@date AS DATETIME2);

Utilisation de TRY_COVERT pour la conversion DateHeure

La fonction CONVERT dans SQL Server convertit les données d'un type à un autre. Vous pouvez l'utiliser pour convertir les formats de données de type date en d'autres formats et vice versa. Cependant, si la conversion échoue, la fonction CONVERT renvoie une erreur.

Par exemple, nous convertissons la chaîne 2015-31-31 au format DATETIME :

DECLARE @date VARCHAR(50) = '2015-31-13';
SELECT  CONVERT(DATETIME, @date ,105) as DOB_CONV

Si vous souhaitez qu'une valeur NULL soit renvoyée lorsque la conversion échoue au lieu du message d'erreur, utilisez le TRY_CONVERT une fonction. Cette méthode ne laissera pas l'application planter - elle renvoie simplement une valeur NULL.

DECLARE @date VARCHAR(50) = '2015-31-13';

SELECT  TRY_CONVERT(DATETIME, @date ,105) as DOB_CONV

Conclusion

En travaillant avec SQL Server, vous pouvez rencontrer de nombreux problèmes qui gâchent votre expérience et compliquent les tâches. Connaître les problèmes les plus courants est, en revanche, la méthode la plus efficace pour les empêcher de se produire. C'est pourquoi nous avons consacré cet article au dépannage de tels désagréments qui peuvent survenir lors de votre travail avec les informations sur les dates et les heures.

Notez également que les outils modernes pour travailler avec les bases de données SQL Server peuvent rendre la vie des spécialistes de la base de données beaucoup plus simple. En particulier, dbForge Studio pour SQL Server fournit la fonctionnalité Visual Data Editor à appliquer lors du traitement des dates. Vous pouvez l'utiliser pour afficher et modifier les dates de la manière la plus conviviale.