OVH Cloud OVH Cloud

question cursor

7 réponses
Avatar
jeorme
Bonjour à tous

Simple question:
Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire les
boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?

C'est pour info car de toutes façons les deux marchent.

A+

7 réponses

Avatar
bruno reiter [MVP]
il vaut mieux une procédure sans curseur

br

"jeorme" wrote in message
news:
Bonjour à tous

Simple question:
Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire les
boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?

C'est pour info car de toutes façons les deux marchent.

A+




Avatar
Fred BROUARD
Oh que oui !

ne pas oublier que par défaut un curseur est perméable aux modifications qui
s'opèrent en cours de route.

Dans 99% des cas ou je voit un curseur dans le code, on peut s'en passer !

A +

bruno reiter [MVP] a écrit:
il vaut mieux une procédure sans curseur

br

"jeorme" wrote in message
news:

Bonjour à tous

Simple question:
Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire les
boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?

C'est pour info car de toutes façons les deux marchent.

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
Philippe T [MS]
Bonjour,

Travailler de façon ensembliste pour SQL est naturel. Il est plus facile
pour un SGBD de traiter plusieurs enregistrements simultanéments que de
traiter les enregistrements les uns après les autres.

Après, lorsque l'on a pas le choix, il est possible d'utiliser un curseur
mais dans ces conditions, il faut privilégier des clauses de type
FAST_FORWARD par exemple pour optimiser les traitements du curseur.

Phil.
________________________________________________________
Philippe TROTIN http://blogs.msdn.com/ptrotin
Microsoft Services France http://www.microsoft.com/france

"Fred BROUARD" wrote in message
news:#
Oh que oui !

ne pas oublier que par défaut un curseur est perméable aux modifications


qui
s'opèrent en cours de route.

Dans 99% des cas ou je voit un curseur dans le code, on peut s'en passer !

A +

bruno reiter [MVP] a écrit:
> il vaut mieux une procédure sans curseur
>
> br
>
> "jeorme" wrote in message
> news:
>
>>Bonjour à tous
>>
>>Simple question:
>>Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire


les
>>boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?
>>
>>C'est pour info car de toutes façons les deux marchent.
>>
>>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
jeorme
Merci à vous pour les infos. Donc si je récapitule il vaut mieux faire les
boucles sur l'interface et faire des PS simples dans SQL Server.



"Philippe T [MS]" a écrit dans le message de
news:
Bonjour,

Travailler de façon ensembliste pour SQL est naturel. Il est plus facile
pour un SGBD de traiter plusieurs enregistrements simultanéments que de
traiter les enregistrements les uns après les autres.

Après, lorsque l'on a pas le choix, il est possible d'utiliser un curseur
mais dans ces conditions, il faut privilégier des clauses de type
FAST_FORWARD par exemple pour optimiser les traitements du curseur.

Phil.
________________________________________________________
Philippe TROTIN http://blogs.msdn.com/ptrotin
Microsoft Services France http://www.microsoft.com/france

"Fred BROUARD" wrote in message
news:#
> Oh que oui !
>
> ne pas oublier que par défaut un curseur est perméable aux modifications
qui
> s'opèrent en cours de route.
>
> Dans 99% des cas ou je voit un curseur dans le code, on peut s'en passer


!
>
> A +
>
> bruno reiter [MVP] a écrit:
> > il vaut mieux une procédure sans curseur
> >
> > br
> >
> > "jeorme" wrote in message
> > news:
> >
> >>Bonjour à tous
> >>
> >>Simple question:
> >>Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire
les
> >>boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?
> >>
> >>C'est pour info car de toutes façons les deux marchent.
> >>
> >>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
Fred BROUARD
non, c'est pas du tout ce que l'on a dit :

Il vaut mieux toujours utiliser des procédures stockées, mêmes très complexe
sans jamais utiliser des boucles et des curseurs en utilisant des requêtes SQL.

Le code client avec des boucles revient à utiliser un curseur puisque c'est le
seul moyen dont le client peut accéder aux données.
Comme c'est en plus distant tu cumule tous les inconvénients.

Un petit exemple :

**************************************************************************
soit un forum modélisé de la façon suivante :

-- table : T_FORUM_FRM
CREATE TABLE T_FORUM_FRM
( FRM_ID INTEGER NOT NULL PRIMARY KEY,
FRM_NOM CHAR(64) NOT NULL,
FRM_SUJET VARCHAR(256) NULL,
FRM_DATE_CREATION DATETIME NOT NULL)

--- table : T_NEWS_NEW
CREATE TABLE T_NEWS_NEW
( NEW_ID INTEGER NOT NULL PRIMARY KEY,
NEW_ID_PERE INTEGER NULL,
USR_ID INTEGER NOT NULL,
FRM_ID INTEGER NOT NULL,
NEW_MOMENT DATETIME NOT NULL,
NEW_GLOBAL_ID CHAR(16) NOT NULL,
NEW_TITRE CHAR(256) NOT NULL,
NEW_TEXT CLOB(2 GB) NULL,
constraint FK_NEW_FRM foreign key (FRM_ID)
references T_FORUM_FRM (FRM_ID),
constraint FK_NEW_USR foreign key (USR_ID)
references T_UTILISATEUR_USR (USR_ID),
constraint FK_NEW_NEW foreign key (NEW_ID_PERE)
references T_NEWS_NEW (NEW_ID))

-- table : T_UTILISATEUR_USR
CREATE TABLE T_UTILISATEUR_USR
( USR_ID INTEGER NOT NULL PRIMARY KEY,
USR_MAIL VARCHAR(256) NOT NULL,
USR_TITRE CHAR(6) NULL DEFAULT 'M.'
CHECK (USR_TITRE IN ('M.', 'Mlle.', 'Mme.')),
USR_NOM CHAR(32) NULL,
USR_PRENOM VARCHAR(32) NULL,
USR_ORGANISATION VARCHAR(128) NULL)


**************************************************************************
et les données suivantes :


INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (1, '', 'M.', 'DUPONT', 'François', 'IBM')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (2, '', 'M.', 'DUVAL', 'Éric', NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (3, '', 'Mlle.', 'ENTE', 'Aurélia', 'AOL');
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (4, '', 'M.', 'MÜLLER', 'Marcel', 'Bell
Telephone Cie.')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (6, '', 'M.', 'Martin', NULL, 'IBM')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (7, '', 'M.', 'LEROY', 'Olivier', NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (9, '', 'M.', 'COWARD', 'John Leslie', 'O_A_C_I')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (10, '', 'M.', 'PRUD''HOMME',
'Étienne', 'Air France')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (11, '', 'Mlle.', 'MAILLANT',
'Catherine', 'FreeSurf International')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (14, '', 'Mlle.', 'CÉSARI', NULL, NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (15, '', 'M.', 'CLERC', 'François', 'SNCF')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (16, '', 'M.', 'DUPONT', 'Charles', 'AOL
france')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (18, '', 'Mme.', 'LEROY', 'Émilie', 'AOL')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (20, '', 'M.', 'VALLADON', 'Antoine', 'FREE')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (21, '', 'Mme.', 'BIDAULT', NULL, NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (22, '', 'M.', 'HERMEX', NULL, 'CEGETEL USA')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (25, '', 'M.', 'DUPONT', 'Charles', 'Wanadoo')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM, USR_PRENOM,
USR_ORGANISATION)
VALUES (27, '', 'M.', 'MAILLANT', NULL, 'France Free')


INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (1, 'fr.comp.applications.sgbd', 'Bases de données', '1996-11-18
20:52:23')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (2, 'comp.databases.ibm-db2', 'RDBMS IBM DB2', '1997-02-19 16:22:41')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (3, 'comp.databases.informix', 'RDBMS IBM INFORMIX', '2001-03-21
05:02:11')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (4, 'comp.databases.ms-access', 'RDBMS Microsoft Access',
'1998-06-11 23:17:16')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (5, 'comp.databases.ms-sqlserver', 'RDBMS Microsoft SQL Server',
'1997-07-20 11:47:59')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (6, 'comp.databases.olap', 'OLAP', '1998-11-12 17:16:15')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (7, 'comp.databases.oracle', 'RDBMS ORACLE', '1997-03-01 10:10:09')

INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (1, NULL, 2, 1, '2005-01-30 20:53:53',
'51271217-1346-46DA-866B-512D00E5C129', 'Quid des marqueurs NULL ?', 'Sont-ils
indispensable ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (2, 1, 2, 1, '2005-01-31 20:59:46',
'660731A0-2C26-43F6-BA4E-A219B51920B5', 'mon expérience des marqueurs NULL',
'Indispensable, parce que sémantiquement important')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (3, NULL, 1, 7, '2005-02-01 16:23:21',
'90475A12-7357-4AF5-BF37-3C17B332129E', 'L''objet dans le serveur', 'Ca sert à
quoi ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (4, 3, 4, 7, '2005-02-02 14:56:16',
'D8D3E3A1-C00A-4542-B909-625E2B101A86', 'Rien de bon!', 'C''est anti relationnel')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (5, 4, 6, 7, '2005-02-02 15:09:11',
'12AF4602-DB3E-4CF3-B89D-1A5A21215C99', 'Mais si au contraire!', 'C''est fait
pour travailler avec des langages objet comme C++ ou Java')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (6, NULL, 15, 1, '2005-02-02 18:17:12',
'87084D0A-C202-454B-AB94-088E2E651EF9', 'Jointure ou sous requête ?', 'Quelle
est la meilleure technique ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (7, 1, 11, 1, '2005-02-02 19:18:17',
'E30933F5-1EFF-4C09-835F-4AF9449B4333', 'Quid des marqueurs NULL ?', 'Moi je met
toujours NOT NULL comme ça j''ai pas d''ennuis.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (8, 1, 7, 1, '2005-01-30 11:16:22',
'6B7DB439-ACDF-4B42-9D4C-BCC86D365FF7', 'Quid des marqueurs NULL ?', 'Pourquoi
pas des marqueurs pour INFINI ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (9, 8, 11, 1, '2005-02-03 17:21:42',
'DEEC380E-5E9E-4260-87F4-3DC748060B76', 'Quid des marqueurs NULL ?', 'Le docteur
CODD et Chris DATE y ont déjà pensé et D. McGoveran à proposé mieux.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (10, NULL, 6, 2, '2005-02-04 11:17:39',
'B6E8D09D-A1BC-440E-A3E3-C50EDA48A0CE', 'Le SQL de DB2', 'Le SQL d''IBM DB2
est-il très normatif ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (11, 10, 22, 2, '2005-02-04 21:41:53',
'1353E2DB-9510-44D8-A763-10F5CB59445D', 'Le SQL de DB2', 'Assurément, mais il
manque quelques éléments')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (12, 10, 14, 2, '2005-02-04 22:00:09',
'ACEF8DFD-1DD7-499F-83BD-BB9C74BDA64E', 'Le SQL de DB2', 'A mon avis c''est le
plus proche de la norme')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (13, NULL, 10, 6, '2005-02-05 09:17:08',
'66848669-62D0-45FE-8214-2047487EF123', 'GROUPING', 'A quoi sert GROUPIN ? GROUP
BY ne suffit-il pas ??')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (15, NULL, 16, 5, '2005-02-09 07:59:58',
'33FA97E5-C0D9-4C2D-BFD8-C5976D1DE5BC', 'Procédure stockée', 'A quoi sert le
niveau d''isolation READ UNCOMMITED ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (16, 15, 18, 5, '2005-02-11 20:19:28',
'EB328538-321E-4DDC-9FFB-FA934E3A2C9E', 'Procédure stockée', 'C''est de la
lecture sale !')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (17, 15, 4, 5, '2005-02-12 13:47:52',
'5358EC89-776C-4104-AE49-781791EF3044', 'Procédure stockée', 'On peut lire des
données non encore validées. C''est dangereux sauf pour une base de données
documentaire')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (19, 16, 2, 5, '2005-02-13 17:47:55',
'5EFA0332-443F-4E6D-9F14-8F93C098C9BA', 'Procédure stockée', 'Le terme technique
est : "lecture impropre".')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (20, NULL, 6, 3, '2005-02-14 15:52:28',
'8C6D1DC3-80D8-4C3E-843E-2BE01F357A44', 'Remplacer INFORMIX', 'Quelle est le
meilleur SGBD pour remplacer INFORMIX ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (21, NULL, 2, 4, '2005-02-17 10:47:52',
'1ED2486A-09DC-432F-B81F-D5906B4CD754', 'Doublons', 'A quoi sert DISTINCTROW ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (22, 21, 14, 4, '2005-02-17 18:11:44',
'5F3FB845-0947-43E5-89B6-006FBB74189D', 'Doublons', 'C''est particulier à Access
: dédoublonnement de ligne de table, mais pas du résultat !')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (23, 22, 2, 4, '2005-02-17 19:44:22',
'5410F92E-B996-4372-8064-C9E5726B7C6B', 'Doublons', 'D''accord, merci.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (24, NULL, 7, 4, '2005-02-19 08:59:00',
'A1DB8A83-8903-49CE-9AE6-4AFDE4213567', 'Doublons', 'D''accord, merci.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (25, NULL, 2, 1, '2005-02-20 16:42:51',
'56E09F83-FD53-49BA-89EE-013FB883F454', 'Les transactions', 'Une étude sur le
sujet. Voir PJ')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (26, NULL, 6, 2, '2005-02-20 16:54:15',
'BA5FDBB9-D34C-4B15-98F4-56416A60C706', 'DATALINK', 'Est-ce une spécialité IBM
DB2 ou est-ce dans SQL ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (28, 21, 2, 4, '2005-02-21 11:33:22',
'63BADCE4-BA5B-4950-8EEB-D2203C142899', 'Doublons', 'Finalement j''ai rien
compris au DISTINCTROW...')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (29, NULL, 2, 5, '2005-02-21 16:21:39',
'D5EEBF6D-6461-4250-871F-04D4222428A5', 'Doublons', 'Le DISTINCTROW d''Access
existe sous SQL Server ? C''est équivalent à DISTINCT ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (30, NULL, 9, 6, '2005-02-22 09:33:46',
'7D1FDA98-F322-49AA-93AE-8633397893ED', 'Datamining', 'Qui pourrait me
conseiller un bon livre sur le datamining/datamart ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (31, NULL, 4, 7, '2005-02-23 09:58:59',
'74578638-5C7B-48DC-8458-ECE9B9B08F5A', 'Livres sur Oracle', 'Quels sont les
meilleurs ouvrages sur le PL/SQL d''Oracle ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (32, 31, 6, 7, '2005-02-23 11:28:13',
'924B5F1F-894D-4AFB-ABC6-C9B14596EBB7', 'Livres sur Oracle', 'SQL pour Oracle de
Soutou et Teste')

**************************************************************************
Énoncé du problème :

Donnez le nom des forums dont aucun utilisateur n'a posté plus d'une news.
**************************************************************************


SOLUTION :

SELECT DISTINCT FRM.FRM_ID, FRM.FRM_NOM
FROM T_NEWS_NEW NEW
INNER JOIN T_FORUM_FRM FRM
ON NEW.FRM_ID = FRM.FRM_ID
GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
HAVING COUNT(*) = ALL (SELECT COUNT(*)
FROM T_NEWS_NEW
WHERE NEW.FRM_ID = FRM_ID
GROUP BY USR_ID, FRM_ID)
La requête suivante :
SELECT FRM.FRM_ID,USR_ID, COUNT(*) NEW_NOMBRE
FROM T_NEWS_NEW NEW
INNER JOIN T_FORUM_FRM FRM
ON NEW.FRM_ID = FRM.FRM_ID
GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
ORDER BY 1
...permet de trouver le nombre de news par forum et par utilisateur.
FRM_ID USR_ID NEW_NOMBRE
----------- ----------- -----------
1 2 3
1 7 1
1 11 2
1 15 1

2 6 2
2 14 1
2 22 1

3 6 1

4 2 3
4 7 1
4 14 1

5 2 2
5 4 1
5 16 1
5 18 1

6 9 1
6 10 1

7 1 1
7 4 2
7 6 2
D'après les résultats produit par cette requête, les forums à retenir, sont ceux
dans lesquels toutes les valeurs de la colonne NEW_NOMBRE sont égale à 1. C'est
le sens de la sous requête corrélée introduite par ALL.

Pas besoin de code client ni de curseur !

A +


jeorme a écrit:
Merci à vous pour les infos. Donc si je récapitule il vaut mieux faire les
boucles sur l'interface et faire des PS simples dans SQL Server.



"Philippe T [MS]" a écrit dans le message de
news:

Bonjour,

Travailler de façon ensembliste pour SQL est naturel. Il est plus facile
pour un SGBD de traiter plusieurs enregistrements simultanéments que de
traiter les enregistrements les uns après les autres.

Après, lorsque l'on a pas le choix, il est possible d'utiliser un curseur
mais dans ces conditions, il faut privilégier des clauses de type
FAST_FORWARD par exemple pour optimiser les traitements du curseur.

Phil.
________________________________________________________
Philippe TROTIN http://blogs.msdn.com/ptrotin
Microsoft Services France http://www.microsoft.com/france

"Fred BROUARD" wrote in message
news:#

Oh que oui !

ne pas oublier que par défaut un curseur est perméable aux modifications



qui

s'opèrent en cours de route.

Dans 99% des cas ou je voit un curseur dans le code, on peut s'en passer





!

A +

bruno reiter [MVP] a écrit:

il vaut mieux une procédure sans curseur

br

"jeorme" wrote in message
news:


Bonjour à tous

Simple question:
Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire







les

boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?

C'est pour info car de toutes façons les deux marchent.

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 *************************












--
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
Philippe T [MS]
Bonjour,

Je confirme ce que dit Fred : toujours favoriser des procédures stockées et
éviter si possible les curseurs !!!

Phil.
________________________________________________________
Philippe TROTIN http://blogs.msdn.com/ptrotin
Microsoft Services France http://www.microsoft.com/france

"Fred BROUARD" wrote in message
news:
non, c'est pas du tout ce que l'on a dit :

Il vaut mieux toujours utiliser des procédures stockées, mêmes très


complexe
sans jamais utiliser des boucles et des curseurs en utilisant des requêtes


SQL.

Le code client avec des boucles revient à utiliser un curseur puisque


c'est le
seul moyen dont le client peut accéder aux données.
Comme c'est en plus distant tu cumule tous les inconvénients.

Un petit exemple :

**************************************************************************
soit un forum modélisé de la façon suivante :

-- table : T_FORUM_FRM
CREATE TABLE T_FORUM_FRM
( FRM_ID INTEGER NOT NULL PRIMARY KEY,
FRM_NOM CHAR(64) NOT NULL,
FRM_SUJET VARCHAR(256) NULL,
FRM_DATE_CREATION DATETIME NOT NULL)

--- table : T_NEWS_NEW
CREATE TABLE T_NEWS_NEW
( NEW_ID INTEGER NOT NULL PRIMARY KEY,
NEW_ID_PERE INTEGER NULL,
USR_ID INTEGER NOT NULL,
FRM_ID INTEGER NOT NULL,
NEW_MOMENT DATETIME NOT NULL,
NEW_GLOBAL_ID CHAR(16) NOT NULL,
NEW_TITRE CHAR(256) NOT NULL,
NEW_TEXT CLOB(2 GB) NULL,
constraint FK_NEW_FRM foreign key (FRM_ID)
references T_FORUM_FRM (FRM_ID),
constraint FK_NEW_USR foreign key (USR_ID)
references T_UTILISATEUR_USR (USR_ID),
constraint FK_NEW_NEW foreign key (NEW_ID_PERE)
references T_NEWS_NEW (NEW_ID))

-- table : T_UTILISATEUR_USR
CREATE TABLE T_UTILISATEUR_USR
( USR_ID INTEGER NOT NULL PRIMARY KEY,
USR_MAIL VARCHAR(256) NOT NULL,
USR_TITRE CHAR(6) NULL DEFAULT 'M.'
CHECK (USR_TITRE IN ('M.', 'Mlle.', 'Mme.')),
USR_NOM CHAR(32) NULL,
USR_PRENOM VARCHAR(32) NULL,
USR_ORGANISATION VARCHAR(128) NULL)


**************************************************************************
et les données suivantes :


INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (1, '', 'M.', 'DUPONT', 'François', 'IBM')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (2, '', 'M.', 'DUVAL', 'Éric', NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (3, '', 'Mlle.', 'ENTE', 'Aurélia',


'AOL');
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (4, '', 'M.', 'MÜLLER', 'Marcel',


'Bell
Telephone Cie.')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (6, '', 'M.', 'Martin', NULL, 'IBM')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (7, '', 'M.', 'LEROY', 'Olivier', NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (9, '', 'M.', 'COWARD', 'John Leslie',


'O_A_C_I')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (10, '', 'M.', 'PRUD''HOMME',
'Étienne', 'Air France')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (11, '', 'Mlle.',


'MAILLANT',
'Catherine', 'FreeSurf International')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (14, '', 'Mlle.', 'CÉSARI', NULL, NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (15, '', 'M.', 'CLERC', 'François',


'SNCF')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (16, '', 'M.', 'DUPONT', 'Charles',


'AOL
france')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (18, '', 'Mme.', 'LEROY', 'Émilie',


'AOL')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (20, '', 'M.', 'VALLADON',


'Antoine', 'FREE')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (21, '', 'Mme.', 'BIDAULT', NULL, NULL)
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (22, '', 'M.', 'HERMEX', NULL,


'CEGETEL USA')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (25, '', 'M.', 'DUPONT', 'Charles',


'Wanadoo')
INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,


USR_PRENOM,
USR_ORGANISATION)
VALUES (27, '', 'M.', 'MAILLANT', NULL, 'France


Free')


INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (1, 'fr.comp.applications.sgbd', 'Bases de données',


'1996-11-18
20:52:23')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (2, 'comp.databases.ibm-db2', 'RDBMS IBM DB2', '1997-02-19


16:22:41')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (3, 'comp.databases.informix', 'RDBMS IBM INFORMIX',


'2001-03-21
05:02:11')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (4, 'comp.databases.ms-access', 'RDBMS Microsoft Access',
'1998-06-11 23:17:16')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (5, 'comp.databases.ms-sqlserver', 'RDBMS Microsoft SQL


Server',
'1997-07-20 11:47:59')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (6, 'comp.databases.olap', 'OLAP', '1998-11-12 17:16:15')
INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
VALUES (7, 'comp.databases.oracle', 'RDBMS ORACLE', '1997-03-01


10:10:09')

INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (1, NULL, 2, 1, '2005-01-30 20:53:53',
'51271217-1346-46DA-866B-512D00E5C129', 'Quid des marqueurs NULL ?',


'Sont-ils
indispensable ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (2, 1, 2, 1, '2005-01-31 20:59:46',
'660731A0-2C26-43F6-BA4E-A219B51920B5', 'mon expérience des marqueurs


NULL',
'Indispensable, parce que sémantiquement important')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (3, NULL, 1, 7, '2005-02-01 16:23:21',
'90475A12-7357-4AF5-BF37-3C17B332129E', 'L''objet dans le serveur', 'Ca


sert à
quoi ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (4, 3, 4, 7, '2005-02-02 14:56:16',
'D8D3E3A1-C00A-4542-B909-625E2B101A86', 'Rien de bon!', 'C''est anti


relationnel')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (5, 4, 6, 7, '2005-02-02 15:09:11',
'12AF4602-DB3E-4CF3-B89D-1A5A21215C99', 'Mais si au contraire!', 'C''est


fait
pour travailler avec des langages objet comme C++ ou Java')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (6, NULL, 15, 1, '2005-02-02 18:17:12',
'87084D0A-C202-454B-AB94-088E2E651EF9', 'Jointure ou sous requête ?',


'Quelle
est la meilleure technique ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (7, 1, 11, 1, '2005-02-02 19:18:17',
'E30933F5-1EFF-4C09-835F-4AF9449B4333', 'Quid des marqueurs NULL ?', 'Moi


je met
toujours NOT NULL comme ça j''ai pas d''ennuis.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (8, 1, 7, 1, '2005-01-30 11:16:22',
'6B7DB439-ACDF-4B42-9D4C-BCC86D365FF7', 'Quid des marqueurs NULL ?',


'Pourquoi
pas des marqueurs pour INFINI ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (9, 8, 11, 1, '2005-02-03 17:21:42',
'DEEC380E-5E9E-4260-87F4-3DC748060B76', 'Quid des marqueurs NULL ?', 'Le


docteur
CODD et Chris DATE y ont déjà pensé et D. McGoveran à proposé mieux.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (10, NULL, 6, 2, '2005-02-04 11:17:39',
'B6E8D09D-A1BC-440E-A3E3-C50EDA48A0CE', 'Le SQL de DB2', 'Le SQL d''IBM


DB2
est-il très normatif ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (11, 10, 22, 2, '2005-02-04 21:41:53',
'1353E2DB-9510-44D8-A763-10F5CB59445D', 'Le SQL de DB2', 'Assurément, mais


il
manque quelques éléments')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (12, 10, 14, 2, '2005-02-04 22:00:09',
'ACEF8DFD-1DD7-499F-83BD-BB9C74BDA64E', 'Le SQL de DB2', 'A mon avis


c''est le
plus proche de la norme')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (13, NULL, 10, 6, '2005-02-05 09:17:08',
'66848669-62D0-45FE-8214-2047487EF123', 'GROUPING', 'A quoi sert GROUPIN ?


GROUP
BY ne suffit-il pas ??')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (15, NULL, 16, 5, '2005-02-09 07:59:58',
'33FA97E5-C0D9-4C2D-BFD8-C5976D1DE5BC', 'Procédure stockée', 'A quoi sert


le
niveau d''isolation READ UNCOMMITED ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (16, 15, 18, 5, '2005-02-11 20:19:28',
'EB328538-321E-4DDC-9FFB-FA934E3A2C9E', 'Procédure stockée', 'C''est de la
lecture sale !')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (17, 15, 4, 5, '2005-02-12 13:47:52',
'5358EC89-776C-4104-AE49-781791EF3044', 'Procédure stockée', 'On peut lire


des
données non encore validées. C''est dangereux sauf pour une base de


données
documentaire')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (19, 16, 2, 5, '2005-02-13 17:47:55',
'5EFA0332-443F-4E6D-9F14-8F93C098C9BA', 'Procédure stockée', 'Le terme


technique
est : "lecture impropre".')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (20, NULL, 6, 3, '2005-02-14 15:52:28',
'8C6D1DC3-80D8-4C3E-843E-2BE01F357A44', 'Remplacer INFORMIX', 'Quelle est


le
meilleur SGBD pour remplacer INFORMIX ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (21, NULL, 2, 4, '2005-02-17 10:47:52',
'1ED2486A-09DC-432F-B81F-D5906B4CD754', 'Doublons', 'A quoi sert


DISTINCTROW ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (22, 21, 14, 4, '2005-02-17 18:11:44',
'5F3FB845-0947-43E5-89B6-006FBB74189D', 'Doublons', 'C''est particulier à


Access
: dédoublonnement de ligne de table, mais pas du résultat !')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (23, 22, 2, 4, '2005-02-17 19:44:22',
'5410F92E-B996-4372-8064-C9E5726B7C6B', 'Doublons', 'D''accord, merci.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (24, NULL, 7, 4, '2005-02-19 08:59:00',
'A1DB8A83-8903-49CE-9AE6-4AFDE4213567', 'Doublons', 'D''accord, merci.')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (25, NULL, 2, 1, '2005-02-20 16:42:51',
'56E09F83-FD53-49BA-89EE-013FB883F454', 'Les transactions', 'Une étude sur


le
sujet. Voir PJ')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (26, NULL, 6, 2, '2005-02-20 16:54:15',
'BA5FDBB9-D34C-4B15-98F4-56416A60C706', 'DATALINK', 'Est-ce une spécialité


IBM
DB2 ou est-ce dans SQL ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (28, 21, 2, 4, '2005-02-21 11:33:22',
'63BADCE4-BA5B-4950-8EEB-D2203C142899', 'Doublons', 'Finalement j''ai rien
compris au DISTINCTROW...')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (29, NULL, 2, 5, '2005-02-21 16:21:39',
'D5EEBF6D-6461-4250-871F-04D4222428A5', 'Doublons', 'Le DISTINCTROW


d''Access
existe sous SQL Server ? C''est équivalent à DISTINCT ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (30, NULL, 9, 6, '2005-02-22 09:33:46',
'7D1FDA98-F322-49AA-93AE-8633397893ED', 'Datamining', 'Qui pourrait me
conseiller un bon livre sur le datamining/datamart ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (31, NULL, 4, 7, '2005-02-23 09:58:59',
'74578638-5C7B-48DC-8458-ECE9B9B08F5A', 'Livres sur Oracle', 'Quels sont


les
meilleurs ouvrages sur le PL/SQL d''Oracle ?')
INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
VALUES (32, 31, 6, 7, '2005-02-23 11:28:13',
'924B5F1F-894D-4AFB-ABC6-C9B14596EBB7', 'Livres sur Oracle', 'SQL pour


Oracle de
Soutou et Teste')

**************************************************************************
Énoncé du problème :

Donnez le nom des forums dont aucun utilisateur n'a posté plus d'une news.
**************************************************************************


SOLUTION :

SELECT DISTINCT FRM.FRM_ID, FRM.FRM_NOM
FROM T_NEWS_NEW NEW
INNER JOIN T_FORUM_FRM FRM
ON NEW.FRM_ID = FRM.FRM_ID
GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
HAVING COUNT(*) = ALL (SELECT COUNT(*)
FROM T_NEWS_NEW
WHERE NEW.FRM_ID = FRM_ID
GROUP BY USR_ID, FRM_ID)
La requête suivante :
SELECT FRM.FRM_ID,USR_ID, COUNT(*) NEW_NOMBRE
FROM T_NEWS_NEW NEW
INNER JOIN T_FORUM_FRM FRM
ON NEW.FRM_ID = FRM.FRM_ID
GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
ORDER BY 1
...permet de trouver le nombre de news par forum et par utilisateur.
FRM_ID USR_ID NEW_NOMBRE
----------- ----------- -----------
1 2 3
1 7 1
1 11 2
1 15 1

2 6 2
2 14 1
2 22 1

3 6 1

4 2 3
4 7 1
4 14 1

5 2 2
5 4 1
5 16 1
5 18 1

6 9 1
6 10 1

7 1 1
7 4 2
7 6 2
D'après les résultats produit par cette requête, les forums à retenir,


sont ceux
dans lesquels toutes les valeurs de la colonne NEW_NOMBRE sont égale à 1.


C'est
le sens de la sous requête corrélée introduite par ALL.

Pas besoin de code client ni de curseur !

A +


jeorme a écrit:
> Merci à vous pour les infos. Donc si je récapitule il vaut mieux faire


les
> boucles sur l'interface et faire des PS simples dans SQL Server.
>
>
>
> "Philippe T [MS]" a écrit dans le message


de
> news:
>
>>Bonjour,
>>
>>Travailler de façon ensembliste pour SQL est naturel. Il est plus facile
>>pour un SGBD de traiter plusieurs enregistrements simultanéments que de
>>traiter les enregistrements les uns après les autres.
>>
>>Après, lorsque l'on a pas le choix, il est possible d'utiliser un


curseur
>>mais dans ces conditions, il faut privilégier des clauses de type
>>FAST_FORWARD par exemple pour optimiser les traitements du curseur.
>>
>>Phil.
>>________________________________________________________
>>Philippe TROTIN http://blogs.msdn.com/ptrotin
>>Microsoft Services France http://www.microsoft.com/france
>>
>>"Fred BROUARD" wrote in message
>>news:#
>>
>>>Oh que oui !
>>>
>>>ne pas oublier que par défaut un curseur est perméable aux


modifications
>>
>>qui
>>
>>>s'opèrent en cours de route.
>>>
>>>Dans 99% des cas ou je voit un curseur dans le code, on peut s'en


passer
>
> !
>
>>>A +
>>>
>>>bruno reiter [MVP] a écrit:
>>>
>>>>il vaut mieux une procédure sans curseur
>>>>
>>>>br
>>>>
>>>>"jeorme" wrote in message
>>>>news:
>>>>
>>>>
>>>>>Bonjour à tous
>>>>>
>>>>>Simple question:
>>>>>Je fais des pages ASP avec une base SQL derrière. Vaut il mieux faire
>>
>>les
>>
>>>>>boucles dans la pages ASP ou faire une PS sur SQL avec des cursors ?
>>>>>
>>>>>C'est pour info car de toutes façons les deux marchent.
>>>>>
>>>>>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 *************************
>>>
>>
>>
>
>

--
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
jeorme
merci beaucoup à tous les deux pour ces infos.

Je vais tacher de me tenir à ce que vous avez dit.

A+




"Philippe T [MS]" a écrit dans le message de
news:
Bonjour,

Je confirme ce que dit Fred : toujours favoriser des procédures stockées


et
éviter si possible les curseurs !!!

Phil.
________________________________________________________
Philippe TROTIN http://blogs.msdn.com/ptrotin
Microsoft Services France http://www.microsoft.com/france

"Fred BROUARD" wrote in message
news:
> non, c'est pas du tout ce que l'on a dit :
>
> Il vaut mieux toujours utiliser des procédures stockées, mêmes très
complexe
> sans jamais utiliser des boucles et des curseurs en utilisant des


requêtes
SQL.
>
> Le code client avec des boucles revient à utiliser un curseur puisque
c'est le
> seul moyen dont le client peut accéder aux données.
> Comme c'est en plus distant tu cumule tous les inconvénients.
>
> Un petit exemple :
>
>


**************************************************************************
> soit un forum modélisé de la façon suivante :
>
> -- table : T_FORUM_FRM
> CREATE TABLE T_FORUM_FRM
> ( FRM_ID INTEGER NOT NULL PRIMARY KEY,
> FRM_NOM CHAR(64) NOT NULL,
> FRM_SUJET VARCHAR(256) NULL,
> FRM_DATE_CREATION DATETIME NOT NULL)
>
> --- table : T_NEWS_NEW
> CREATE TABLE T_NEWS_NEW
> ( NEW_ID INTEGER NOT NULL PRIMARY KEY,
> NEW_ID_PERE INTEGER NULL,
> USR_ID INTEGER NOT NULL,
> FRM_ID INTEGER NOT NULL,
> NEW_MOMENT DATETIME NOT NULL,
> NEW_GLOBAL_ID CHAR(16) NOT NULL,
> NEW_TITRE CHAR(256) NOT NULL,
> NEW_TEXT CLOB(2 GB) NULL,
> constraint FK_NEW_FRM foreign key (FRM_ID)
> references T_FORUM_FRM (FRM_ID),
> constraint FK_NEW_USR foreign key (USR_ID)
> references T_UTILISATEUR_USR (USR_ID),
> constraint FK_NEW_NEW foreign key (NEW_ID_PERE)
> references T_NEWS_NEW (NEW_ID))
>
> -- table : T_UTILISATEUR_USR
> CREATE TABLE T_UTILISATEUR_USR
> ( USR_ID INTEGER NOT NULL PRIMARY KEY,
> USR_MAIL VARCHAR(256) NOT NULL,
> USR_TITRE CHAR(6) NULL DEFAULT 'M.'
> CHECK (USR_TITRE IN ('M.', 'Mlle.', 'Mme.')),
> USR_NOM CHAR(32) NULL,
> USR_PRENOM VARCHAR(32) NULL,
> USR_ORGANISATION VARCHAR(128) NULL)
>
>
>


**************************************************************************
> et les données suivantes :
>
>
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (1, '', 'M.', 'DUPONT', 'François', 'IBM')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (2, '', 'M.', 'DUVAL', 'Éric', NULL)
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (3, '', 'Mlle.', 'ENTE', 'Aurélia',
'AOL');
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (4, '', 'M.', 'MÜLLER', 'Marcel',
'Bell
> Telephone Cie.')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (6, '', 'M.', 'Martin', NULL, 'IBM')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (7, '', 'M.', 'LEROY', 'Olivier', NULL)
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (9, '', 'M.', 'COWARD', 'John


Leslie',
'O_A_C_I')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (10, '', 'M.',


'PRUD''HOMME',
> 'Étienne', 'Air France')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (11, '', 'Mlle.',
'MAILLANT',
> 'Catherine', 'FreeSurf International')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (14, '', 'Mlle.', 'CÉSARI', NULL, NULL)
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (15, '', 'M.', 'CLERC',


'François',
'SNCF')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (16, '', 'M.', 'DUPONT', 'Charles',
'AOL
> france')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (18, '', 'Mme.', 'LEROY', 'Émilie',
'AOL')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (20, '', 'M.', 'VALLADON',
'Antoine', 'FREE')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (21, '', 'Mme.', 'BIDAULT', NULL, NULL)
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (22, '', 'M.', 'HERMEX', NULL,
'CEGETEL USA')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (25, '', 'M.', 'DUPONT', 'Charles',
'Wanadoo')
> INSERT INTO T_UTILISATEUR_USR (USR_ID, USR_MAIL, USR_TITRE, USR_NOM,
USR_PRENOM,
> USR_ORGANISATION)
> VALUES (27, '', 'M.', 'MAILLANT', NULL,


'France
Free')
>
>
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (1, 'fr.comp.applications.sgbd', 'Bases de données',
'1996-11-18
> 20:52:23')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (2, 'comp.databases.ibm-db2', 'RDBMS IBM DB2',


'1997-02-19
16:22:41')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (3, 'comp.databases.informix', 'RDBMS IBM INFORMIX',
'2001-03-21
> 05:02:11')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (4, 'comp.databases.ms-access', 'RDBMS Microsoft Access',
> '1998-06-11 23:17:16')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (5, 'comp.databases.ms-sqlserver', 'RDBMS Microsoft SQL
Server',
> '1997-07-20 11:47:59')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (6, 'comp.databases.olap', 'OLAP', '1998-11-12 17:16:15')
> INSERT INTO T_FORUM_FRM (FRM_ID, FRM_NOM, FRM_SUJET, FRM_DATE_CREATION)
> VALUES (7, 'comp.databases.oracle', 'RDBMS ORACLE', '1997-03-01
10:10:09')
>
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (1, NULL, 2, 1, '2005-01-30 20:53:53',
> '51271217-1346-46DA-866B-512D00E5C129', 'Quid des marqueurs NULL ?',
'Sont-ils
> indispensable ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (2, 1, 2, 1, '2005-01-31 20:59:46',
> '660731A0-2C26-43F6-BA4E-A219B51920B5', 'mon expérience des marqueurs
NULL',
> 'Indispensable, parce que sémantiquement important')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (3, NULL, 1, 7, '2005-02-01 16:23:21',
> '90475A12-7357-4AF5-BF37-3C17B332129E', 'L''objet dans le serveur', 'Ca
sert à
> quoi ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (4, 3, 4, 7, '2005-02-02 14:56:16',
> 'D8D3E3A1-C00A-4542-B909-625E2B101A86', 'Rien de bon!', 'C''est anti
relationnel')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (5, 4, 6, 7, '2005-02-02 15:09:11',
> '12AF4602-DB3E-4CF3-B89D-1A5A21215C99', 'Mais si au contraire!', 'C''est
fait
> pour travailler avec des langages objet comme C++ ou Java')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (6, NULL, 15, 1, '2005-02-02 18:17:12',
> '87084D0A-C202-454B-AB94-088E2E651EF9', 'Jointure ou sous requête ?',
'Quelle
> est la meilleure technique ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (7, 1, 11, 1, '2005-02-02 19:18:17',
> 'E30933F5-1EFF-4C09-835F-4AF9449B4333', 'Quid des marqueurs NULL ?',


'Moi
je met
> toujours NOT NULL comme ça j''ai pas d''ennuis.')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (8, 1, 7, 1, '2005-01-30 11:16:22',
> '6B7DB439-ACDF-4B42-9D4C-BCC86D365FF7', 'Quid des marqueurs NULL ?',
'Pourquoi
> pas des marqueurs pour INFINI ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (9, 8, 11, 1, '2005-02-03 17:21:42',
> 'DEEC380E-5E9E-4260-87F4-3DC748060B76', 'Quid des marqueurs NULL ?', 'Le
docteur
> CODD et Chris DATE y ont déjà pensé et D. McGoveran à proposé mieux.')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (10, NULL, 6, 2, '2005-02-04 11:17:39',
> 'B6E8D09D-A1BC-440E-A3E3-C50EDA48A0CE', 'Le SQL de DB2', 'Le SQL d''IBM
DB2
> est-il très normatif ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (11, 10, 22, 2, '2005-02-04 21:41:53',
> '1353E2DB-9510-44D8-A763-10F5CB59445D', 'Le SQL de DB2', 'Assurément,


mais
il
> manque quelques éléments')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (12, 10, 14, 2, '2005-02-04 22:00:09',
> 'ACEF8DFD-1DD7-499F-83BD-BB9C74BDA64E', 'Le SQL de DB2', 'A mon avis
c''est le
> plus proche de la norme')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (13, NULL, 10, 6, '2005-02-05 09:17:08',
> '66848669-62D0-45FE-8214-2047487EF123', 'GROUPING', 'A quoi sert GROUPIN


?
GROUP
> BY ne suffit-il pas ??')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (15, NULL, 16, 5, '2005-02-09 07:59:58',
> '33FA97E5-C0D9-4C2D-BFD8-C5976D1DE5BC', 'Procédure stockée', 'A quoi


sert
le
> niveau d''isolation READ UNCOMMITED ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (16, 15, 18, 5, '2005-02-11 20:19:28',
> 'EB328538-321E-4DDC-9FFB-FA934E3A2C9E', 'Procédure stockée', 'C''est de


la
> lecture sale !')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (17, 15, 4, 5, '2005-02-12 13:47:52',
> '5358EC89-776C-4104-AE49-781791EF3044', 'Procédure stockée', 'On peut


lire
des
> données non encore validées. C''est dangereux sauf pour une base de
données
> documentaire')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (19, 16, 2, 5, '2005-02-13 17:47:55',
> '5EFA0332-443F-4E6D-9F14-8F93C098C9BA', 'Procédure stockée', 'Le terme
technique
> est : "lecture impropre".')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (20, NULL, 6, 3, '2005-02-14 15:52:28',
> '8C6D1DC3-80D8-4C3E-843E-2BE01F357A44', 'Remplacer INFORMIX', 'Quelle


est
le
> meilleur SGBD pour remplacer INFORMIX ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (21, NULL, 2, 4, '2005-02-17 10:47:52',
> '1ED2486A-09DC-432F-B81F-D5906B4CD754', 'Doublons', 'A quoi sert
DISTINCTROW ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (22, 21, 14, 4, '2005-02-17 18:11:44',
> '5F3FB845-0947-43E5-89B6-006FBB74189D', 'Doublons', 'C''est particulier


à
Access
> : dédoublonnement de ligne de table, mais pas du résultat !')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (23, 22, 2, 4, '2005-02-17 19:44:22',
> '5410F92E-B996-4372-8064-C9E5726B7C6B', 'Doublons', 'D''accord, merci.')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (24, NULL, 7, 4, '2005-02-19 08:59:00',
> 'A1DB8A83-8903-49CE-9AE6-4AFDE4213567', 'Doublons', 'D''accord, merci.')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (25, NULL, 2, 1, '2005-02-20 16:42:51',
> '56E09F83-FD53-49BA-89EE-013FB883F454', 'Les transactions', 'Une étude


sur
le
> sujet. Voir PJ')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (26, NULL, 6, 2, '2005-02-20 16:54:15',
> 'BA5FDBB9-D34C-4B15-98F4-56416A60C706', 'DATALINK', 'Est-ce une


spécialité
IBM
> DB2 ou est-ce dans SQL ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (28, 21, 2, 4, '2005-02-21 11:33:22',
> '63BADCE4-BA5B-4950-8EEB-D2203C142899', 'Doublons', 'Finalement j''ai


rien
> compris au DISTINCTROW...')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (29, NULL, 2, 5, '2005-02-21 16:21:39',
> 'D5EEBF6D-6461-4250-871F-04D4222428A5', 'Doublons', 'Le DISTINCTROW
d''Access
> existe sous SQL Server ? C''est équivalent à DISTINCT ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (30, NULL, 9, 6, '2005-02-22 09:33:46',
> '7D1FDA98-F322-49AA-93AE-8633397893ED', 'Datamining', 'Qui pourrait me
> conseiller un bon livre sur le datamining/datamart ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (31, NULL, 4, 7, '2005-02-23 09:58:59',
> '74578638-5C7B-48DC-8458-ECE9B9B08F5A', 'Livres sur Oracle', 'Quels sont
les
> meilleurs ouvrages sur le PL/SQL d''Oracle ?')
> INSERT INTO T_NEWS_NEW (NEW_ID, NEW_ID_PERE, USR_ID, FRM_ID, NEW_MOMENT,
> NEW_GLOBAL_ID, NEW_TITRE, NEW_TEXT)
> VALUES (32, 31, 6, 7, '2005-02-23 11:28:13',
> '924B5F1F-894D-4AFB-ABC6-C9B14596EBB7', 'Livres sur Oracle', 'SQL pour
Oracle de
> Soutou et Teste')
>
>


**************************************************************************
> Énoncé du problème :
>
> Donnez le nom des forums dont aucun utilisateur n'a posté plus d'une


news.
>


**************************************************************************
>
>
> SOLUTION :
>
> SELECT DISTINCT FRM.FRM_ID, FRM.FRM_NOM
> FROM T_NEWS_NEW NEW
> INNER JOIN T_FORUM_FRM FRM
> ON NEW.FRM_ID = FRM.FRM_ID
> GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
> HAVING COUNT(*) = ALL (SELECT COUNT(*)
> FROM T_NEWS_NEW
> WHERE NEW.FRM_ID = FRM_ID
> GROUP BY USR_ID, FRM_ID)
> La requête suivante :
> SELECT FRM.FRM_ID,USR_ID, COUNT(*) NEW_NOMBRE
> FROM T_NEWS_NEW NEW
> INNER JOIN T_FORUM_FRM FRM
> ON NEW.FRM_ID = FRM.FRM_ID
> GROUP BY USR_ID, FRM.FRM_ID, NEW.FRM_ID, FRM.FRM_NOM
> ORDER BY 1
> ...permet de trouver le nombre de news par forum et par utilisateur.
> FRM_ID USR_ID NEW_NOMBRE
> ----------- ----------- -----------
> 1 2 3
> 1 7 1
> 1 11 2
> 1 15 1
>
> 2 6 2
> 2 14 1
> 2 22 1
>
> 3 6 1
>
> 4 2 3
> 4 7 1
> 4 14 1
>
> 5 2 2
> 5 4 1
> 5 16 1
> 5 18 1
>
> 6 9 1
> 6 10 1
>
> 7 1 1
> 7 4 2
> 7 6 2
> D'après les résultats produit par cette requête, les forums à retenir,
sont ceux
> dans lesquels toutes les valeurs de la colonne NEW_NOMBRE sont égale à


1.
C'est
> le sens de la sous requête corrélée introduite par ALL.
>
> Pas besoin de code client ni de curseur !
>
> A +
>
>
> jeorme a écrit:
> > Merci à vous pour les infos. Donc si je récapitule il vaut mieux faire
les
> > boucles sur l'interface et faire des PS simples dans SQL Server.
> >
> >
> >
> > "Philippe T [MS]" a écrit dans le


message
de
> > news:
> >
> >>Bonjour,
> >>
> >>Travailler de façon ensembliste pour SQL est naturel. Il est plus


facile
> >>pour un SGBD de traiter plusieurs enregistrements simultanéments que


de
> >>traiter les enregistrements les uns après les autres.
> >>
> >>Après, lorsque l'on a pas le choix, il est possible d'utiliser un
curseur
> >>mais dans ces conditions, il faut privilégier des clauses de type
> >>FAST_FORWARD par exemple pour optimiser les traitements du curseur.
> >>
> >>Phil.
> >>________________________________________________________
> >>Philippe TROTIN http://blogs.msdn.com/ptrotin
> >>Microsoft Services France http://www.microsoft.com/france
> >>
> >>"Fred BROUARD" wrote in message
> >>news:#
> >>
> >>>Oh que oui !
> >>>
> >>>ne pas oublier que par défaut un curseur est perméable aux
modifications
> >>
> >>qui
> >>
> >>>s'opèrent en cours de route.
> >>>
> >>>Dans 99% des cas ou je voit un curseur dans le code, on peut s'en
passer
> >
> > !
> >
> >>>A +
> >>>
> >>>bruno reiter [MVP] a écrit:
> >>>
> >>>>il vaut mieux une procédure sans curseur
> >>>>
> >>>>br
> >>>>
> >>>>"jeorme" wrote in message
> >>>>news:
> >>>>
> >>>>
> >>>>>Bonjour à tous
> >>>>>
> >>>>>Simple question:
> >>>>>Je fais des pages ASP avec une base SQL derrière. Vaut il mieux


faire
> >>
> >>les
> >>
> >>>>>boucles dans la pages ASP ou faire une PS sur SQL avec des cursors


?
> >>>>>
> >>>>>C'est pour info car de toutes façons les deux marchent.
> >>>>>
> >>>>>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


*************************
> >>>
> >>
> >>
> >
> >
>
> --
> 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 *************************
>