OVH Cloud OVH Cloud

insert conditionnel

27 réponses
Avatar
Etienne SOBOLE
c'est possible de faire un insert dans une table sous condition?

j'ai un table qui relie un contact a une société
et je voudrai faire l'insertion dans cette table que si l'entrée n'existe
pas deja !

genre
INSERT INTO lien WHERE idsoc = 5 AND idctc = 9 .... if l'entrée n'existe pas
deja !!!

merci
Etienne

10 réponses

1 2 3
Avatar
Fred Brouard - SQLpro
Hugues a écrit:


l'index unique est plus performant.
Avec certaines versions d'oracle (je n'ai pas encore testé la 10g), il
est plus performant d'ajouter un test sur le rownum
INSERT INTO T_TEST
SELECT 1, 'NORD'
FROM DUAL
WHERE NOT EXISTS (SELECT *
FROM T_TEST
WHERE COL1 = 1
AND COL2 = 'NORD'
AND ROWNUM < 1)

ce qui permet de ne retourner que la premiere ligne dans le sous select.
J'avais vu une différence sur des gros traitements batchs (plan
d'execution avec un STOP dedans)

Dans tous les cas, je suis persuadé que l'index unique sera plus
performant. Ou encore mieux une contrainte d'intégrité unique.




ROWNUM n'existe pas en SQL... C'est propre à Oracle (comme DUAL d'ailleur).
Sous SQL:2003 la fonction ROW_NUMBER() a été ajoutée

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 *************************
Avatar
Hugues
Etienne SOBOLE a écrit :
Avec certaines versions d'oracle (je n'ai pas encore testé la 10g), il est
plus performant d'ajouter un test sur le rownum
INSERT INTO T_TEST
SELECT 1, 'NORD'
FROM DUAL
WHERE NOT EXISTS (SELECT *
FROM T_TEST
WHERE COL1 = 1
AND COL2 = 'NORD'
AND ROWNUM < 1)




oui mais tout le monde n'est pas sous oracle ;)




Les personnes qui sont sous d'autres SGBD sauront optimiser au maximum
les requêtes sous leur systeme (menfin, j'espere... j'ai déjà tellement
vu de systèmes/applis HS pour cause d'erreur de programmation)
Avatar
Hugues
Fred Brouard - SQLpro a écrit :


Hugues a écrit:


l'index unique est plus performant.
Avec certaines versions d'oracle (je n'ai pas encore testé la 10g), il
est plus performant d'ajouter un test sur le rownum
INSERT INTO T_TEST
SELECT 1, 'NORD'
FROM DUAL
WHERE NOT EXISTS (SELECT *
FROM T_TEST
WHERE COL1 = 1
AND COL2 = 'NORD'
AND ROWNUM < 1)

ce qui permet de ne retourner que la premiere ligne dans le sous
select. J'avais vu une différence sur des gros traitements batchs
(plan d'execution avec un STOP dedans)

Dans tous les cas, je suis persuadé que l'index unique sera plus
performant. Ou encore mieux une contrainte d'intégrité unique.




ROWNUM n'existe pas en SQL... C'est propre à Oracle (comme DUAL d'ailleur).
Sous SQL:2003 la fonction ROW_NUMBER() a été ajoutée

A +




Mais la question de base, c'était l'aspect facilité d'écriture et
l'aspect performance.

sous oracle, la meilleure solution, c'est la contrainte unique avec un
test de l'exception si on est dans un language style pl/sql pour eviter
un plantage.

Après, si une nouvelle definition sql définit mieux, il faudra faire des
tests de performance entre les ordres "adaptable à la oracle" et les
possibilités de la nouvelle norme.
Avatar
see
Hugues wrote:

Avec certaines versions d'oracle (je n'ai pas encore testé la 10g), il
est plus performant d'ajouter un test sur le rownum
INSERT INTO T_TEST
SELECT 1, 'NORD'
FROM DUAL
WHERE NOT EXISTS (SELECT *
FROM T_TEST
WHERE COL1 = 1
AND COL2 = 'NORD'
AND ROWNUM < 1)

ce qui permet de ne retourner que la premiere ligne dans le sous select.
J'avais vu une différence sur des gros traitements batchs (plan
d'execution avec un STOP dedans)



Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.

À noter : l'instruction merge est disponible avec la 9i

--
Bruno
http://errance.lirano.net (photographies)
Avatar
Yves Calvet
Bruno Jargot a écrit :

Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.



fais un rapport de bug: le gens d'Oracle ont aussi le droit de se marrer
:-)


