OVH Cloud OVH Cloud

Question de débutant

26 réponses
Avatar
Etienne SOBOLE
salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est renseignée alors
alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne

10 réponses

1 2 3
Avatar
Bertrand
Sur Oracle tu crée... un index unique.
Un index unique accepte aussi les valeurs nulles (ce qui n'est pas le
cas de la clé primaire).


CREATE TABLE TEST
(
TEST VARCHAR2(1)
);

INSERT INTO TEST ( TEST ) VALUES (
'A');
INSERT INTO TEST ( TEST ) VALUES (
'B');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
INSERT INTO TEST ( TEST ) VALUES (
'D');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
COMMIT;

CREATE UNIQUE INDEX PKTEST ON TEST(TEST);

--
bertrand
Etienne SOBOLE wrote:

salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est
renseignée alors
alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne
Avatar
newdb
Bertrand <> wrote:
Sur Oracle tu crée... un index unique.
Un index unique accepte aussi les valeurs nulles (ce qui n'est pas le
cas de la clé primaire).




sur mysql aussi tout pareil (depuis la version 3.23 et avec une table
MyISAM)

--
@@@@@
E -00 comme on est very beaux dis !
' `) /
|_ =="
Avatar
Fred BROUARD - SQLpro
A lire :
1)
http://sqlpro.developpez.com/cours/null/#L5.2
2)
http://sqlpro.developpez.com/cours/null/#L7.4

Hélas rare sont les SGBDR qui acceptent réeellement la contrainte d'unicité à la
norme SQL

La seule solution est d'implémenter un trigger.

A +

Etienne SOBOLE a écrit:
salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est renseignée alors
alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne





--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************
Avatar
Igor Racic
Juste comme un complément, dans les index multi-column, ça c'est
vrais
seulement si TOUT les champs sont null:

SQL> create table t ( a number, b number );

Table created.

SQL> create unique index ti on t ( a, b );

Index created.

SQL> insert into t values ( 1, null );

1 row created.

SQL> insert into t values ( 1, null );
insert into t values ( 1, null )
*
ERROR at line 1:
ORA-00001: unique constraint (SYS.TI) violated


SQL>
SQL> insert into t values ( null, null );

1 row created.

SQL> /

1 row created.


Igor




Bertrand wrote:

Sur Oracle tu crée... un index unique.
Un index unique accepte aussi les valeurs nulles (ce qui n'est pas le
cas de la clé primaire).


CREATE TABLE TEST
(
TEST VARCHAR2(1)
);

INSERT INTO TEST ( TEST ) VALUES (
'A');
INSERT INTO TEST ( TEST ) VALUES (
'B');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
INSERT INTO TEST ( TEST ) VALUES (
'D');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
COMMIT;

CREATE UNIQUE INDEX PKTEST ON TEST(TEST);

--
bertrand
Etienne SOBOLE wrote:

salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est
renseignée
alors alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne
Avatar
Fred BROUARD - SQLpro
oui, mais c'est illogique, cette façon de faire propre à Oracle
est aussi celle
de bon nombre de SGBDR. Or le théorème de base du marqueur NULL,
c'est que,
comme il ne s'agit pas d'une valeur on ne peut donc pas la comparer. Elle est
donc à la fois toujours différente à elle même. Or la
plupart des SGBDR agissent
comme si NULL = NULL, qui par définition est une vaste connerie !

A +

--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste
Delphi, web
Livre SQL - col. Référence :
http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Igor Racic a écrit:

Juste comme un complément, dans les index multi-column, ça c'est
vrais
seulement si TOUT les champs sont null:

SQL> create table t ( a number, b number );

Table created.

SQL> create unique index ti on t ( a, b );

Index created.

SQL> insert into t values ( 1, null );

1 row created.

SQL> insert into t values ( 1, null );
insert into t values ( 1, null )
*
ERROR at line 1:
ORA-00001: unique constraint (SYS.TI) violated


SQL>
SQL> insert into t values ( null, null );

1 row created.

SQL> /

1 row created.


Igor




Bertrand wrote:


Sur Oracle tu crée... un index unique.
Un index unique accepte aussi les valeurs nulles (ce qui n'est pas le
cas de la clé primaire).


CREATE TABLE TEST
(
TEST VARCHAR2(1)
);

INSERT INTO TEST ( TEST ) VALUES (
'A');
INSERT INTO TEST ( TEST ) VALUES (
'B');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
INSERT INTO TEST ( TEST ) VALUES (
'D');
INSERT INTO TEST ( TEST ) VALUES (
NULL);
COMMIT;

CREATE UNIQUE INDEX PKTEST ON TEST(TEST);

--
bertrand
Etienne SOBOLE wrote:

salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est
renseignée
alors alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne
Avatar
newdb
Igor Racic wrote:
Juste comme un complément, dans les index multi-column, ça c'est vrais
seulement si TOUT les champs sont null:
SQL> create table t ( a number, b number );
SQL> create unique index ti on t ( a, b );
SQL> insert into t values ( 1, null );
SQL> insert into t values ( null, null );



oui, mais tu peux avoir
1,null
1,1
2,null
2,1

tu n'a donc d'unicité ni sur a ni sur b (seulement sur a.b)

alors qu'avec un 'simple' index unique sur a,
tu as SOIT null SOIT valeur-unique

(mysql à partir 3.23 avec table myisam)

