OVH Cloud OVH Cloud

simplifier une requête

6 réponses
Avatar
Richard
Bonjour.
Je cherche à archiver des données dans une table d’archivage, puis à les
détruire dans la table d’origine pour gagner de la place

J’ai donc réaliser la requete suivante.

Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
vous une solution pour moi.

Si vous répondez à ma demande je voudrai du commentaire, le but et de
comprendre pour pouvoir appliquer dans d’autre situations.
Par avance merci.

Présentation de la requête global d’archivage

/*----------------------------------------------------------------
Copier les données de la table ‘MOUVMNT’ dans ‘ARCH_MOUVEMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')


/*----------------------------------------------------------------
Supprimer les données de la table ‘MOUVMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

delete from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')

6 réponses

Avatar
Jean-Nicolas BERGER
Voici mes premières remarques par rapport au code indiqué :
- le fait d'exécuter deux fois la sélection est une perte de temps (on
parcourt deux fois les indexes, en faisant les tests sur site, batiment et
date_inventaire). Il serait plus judicieux de créer une table contenant
uniquement les colonnes de la PK de la table des mouvements (genre
MOUVMNT_A_ARCHIVER), de remplir cette table, puis de l'utiliser par simple
jointure pour faire le INSERT puis le DELETE
- si le DELETE plante (pour quelque raison que ce soit), le INSERT a déjà
été fait. Il faudrait donc inclure l'ensemble le code dans une transaction
(attention à la taille du journal des transaction), voire mieux, utiliser la
table décrite dans le point précédent pour gérer une procédure de reprise
qui ne fasse que le DELETE
- attention : grosse faille dans ton code, qui peut entrainer une perte de
données : ne surtout pas utiliser deux fois le CURRENT_TIMESTAMP. En effet,
si la première requète dure une heuree, on peut perdre une heure de
mouvements !!! Soit stocker la date-heure de référence de l'archivage
quelque part, soit utiliser la table décrite au premier point.
- les requêtes de sélection semblent hasardeuses, étant donné qu'elles
n'archivent pas seulement les mouvements antérieures à maintenant moins
365j, mais l'ensemble des mouvements concernant du matériel qui a eu un
mouvement il y a plus d'un an. Exemple : un matériel a eu un mouvement il y
a 14 mois, puis un autre mouvement hier --> les deux mouvements vont être
archivés. Est-ce vraiment le fonctionnement désiré? J'aurais tendance à
faire sauter le code ... where CLE_MATERIEL in (select ... , et à nettoyer
un peu autour. Eviter le "select in", sur ce la volumétrie de ce genre, il
crée des tables temporaires (et donc du volume) inutilement.
- note au passage : revoir la syntaxe de DELETE. On peut faire DELETE
MOUVEMNT from MOUVEMNT , MOUVMNT_A_ARCHIVER WHERE ...
- a terme, il se peut que la table MOUVMNT et la table ARCH_MOUVEMNT
n'aient plus forcément leur colonne dans le même ordre. (je parle de vécu,
fais-moi confinace). Le select * est donc totalement à banir pour le INSERT,
tout comme la non spécification explicate des champs destination. Faire
INSERT INTO ARCH_MOUVEMNT (CHAMP_A, CHAMP_B, ...) select CHAMP_A, CHAMP_B,
...FROM ...

Bon courage.
JN.


"Richard" a écrit dans le message de
news:
Bonjour.
Je cherche à archiver des données dans une table d'archivage, puis à les
détruire dans la table d'origine pour gagner de la place

J'ai donc réaliser la requete suivante.

Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
vous une solution pour moi.

Si vous répondez à ma demande je voudrai du commentaire, le but et de
comprendre pour pouvoir appliquer dans d'autre situations.
Par avance merci.

Présentation de la requête global d'archivage

/*----------------------------------------------------------------
Copier les données de la table 'MOUVMNT' dans 'ARCH_MOUVEMNT'
Création d'alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where
CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')


/*----------------------------------------------------------------
Supprimer les données de la table 'MOUVMNT'
Création d'alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

delete from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')




Avatar
Richard
Bonjour et merci pour ces explications.

Je remarque que vous maîtrisez bien le langage de programmation, par contre
pas moi.
J'ai bien compris que mon travail n'est pas super, je n'ai aucune formation
sur le sujet, j'ai réalisé ce code en utilisant l'aide Microsoft et le forum
et j'ai assemblé le tous.
Je ne suis pas capable dans l'état d'actuel de mes connaissances de faire
les corrections que vous m'avez donnés.
Votre aide s'adresse déjà à une personne ayant une formation sur le sujet ce
qui n'est pas mon cas.
Je marche actuellement plus en copier coller que en développement personnel.
Dans l'état actuelle des choses je vais utiliser ma solution avec ces
risques, j'ai un besoin immédiat de faire cette manip et aucune solution avec
des collègues pour m'aider n’est possible. Je vais voir à apprendre ce
langage un peu mieux pour la suite.

Merci.



"Jean-Nicolas BERGER" a écrit :

Voici mes premières remarques par rapport au code indiqué :
- le fait d'exécuter deux fois la sélection est une perte de temps (on
parcourt deux fois les indexes, en faisant les tests sur site, batiment et
date_inventaire). Il serait plus judicieux de créer une table contenant
uniquement les colonnes de la PK de la table des mouvements (genre
MOUVMNT_A_ARCHIVER), de remplir cette table, puis de l'utiliser par simple
jointure pour faire le INSERT puis le DELETE
- si le DELETE plante (pour quelque raison que ce soit), le INSERT a déjà
été fait. Il faudrait donc inclure l'ensemble le code dans une transaction
(attention à la taille du journal des transaction), voire mieux, utiliser la
table décrite dans le point précédent pour gérer une procédure de reprise
qui ne fasse que le DELETE
- attention : grosse faille dans ton code, qui peut entrainer une perte de
données : ne surtout pas utiliser deux fois le CURRENT_TIMESTAMP. En effet,
si la première requète dure une heuree, on peut perdre une heure de
mouvements !!! Soit stocker la date-heure de référence de l'archivage
quelque part, soit utiliser la table décrite au premier point.
- les requêtes de sélection semblent hasardeuses, étant donné qu'elles
n'archivent pas seulement les mouvements antérieures à maintenant moins
365j, mais l'ensemble des mouvements concernant du matériel qui a eu un
mouvement il y a plus d'un an. Exemple : un matériel a eu un mouvement il y
a 14 mois, puis un autre mouvement hier --> les deux mouvements vont être
archivés. Est-ce vraiment le fonctionnement désiré? J'aurais tendance à
faire sauter le code ... where CLE_MATERIEL in (select ... , et à nettoyer
un peu autour. Eviter le "select in", sur ce la volumétrie de ce genre, il
crée des tables temporaires (et donc du volume) inutilement.
- note au passage : revoir la syntaxe de DELETE. On peut faire DELETE
MOUVEMNT from MOUVEMNT , MOUVMNT_A_ARCHIVER WHERE ...
- a terme, il se peut que la table MOUVMNT et la table ARCH_MOUVEMNT
n'aient plus forcément leur colonne dans le même ordre. (je parle de vécu,
fais-moi confinace). Le select * est donc totalement à banir pour le INSERT,
tout comme la non spécification explicate des champs destination. Faire
INSERT INTO ARCH_MOUVEMNT (CHAMP_A, CHAMP_B, ...) select CHAMP_A, CHAMP_B,
....FROM ...

Bon courage.
JN.


"Richard" a écrit dans le message de
news:
> Bonjour.
> Je cherche à archiver des données dans une table d'archivage, puis à les
> détruire dans la table d'origine pour gagner de la place
>
> J'ai donc réaliser la requete suivante.
>
> Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
> vous une solution pour moi.
>
> Si vous répondez à ma demande je voudrai du commentaire, le but et de
> comprendre pour pouvoir appliquer dans d'autre situations.
> Par avance merci.
>
> Présentation de la requête global d'archivage
>
> /*----------------------------------------------------------------
> Copier les données de la table 'MOUVMNT' dans 'ARCH_MOUVEMNT'
> Création d'alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where
> CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>
> /*----------------------------------------------------------------
> Supprimer les données de la table 'MOUVMNT'
> Création d'alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> delete from Dbo.MOUVEMNT where CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>





Avatar
Fred BROUARD
Votre première requête est incomplète. Il y manque le condition de jointure
entre les tables MATERIEL et MOUVEMNT.

Voici une correction plus propre et plus optimisée :

insert into E_ARCH_MOUVEMNT
select *
From MOUVEMNT
where CLE_MATERIEL in (select distinct a.CLE_MATERIEL
from MATERIEL a
JOIN MOUVEMNT b
ON ???
WHERE a.DATE_INVENTAIRE <
DATEADD(Day, - 365,> CURRENT_TIMESTAMP)
AND a.SITE IN ('EXT', 'FIN')
and a.BATIMENT NOT IN ('EN ATTENTE', 'A GERER'))

même topo pour la seconde

de plus vous devez gérer une transaction pour ces deux requêtes car en cas de
problème entre les deux vous resterez dans une état incohérent.

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

Richard a écrit:
Bonjour.
Je cherche à archiver des données dans une table d’archivage, puis à les
détruire dans la table d’origine pour gagner de la place

J’ai donc réaliser la requete suivante.

Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
vous une solution pour moi.

Si vous répondez à ma demande je voudrai du commentaire, le but et de
comprendre pour pouvoir appliquer dans d’autre situations.
Par avance merci.

Présentation de la requête global d’archivage

/*----------------------------------------------------------------
Copier les données de la table ‘MOUVMNT’ dans ‘ARCH_MOUVEMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')


/*----------------------------------------------------------------
Supprimer les données de la table ‘MOUVMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

delete from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')




Avatar
Fred BROUARD
Votre première requête est incomplète. Il y manque le condition de jointure
entre les tables MATERIEL et MOUVEMNT.

Voici une correction plus propre et plus optimisée :

insert into E_ARCH_MOUVEMNT
select *
From MOUVEMNT
where CLE_MATERIEL in (select distinct a.CLE_MATERIEL
from MATERIEL a
JOIN MOUVEMNT b
ON ???
WHERE a.DATE_INVENTAIRE <
DATEADD(Day, - 365,> CURRENT_TIMESTAMP)
AND a.SITE IN ('EXT', 'FIN')
and a.BATIMENT NOT IN ('EN ATTENTE', 'A GERER'))

même topo pour la seconde

de plus vous devez gérer une transaction pour ces deux requêtes car en cas de
problème entre les deux vous resterez dans une état incohérent.

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

Richard a écrit:
Bonjour.
Je cherche à archiver des données dans une table d’archivage, puis à les
détruire dans la table d’origine pour gagner de la place

J’ai donc réaliser la requete suivante.

Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
vous une solution pour moi.

Si vous répondez à ma demande je voudrai du commentaire, le but et de
comprendre pour pouvoir appliquer dans d’autre situations.
Par avance merci.

Présentation de la requête global d’archivage

/*----------------------------------------------------------------
Copier les données de la table ‘MOUVMNT’ dans ‘ARCH_MOUVEMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')


/*----------------------------------------------------------------
Supprimer les données de la table ‘MOUVMNT’
Création d’alias pour

A pour Dbo.MATERIEL
B pour Dbo.MOUVEMNT

Evite de récrire le nom des tables.

Filtres pour les critères suivants

SITE = EXT et FIN
BATIMENT <> EN ATTENTE et A GERER
DATE_INVENTAIRE <> ce jour moins 365 jours
-----------------------------------------------------------------*/