--
Yves Calvet
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html
Avatar
Hugues
Yves Calvet a écrit :
Bruno Jargot a écrit :


Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.




fais un rapport de bug: le gens d'Oracle ont aussi le droit de se marrer
:-)




Plus on fournit d'info au moteur de base de données, moins il a de chose
à déduire par lui même et meilleures sont les perfs.
Effectivement, il y a bcp de développeurs qui n'ont aucune idée de
comment ça marche derrière (analyse sémantique, compilation,
fonctionnement des différents niveaux de caches, etc...) et écrive
n'importe comment, et ne comprennent pas ensuite que les perfs soit
mauvaises.
C'est sur que sur une bête requête à 1 ou 2 tables, le noyau fait plein
de choses tout seul. Quand tu atteindras les 30 ou 50 tables avec
différents niveaux d'agrégats... dans tes requêtes, tu comprendras que
tout petit peu aide et sera moins ironique.
Avatar
Fred Brouard - SQLpro
L'otpimiseur d'Oracle est si mauvais que cela qu'il n'est pas capable de lui
même de trouver un bon plan d'exécution et de tirer partie de ses propres
structures internes ???

;-)

A +

Hugues a écrit:
Yves Calvet a écrit :

Bruno Jargot a écrit :


Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.





fais un rapport de bug: le gens d'Oracle ont aussi le droit de se
marrer :-)




Plus on fournit d'info au moteur de base de données, moins il a de chose
à déduire par lui même et meilleures sont les perfs.
Effectivement, il y a bcp de développeurs qui n'ont aucune idée de
comment ça marche derrière (analyse sémantique, compilation,
fonctionnement des différents niveaux de caches, etc...) et écrive
n'importe comment, et ne comprennent pas ensuite que les perfs soit
mauvaises.
C'est sur que sur une bête requête à 1 ou 2 tables, le noyau fait plein
de choses tout seul. Quand tu atteindras les 30 ou 50 tables avec
différents niveaux d'agrégats... dans tes requêtes, tu comprendras que
tout petit peu aide et sera moins ironique.



--
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
Hugues
Non, il est tres bon. Mais je part du principe que tout info donnée à
l'optimiseur va lui simplifier la vie, donc lui faire gagner du temps.
Peut etre a tu déjà écrit des compilateurs ou des moteurs de recherche.
Dans ce cas, tu comprendras plus facilement ma pensée.


Mais en prenant un cas simple :
select * from t1 where id in (select id from t2 where ...)

l'optimiseur va travailler correctement et faire un
select * from t1, t2 where t1.id = t2.id and ...

mais ça, ce n'est pas un travail d'optimiseur mais plutot au développeur
de le faire. Et puis, pour faire cette transformation, le noyau a du
bosser, donc ça prend du temps.

La, c'était un cas très simple. Mais tu dois savoir qu'il y a
fréquemment des requêtes avec des dizaines de tables, dans des
traitements batch, que le temps est limité (car la sauvegarde démarre à
3h du mat et qu'il faut avoir fini avant)...

D'autres cas encore nécessite de l'intelligence coté développeur.
par exemple, utiliser des variables de bind pour que le plan d'execution
soit la pour la fois suivante (select * from t1 where id = :v)
mais quand on fait un (select * from t1 where nom like :v), l'optimiseur
a de forte chance de faire un full table scan car il n'a aucune idée de
ce que contient la variable. Encore du travail pour le -bon- développeur
(soit pas de bind, soit mettre un hint pour guider l'optimiseur). Mais
en général, le -mauvais- développeur, il n'en a rien à faire et demande
à l'administrateur d'ajouter des cpu ou de la ram.

Fred Brouard - SQLpro a écrit :
L'otpimiseur d'Oracle est si mauvais que cela qu'il n'est pas capable de
lui même de trouver un bon plan d'exécution et de tirer partie de ses
propres structures internes ???

;-)

A +

Hugues a écrit:

Yves Calvet a écrit :

Bruno Jargot a écrit :


Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.






fais un rapport de bug: le gens d'Oracle ont aussi le droit de se
marrer :-)




