Vous n'êtes pas identifié(e).
cec.machines(id) is an integer not null >=0
cec.machines(machineid) is null when cec.machines(id) =0
cec.groupitems(iditem) is an integer not null (and is primary key of cec.groupitems).
running
select -2, null
union select 0, IDITEM from cec.GroupItems ;
works.
running
select id, null as gr
FROM cec.MACHINES
WHERE MACHINEID IS NOT NULL
union select -2, null;
also works.
But running
select id, null as gr
FROM cec.MACHINES
WHERE MACHINEID IS NOT NULL
union select -2, null
union select 0, IDITEM from cec.GroupItems ;
gives
ERROR: UNION types text and integer cannot be matched
LINE 5: union select 0, IDITEM from cec.GroupItems
^
********** Error **********
ERROR: UNION types text and integer cannot be matched
SQL state: 42804
Character: 110
Why why why why?
Dernière modification par albourg (15/11/2016 18:24:36)
Hors ligne
Bonjour,
La raison est que le type doit être connu au moment de faire un UNION. Du coup, par défaut un NULL est typé en text, à défaut d'avoir une autre information. Vous pouvez soit inverser l'ordre des élément dans la requête, soit typer explicitement le premier NULL en integer.
Julien.
https://rjuju.github.io/
Hors ligne
J'ai du mal avec cette explication:
abotest=# select null union select null union select 1;
ERROR: UNION types text and integer cannot be matched
LINE 1: select null union select null union select 1;
^
abotest=# rollback;
ROLLBACK
abotest=# select null union select 1;
?column?
----------
1
(2 rows)
Si ce que vous dites est vrai, alors select null union select 1 devrait planter aussi, or ce n'est pas le cas. En fait le souci se pose quand il y a deux null et un n°.
Hors ligne
Non, le soucis est que la norme sql impose de résoudre les types par "couple d'ensemble", donc deux par deux plutôt que globalement.
Julien.
https://rjuju.github.io/
Hors ligne
La norme SQL impose? En oracle ca marche en tout cas.
SQL> select null from dual union select null from dual union select 1 from dual;
NULL
----------
1
En access aussi.
Hors ligne
Et bien ni oracle ni access ne respectent la norme SQL sur ce point là.
Si vous voulez une référence : https://www.postgresql.org/message-id/9 … .pgh.pa.us
The reason we haven't done it is that it looks like the SQL standard requires type resolution for set-ops to happen one pair of input relations at a time. See SQL:2008 7.13 <query expression>, in which everything that's said about UNION/INTERSECT/EXCEPT is phrased in terms of exactly two input subqueries; for instance INTERSECT's result type is defined in syntax rule 18b as:
norme SQL a écrit :The declared type of the i-th column of TR is determined by applying Subclause 9.3, "Result of data type combinations", to the declared types of the i-th column of T1 and the i-th column of T2.
Julien.
https://rjuju.github.io/
Hors ligne
The declared type of the i-th column of TR is determined by applying Subclause 9.3, "Result of data type combinations", to the declared types of the i-th column of T1 and the i-th column of T2.
1. Null union null=null
2. Null union int=int.
Je ne vois aucune raison d'assigner un type texte quand il n'y en a pas.
Hors ligne
Le problème est justement que NULL n'a pas de type, et qu'un champ doit avoir un type. Donc à défaut d'avoir pu trouver un type, NULL UNION NULL est résolu en text, probablement parce que c'est le type qui posera le moins de soucis.
Julien.
https://rjuju.github.io/
Hors ligne