delete from Dbo.MOUVEMNT where CLE_MATERIEL
in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b

WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
<> 'EN ATTENTE' and
Dbo.MATERIEL.BATIMENT <> 'A GERER')




Avatar
Richard
Bonjour.
Je viens de lancer cette requête et j'ai le message suivant.

[Microsoft][ODBC SQL Server Driver]Champ COUNT incorrect ou erreur de syntaxe

Ou est le probléme, je ne comprends pas pourquoi un PB sur "champ count"

Sinon merci pour la simplification de la zone WHERE

Par contre je ne comprend pas le ON ???, il s'agit de la jointure avec la
table MATERIEL?
dans ce cas je cherche à faire un joint 1 "MATERIEL" vers n MOUVEMENT avez
vous la syntaxe.

Par avance merci



Help

"Fred BROUARD" a écrit :

Votre première requête est incomplète. Il y manque le condition de jointure
entre les tables MATERIEL et MOUVEMNT.

Voici une correction plus propre et plus optimisée :

insert into E_ARCH_MOUVEMNT
select *
From MOUVEMNT
where CLE_MATERIEL in (select distinct a.CLE_MATERIEL
from MATERIEL a
JOIN MOUVEMNT b
ON ???
WHERE a.DATE_INVENTAIRE <
DATEADD(Day, - 365,> CURRENT_TIMESTAMP)
AND a.SITE IN ('EXT', 'FIN')
and a.BATIMENT NOT IN ('EN ATTENTE', 'A GERER'))