Plus on fournit d'info au moteur de base de données, moins il a de
chose à déduire par lui même et meilleures sont les perfs.
Effectivement, il y a bcp de développeurs qui n'ont aucune idée de
comment ça marche derrière (analyse sémantique, compilation,
fonctionnement des différents niveaux de caches, etc...) et écrive
n'importe comment, et ne comprennent pas ensuite que les perfs soit
mauvaises.
C'est sur que sur une bête requête à 1 ou 2 tables, le noyau fait
plein de choses tout seul. Quand tu atteindras les 30 ou 50 tables
avec différents niveaux d'agrégats... dans tes requêtes, tu
comprendras que tout petit peu aide et sera moins ironique.




Avatar
Fred Brouard - SQLpro
je connais bien tout cela, mais le contraire est aussi vrai.

A force de forcer un plan de requête ce dernier peut s'avérer mauvais à la
montée en charge.

L'optimisation est donc plutôt à faire après montée en charge et en récrivant la
requête sans tag si possible. Si tout cela échoue alors taguer pour obliger
certains verrous.

Mais donner de but en blanc une requête aussi tordue et spécifique n'est
franchement pas une bonne chose !

A +

Hugues a écrit:
Non, il est tres bon. Mais je part du principe que tout info donnée à
l'optimiseur va lui simplifier la vie, donc lui faire gagner du temps.
Peut etre a tu déjà écrit des compilateurs ou des moteurs de recherche.
Dans ce cas, tu comprendras plus facilement ma pensée.


Mais en prenant un cas simple :
select * from t1 where id in (select id from t2 where ...)

l'optimiseur va travailler correctement et faire un
select * from t1, t2 where t1.id = t2.id and ...

mais ça, ce n'est pas un travail d'optimiseur mais plutot au développeur
de le faire. Et puis, pour faire cette transformation, le noyau a du
bosser, donc ça prend du temps.

La, c'était un cas très simple. Mais tu dois savoir qu'il y a
fréquemment des requêtes avec des dizaines de tables, dans des
traitements batch, que le temps est limité (car la sauvegarde démarre à
3h du mat et qu'il faut avoir fini avant)...

D'autres cas encore nécessite de l'intelligence coté développeur.
par exemple, utiliser des variables de bind pour que le plan d'execution
soit la pour la fois suivante (select * from t1 where id = :v)
mais quand on fait un (select * from t1 where nom like :v), l'optimiseur
a de forte chance de faire un full table scan car il n'a aucune idée de
ce que contient la variable. Encore du travail pour le -bon- développeur
(soit pas de bind, soit mettre un hint pour guider l'optimiseur). Mais
en général, le -mauvais- développeur, il n'en a rien à faire et demande
à l'administrateur d'ajouter des cpu ou de la ram.

Fred Brouard - SQLpro a écrit :

L'otpimiseur d'Oracle est si mauvais que cela qu'il n'est pas capable
de lui même de trouver un bon plan d'exécution et de tirer partie de
ses propres structures internes ???

;-)

A +

Hugues a écrit:

Yves Calvet a écrit :

Bruno Jargot a écrit :


Tu veux dire que le moteur Oracle n'est pas capable de s'arrêter tout
seul à la première occurence trouvée ?
À ce niveau, je suppose qu'il s'agit d'un bug.







fais un rapport de bug: le gens d'Oracle ont aussi le droit de se
marrer :-)




Plus on fournit d'info au moteur de base de données, moins il a de
chose à déduire par lui même et meilleures sont les perfs.
Effectivement, il y a bcp de développeurs qui n'ont aucune idée de
comment ça marche derrière (analyse sémantique, compilation,
fonctionnement des différents niveaux de caches, etc...) et écrive
n'importe comment, et ne comprennent pas ensuite que les perfs soit
mauvaises.
C'est sur que sur une bête requête à 1 ou 2 tables, le noyau fait
plein de choses tout seul. Quand tu atteindras les 30 ou 50 tables
avec différents niveaux d'agrégats... dans tes requêtes, tu
comprendras que tout petit peu aide et sera moins ironique.










--
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
\(¯`·..Yttrium ...·´¯\)
"Hugues" a écrit dans le message de news:
42a430e9$0$25834$

[...] Encore du travail pour le -bon- développeur [...]
[...] le -mauvais- développeur, il n'en a rien à faire et demande [...]



Bonjour,

De l'art de distinguer le *bon* développeur du *mauvais* développeur....

Salutations.
1 2 3