Y a-t-il un type Boolean dans les bases de données Oracle, similaire au type BIT
dans Ms SQL Server?
1/0 est, sinon ambigu, au moins moins ambigu.
Y a-t-il un type Boolean dans les bases de données Oracle, similaire au type BIT
dans Ms SQL Server?
Avant la version 23c (2023), non seulement le type de données booléen était absent du SQL d'Oracle (pas du PL/SQL), mais il n'y avait également aucune recommandation claire sur ce qu'il fallait utiliser à la place. Voir ce fil de discussion sur asktom. En passant de CHAR(1) 'Y'/'N'
à NUMBER(1) 0/1
lorsqu'on souligne que 'Y'/'N'
dépend de la langue anglaise, alors que par exemple les programmeurs allemands pourraient utiliser 'J'/'N'
à la place.
Le pire est qu'ils défendent cette décision stupide comme ils défendent la stupidité de ''=NULL
.
Oracle 23c prend enfin en charge les types de données booléens dans tous les contextes, ainsi que plusieurs autres fonctionnalités qui lui ont fait défaut par rapport aux autres bases de données.
SQL> select true;
TRUE
-----------
TRUE
SQL> create table test1(a boolean);
Table created.
SQL> insert into test1 values (true),(false),(to_boolean(0)),(to_boolean('y'));
4 lignes créées.
Mais le problème de la chaîne vide ne changera jamais.
Je préfère aussi 1/0, mais bien sûr vous trouverez également des personnes ayant une expérience en Visual Basic qui choisiront -1/0 à la place. À mon avis, il n'y a qu'une seule solution raisonnable à ce problème : Oracle devrait créer un type de données booléen. Ce ne peut pas être si difficile quand presque tous les autres SGBDR en ont un.
Non.
Peut utiliser:
IS_COOL NUMBER(1,0)
1 - vrai
0 - faux
--- profitez d'Oracle
Ou utiliser char Y/N comme décrit ici
Je préfère char(1) car il utilise moins d'espace. Vous pouvez le vérifier de cette manière : create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool;
Ce CHAR est stocké : Typ=96 Len=1: 89
et ce NUMBER : Typ=2 Len=2: 193,2
Au moins en 12c, NUMBER(1) peut utiliser 2 octets...
Venir d'un contexte Java, la spécification JDBC de ResultSet.getBoolean()
indique: Si la colonne désignée a un type de données CHAR ou VARCHAR et contient un "0" ou a un type de données BIT, TINYINT, SMALLINT, INTEGER ou BIGINT et contient un 0, une valeur de faux est renvoyée. Si la colonne désignée a un type de données CHAR ou VARCHAR et contient un "1" ou a un type de données BIT, TINYINT, SMALLINT, INTEGER ou BIGINT et contient un 1, une valeur de vrai est renvoyée. -- Sur la base de cela, je recommanderais la solution 0/1
plutôt que Y/N
. Même en utilisant une colonne CHAR, il est préférable d'utiliser des nombres.
@phil_w En tant qu'ancien programmeur C, je préfère TRUE = 1 et FALSE = 0 dans les assertions logiques, et tout ce qui n'est pas nul est vrai. Le choix entre nombre et caractère est un compromis entre vitesse et taille car les nombres n'ont jamais besoin de passer par une conversion de jeu de caractères tandis que les caractères le font fréquemment.
Il existe un type booléen à utiliser en pl/sql, mais aucun ne peut être utilisé comme type de données d'une colonne.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
9 votes
Malheureusement, Oracle ne prend pas en charge pleinement la norme ANSI SQL:1999 (en.wikipedia.org/wiki/SQL:1999) lors de son introduction.
2 votes
Point de vue alternatif (pourquoi SQL ne devrait pas avoir un type booléen) : vadimtropashko.wordpress.com/2010/09/16/…
18 votes
@JeffreyKemp Ce blog n'a aucun sens. Juste parce que certaines valeurs booléennes peuvent être calculées en fonction d'autres champs dans une table, ne signifie pas que tous les champs booléens peuvent être calculés. Par exemple "is_trusted_customer" où cela est vrai si et seulement si un humain décide, "Je fais confiance à cette personne."
0 votes
@Jacob (juste jouer le rôle de l'avocat du diable ici) "is_trusted_customer" pourrait être repensé comme "customer_trust_score > 0" :) P.S. Je ne suis pas nécessairement d'accord avec l'article.
0 votes
Possible duplicate de Champ booléen dans Oracle
4 votes
@JeffreyKemp Félicitations, vous venez de réinventer les booléens de style C (où vous utilisez des
int
à la place). Nous devrions certainement revenir à cela dans le code. De plus, l'argument tombe complètement à l'eau si les types de données entre les colonnes de la table et les colonnes de résultat (d'unSELECT
) sont partagés, car il est tout à fait approprié de retourner un booléen en tant que résultat calculé parfois même étant donné le reste de l'argument.0 votes
Non, je n'ai rien inventé. Dans l'expression "score > 0", score est un nombre, pas un booléen (style C ou autre).
1 votes
@JeffreyKemp Mon point est que si les applications et les utilisateurs ne se soucient pas de l'ampleur du score (ce qui est le seul moment où vous envisageriez d'utiliser un booléen au lieu d'un nombre), alors c'est effectivement un booléen, où tout ce qui est >0 est vrai et 0 est faux. Un tel choix obscurcirait en fait le véritable sens de la colonne sans amélioration du système. (Je suis conscient que vous n'êtes pas nécessairement d'accord avec le point de vue de l'article, donc je m'excuse que mes mots étaient plutôt personnels. Je voulais m'adresser au concept.)
4 votes
Oui. Plus de types de données comme les booléens donneraient plus de puissance expressive exacte - vous n'aurez aucune objection de ma part sur ce point. Je suis juste content que nous ayons au moins un type
DATE
- imaginez avoir à traiter des représentations de dates sous forme de chaînes tout le temps :)1 votes
Plus de types de données n'est pas nécessairement mieux. Avoir un seul type de données numériques dans Oracle est une bénédiction. En parlant de dates, si les dates n'étaient que des chiffres de secondes (avec certaines fonctions prises en charge), peut-être alors n'aurions-nous pas à passer par le rituel idiot d'ajuster des myriades d'horloges deux fois par an?
0 votes
@TegiriNenashi Oracle prend en charge en fait NUMBER, BINARY_FLOAT et BINARY_DOUBLE en SQL. Je n'ai pas d'utilisation pour les deux derniers, cependant.
1 votes
Non, le type de données booléen n'ajoute pas de puissance expressive. C'est juste du sucre syntaxique pour les valeurs 0 et 1. En fait, contrairement aux logiciens, les mathématiciens se réfèrent aux booléens comme des éléments de Z/(2). D'un point de vue pratique, que diriez-vous de la conjonction booléenne? C'est simplement une multiplication xy. Et la disjonction? C'est x+y-xy. La négation? 1-x.
0 votes
@JeffreyKemp Sauf si vous êtes sarcastique à propos du type de données
DATE
: Comment utiliser '01-JAN-1970' pour créer une date ouTO_DATE('2012-06-05', 'YYYY-MM-DD')
ne revient-il pas à utiliser des chaînes de caractères pour représenter des dates? Honnêtement, je préférerais juste stocker les horodatages UNIX en tant que valeursNUMBER
. (C'est ce que l'on m'a appris à faire et on ne m'a jamais donné de raison de ne pas le faire.)1 votes
@AgiHammerthief non, je ne faisais pas de sarcasme. Le type de données
DATE
est l'un des meilleurs éléments de SQL. (Au fait,'01-JAN-1970'
est une chaîne de caractères, PAS une date; etto_date
retourne unedate
, pas une chaîne de caractères) Une valeurDATE
représente une date (date/heure, en fait) de manière non ambiguë (ce que les chaînes de caractères et les nombres ne peuvent pas faire) et les opérateurs de comparaison et arithmétiques de base fonctionnent de manière utile (contrairement aux chaînes de caractères ou aux valeurs numériques).0 votes
@JeffreyKemp Les horodatages UNIX utilisent des nombres de manière non ambiguë (nombre de secondes ou de millisecondes avant ou depuis le 1er janvier 1970, UTC/GMT, ou 0).
'01-JAN-1970'
etTO_DATE('2012-06-05', 'YYYY-MM-DD')
utilisent tous deux des chaînes de caractères pour fournir des valeurs à un type de données qui a une représentation interne différente qui n'est pas apparente par simple inspection visuelle. Tout langage de programmation décent (y compris SQL) devrait avoir la fonctionnalitéString from_unix_timestamp(long inVal, String format)
etlong to_unix_timestamp(String inVal, String format)
, dont une partie devrait permettre de spécifier le format de date, le décalage TZ & DST.0 votes
@JeffreyKemp Pour un timestamp UNIX
x
en millisecondes,x + 1
renverra 1 milliseconde aprèsx
.x + (24 * 60 * 60 * 1000)
renverra 24 heures aprèsx
, en supposant que le nombre de millisecondes dans une heure n'ait pas augmenté depuis la date représentée parx
. Dans le cas de l'année 1752, le timestamp UNIX pour01 janvier 1752 00:00:00 GMT+00:00
est-6879427200000
. Un DATE oracle représenterait cela comme '01-JAN-52', ce qui est ambigu, étant donné le manque de précision sur la partie année et l'omission des heures, minutes, secondes et décalage GMT.1 votes
@AgiHammerthief, non - Oracle ne représente PAS les dates sous forme de chaînes de caractères.
'01-JAN-52'
, comme tu l'as correctement souligné, n'est qu'une chaîne de caractères et n'est pas une date et est certainement ambiguë. Oracle n'utilise pas des chaînes comme celle-ci pour représenter des dates.