--
@@@@@
E -00 comme on est very beaux dis !
' `) /
|_ =="
Avatar
see
denisb wrote:

Igor Racic wrote:
> Juste comme un complément, dans les index multi-column, ça c'est vrais
> seulement si TOUT les champs sont null:
> SQL> create table t ( a number, b number );
> SQL> create unique index ti on t ( a, b );
> SQL> insert into t values ( 1, null );
> SQL> insert into t values ( null, null );

oui, mais tu peux avoir
1,null
1,1
2,null
2,1

tu n'a donc d'unicité ni sur a ni sur b (seulement sur a.b)



Ben, c'est le comportement attendu ! Par définition !

alors qu'avec un 'simple' index unique sur a,
tu as SOIT null SOIT valeur-unique



Le comportement est parfaitement cohérent.
Un index unique ne stocke que des valeurs uniques, sans exception. Le
truc étant que si toutes les colonnes de l'index sont nulles, la ligne
n'est pas stockée dans l'index et n'est donc pas soumise à l'unicité de
l'index.
Si l'index ne porte que sur une seule colonne a, alors les lignes avec
une valeur nulle pour a ne sont pas stockées dans l'index et ne sont
donc pas soumise à l'unicité du champ a.
Si l'index porte sur deux colonnes a et b, alors les lignes ayant a et b
avec une valeur nulle ne sont pas stockées dans l'index. Par contre, si
a ou b ne sont pas nulles, alors la ligne est référencé dans l'index.

Comme l'indique Frédéric, le moteur considère que NULL = NULL quand il
examine une unicité.
Avatar
newdb
Bruno Jargot wrote:
Un index unique ne stocke que des valeurs uniques, sans exception. Le
truc étant que si toutes les colonnes de l'index sont nulles, la ligne
n'est pas stockée dans l'index et n'est donc pas soumise à l'unicité de
l'index.



ok. ça je comprends bien. l'index n'est construit qu'à partir de valeurs
renseignées.

Si l'index ne porte que sur une seule colonne a, alors les lignes avec
une valeur nulle pour a ne sont pas stockées dans l'index et ne sont
donc pas soumise à l'unicité du champ a.



ok donc.

Si l'index porte sur deux colonnes a et b, alors les lignes ayant a et b
avec une valeur nulle ne sont pas stockées dans l'index. Par contre, si
a ou b ne sont pas nulles, alors la ligne est référencé dans l'index.



oui. mais justement, pourquoi se donner la peine de 'doubler' l'index en
concaténant les 2 colonnes ? je pressens bien qu'il y a un truc bancale
(illogique ?) dans cette histoire (une valeur qui s'interroge : être ou
ne pas être ? c'est fort), mais je n'arrive pas à voir quoi...

Comme l'indique Frédéric, le moteur considère que NULL = NULL quand il
examine une unicité.



donc il ne prend pas en compte la ligne. ce qui est le but recherché (je
crois) par Etienne.
oui. mais bon :
que NULL = NULL tout comme NULL,NULL = NULL,NULL
c'est la vérité (logique) non ?
sauf à considérer que NULL est une valeur indexable et donc
que NULL <> NULL ***dés lors que NULL 'existe' au moins une fois***
...

pfiouuuu... aspirine

--
@@@@@
E -00 ... là est la question !
' `) /
|_ =="
Avatar
Etienne SOBOLE
Et bien merci pour toutes ces réponses...
moi j'utilise postgreSQL. k'ai pluqu'a vérifier que ca marche aussi.

A+

PS : denisb a parlé de MySQL en mode MyISAM
qu'en est il du mode InnoDB ???

Etienne

"Etienne SOBOLE" a écrit dans le message de news:
418fa69f$0$5226$
salut.

comment fait on pour placer un index qui est soit unique soit null.
en gros l'idée c'est que je veux que si une colonne est renseignée alors
alle doit etre unique, sinon elle est nulle !!!

Merci
Etienne

Avatar
newdb
denisb wrote:
oui. mais justement, pourquoi se donner la peine de 'doubler' l'index en
concaténant les 2 colonnes ? je pressens bien qu'il y a un truc bancale
(illogique ?) dans cette histoire (une valeur qui s'interroge : être ou
ne pas être ? c'est fort), mais je n'arrive pas à voir quoi...



ça y est !!!
non mais des fois, j'vous jure...
c'était tellement con...plexe !

CREATE TABLE `ma_table` (
`mon_champ` int(11) default NULL,
UNIQUE KEY `mon_champ` (`mon_champ`)
) TYPE=MyISAM;

INSERT INTO `ma_table` VALUES (NULL);
INSERT INTO `ma_table` VALUES (NULL);
INSERT INTO `ma_table` VALUES (1);
INSERT INTO `ma_table` VALUES (2);
INSERT INTO `ma_table` VALUES (3);

SELECT * FROM ma_table WHERE mon_champ != NULL
=> 0 row

SELECT * FROM ma_table WHERE mon_champ = NULL
=> 0 row

SELECT * FROM ma_table WHERE mon_champ != ''
=> 3 rows

certes, mais ...

SELECT * FROM ma_table WHERE mon_champ = ''
=> 0 row

impossible donc de retrouver les lignes NULL
aïe aïe aïe ...

--
@@@@@
E -00 comme on est very beaux dis !
' `) /
|_ =="
1 2 3