Base de données SQL agnostique pour la liste de retour pour la date de naissance enregistrée en tant que Timestamp

StackOverflow https://stackoverflow.com/questions/868464

Question

Si je dois chercher à la date de naissance qui est stocké sans les heures et les minutes, mais la date que je dois chercher avec comprend des heures et des minutes ce qui est la meilleure façon de retourner toutes les lignes où la date est égalés sur le jour seulement, mois et l'année

i.e..
Stocké sous forme de 01-JAN-50 10.22.06.000000000
Date sélectionnée 01-janv.-50 10.22.06.010101120

Si je la date avec les heures et les minutes, le SQL renvoie uniquement les lignes avec l'horodatage exact et non ceux pour seulement le jour, le mois et l'année.

Le SQL doit travailler sur Oracle, SQLServer, MySQL et DB2.

Était-ce utile?

La solution

type DATE Oracle date d'avant la version standard SQL (comme le fait de Informix), ce qui rend cette extrêmement difficile - voire impossible - de faire de façon SGBD neutre. Bien sûr, il est une question de « pourquoi la représentation de données choisie incluent le temps ».

Dans SQL standard, la technique évidente serait de jeter le TIMESTAMP à une date. Nous n'avons pas aussi une explication claire des données que vous devez rechercher avec.

SELECT CAST(DateOfBirth AS DATE), ...other columns...
    FROM TheMysteryTable         -- Why do people hate giving tables names?
    WHERE CAST(DateOfBirth AS DATE) =
          CAST(TIMESTAMP '1950-01-01 10.22.06.010101120' AS DATE)

Mais cela suppose que vous écrivez la « date de recherche avec » comme un littéral. Si elle est une variable hôte, le type de la variable hôte doit être DATE, pas TIMESTAMP. Et la colonne DateOfBirth devrait probablement être une date, pas un TIMESTAMP. Vous ne devriez pas utiliser TIMESTAMP à moins que la partie du temps est pertinente -. Il gaspille le stockage et une perte de temps de calcul

Notez qu'en raison des moulages, il est peu probable que le SGBD sera en mesure d'utiliser tous les index ou quoi que ce soit. Si les types ont été sain d'esprit, alors la requête serait simplement:

SELECT DateOfBirth, ...other columns...
    FROM TheMysteryTable
    WHERE DateOfBirth = DATE '1950-01-01'

Autres conseils

Comme toute solution va nécessiter la manipulation d'objets de date et datetime, alors il n'y aura pas de solution agnostique système -. Chacun aura différentes fonctions pour les objets

La meilleure solution, autre que l'abstraction de base de données, serait d'arrondir l'objet datetime utilisé d'abord, puis seulement une clause de comparaison SQL générique est nécessaire, qui sera fonctionnelle dans tous les blocs de données énumérés.

Il n'y a pas de format de date ANSI, ni la manipulation de chaînes. Tout code que dans certaines années SGBDR, sinon un seul.

Cependant, si vous obtenez votre date sélectionnée en dehors de votre SGBDR (par exemple, PHP, Java, etc.), je vous suggère désinfectante avant de l'envoyer dans la requête; alors vous pouvez comparer chaîne à chaîne, qui devrait fonctionner dans presque tous les systèmes.

Comme d'autres l'ont souligné, SGBDR de sont très divergentes en matière de manipulation datetimes. Si ils ont effectivement suivi la norme ANSI-92, alors ce qui suit devrait fonctionner:

SELECT
     <column list>
FROM
     <table name>
WHERE
     CAST(birth_date AS DATE) = CAST(search_date AS DATE)

ne serait pas la façon la plus efficace de le faire bien, car il empêcherait l'utilisation des index à la date de la plupart des systèmes. Ce qui suit peut travail pour une base de données 92 conforme aux normes ANSI entièrement:

SELECT
     <column list>
FROM
     <table name>
WHERE
     birth_date >= CAST(CAST(search_date AS DATE) AS DATETIME) AND
     birth_date < CAST(CAST(search_date AS DATE) + 1 AS DATETIME)

Utilisation EXTRACT ()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top