même topo pour la seconde

de plus vous devez gérer une transaction pour ces deux requêtes car en cas de
problème entre les deux vous resterez dans une état incohérent.

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

Richard a écrit:
> Bonjour.
> Je cherche à archiver des données dans une table d’archivage, puis à les
> détruire dans la table d’origine pour gagner de la place
>
> J’ai donc réaliser la requete suivante.
>
> Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
> vous une solution pour moi.
>
> Si vous répondez à ma demande je voudrai du commentaire, le but et de
> comprendre pour pouvoir appliquer dans d’autre situations.
> Par avance merci.
>
> Présentation de la requête global d’archivage
>
> /*----------------------------------------------------------------
> Copier les données de la table ‘MOUVMNT’ dans ‘ARCH_MOUVEMNT’
> Création d’alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>
> /*----------------------------------------------------------------
> Supprimer les données de la table ‘MOUVMNT’
> Création d’alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> delete from Dbo.MOUVEMNT where CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>




Avatar
Richard
Bonjour.

je viens de compléter la requête comme suit

Ajout du lien entre table MATERIEL et MOUVEMNT 1 vers n

Suppression de ">" qui me donne une erreur:
Serveur : Msg 170, Niveau 15, État 1, Ligne 7
Ligne 7 : syntaxe incorrecte vers '>'.

Cela vous semble t'il correcte

insert into E_ARCH_MOUVEMNT
select *
From MOUVEMNT
where CLE_MATERIEL in (select distinct a.CLE_MATERIEL
from MATERIEL a LEFT OUTER JOIN
MOUVEMNT b ON a.CLE_MATERIEL = a.CLE_MATERIEL
WHERE a.DATE_INVENTAIRE <DATEADD(Day, -
365,CURRENT_TIMESTAMP)
AND a.SITE IN ('EXT', 'FIN')
and a.BATIMENT NOT IN ('EN ATTENTE', 'A GERER'))

A+

"Fred BROUARD" a écrit :

Votre première requête est incomplète. Il y manque le condition de jointure
entre les tables MATERIEL et MOUVEMNT.

Voici une correction plus propre et plus optimisée :

insert into E_ARCH_MOUVEMNT
select *
From MOUVEMNT
where CLE_MATERIEL in (select distinct a.CLE_MATERIEL
from MATERIEL a
JOIN MOUVEMNT b
ON ???
WHERE a.DATE_INVENTAIRE <
DATEADD(Day, - 365,> CURRENT_TIMESTAMP)
AND a.SITE IN ('EXT', 'FIN')
and a.BATIMENT NOT IN ('EN ATTENTE', 'A GERER'))

même topo pour la seconde

de plus vous devez gérer une transaction pour ces deux requêtes car en cas de
problème entre les deux vous resterez dans une état incohérent.

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

Richard a écrit:
> Bonjour.
> Je cherche à archiver des données dans une table d’archivage, puis à les
> détruire dans la table d’origine pour gagner de la place
>
> J’ai donc réaliser la requete suivante.
>
> Je suis débutant en SQL, donc je pense que je peux faire plus simple avez
> vous une solution pour moi.
>
> Si vous répondez à ma demande je voudrai du commentaire, le but et de
> comprendre pour pouvoir appliquer dans d’autre situations.
> Par avance merci.
>
> Présentation de la requête global d’archivage
>
> /*----------------------------------------------------------------
> Copier les données de la table ‘MOUVMNT’ dans ‘ARCH_MOUVEMNT’
> Création d’alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> insert into Dbo.E_ARCH_MOUVEMNT select * from Dbo.MOUVEMNT where CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>
> /*----------------------------------------------------------------
> Supprimer les données de la table ‘MOUVMNT’
> Création d’alias pour
>
> A pour Dbo.MATERIEL
> B pour Dbo.MOUVEMNT
>
> Evite de récrire le nom des tables.
>
> Filtres pour les critères suivants
>
> SITE = EXT et FIN
> BATIMENT <> EN ATTENTE et A GERER
> DATE_INVENTAIRE <> ce jour moins 365 jours
> -----------------------------------------------------------------*/
>
> delete from Dbo.MOUVEMNT where CLE_MATERIEL
> in (select distinct a.CLE_MATERIEL from Dbo.MATERIEL a, Dbo.MOUVEMNT b
>
> WHERE (Dbo.MATERIEL.DATE_INVENTAIRE < DATEADD(Day, - 365,
> CURRENT_TIMESTAMP)) AND (Dbo.MATERIEL.SITE = 'EXT' or
> Dbo.MATERIEL.SITE = 'FIN') and (Dbo.MATERIEL.BATIMENT
> <> 'EN ATTENTE' and
> Dbo.MATERIEL.BATIMENT <> 'A GERER')
>
>