OVH Cloud OVH Cloud

Conseil Integrité

2 réponses
Avatar
LuckyMan
Bonsoir,

Soit la SP suivante

"
CREATE Procedure dbo.DESACTIVE_GESTIONNAIRE
(
@GESTIONNAIRE_CODE numeric
)

As

/*
Traiter les bases de ce gestionnaire une par une
*/
DECLARE tbase_cursor CURSOR FOR SELECT BASE_CODE FROM BASE WHERE
(GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE)
OPEN tbase_cursor
DECLARE @base_code numeric
FETCH NEXT FROM tbase_cursor INTO @base_code

WHILE (@@FETCH_STATUS <> -1)
BEGIN

IF (@@FETCH_STATUS <> -2)
BEGIN

DELETE FROM ATTRIBUT WHERE (RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))
DELETE FROM RESP_RIB WHERE (RESP_RIB_RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))
DELETE FROM RESP_RGP WHERE (RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))

UPDATE BASE SET GESTIONNAIRE_CODE=BASE_CODE WHERE (BASE_CODE IN (SELECT
BASE_CODE FROM RGP_BASE WHERE BATIMENT_CODE IN (SELECT BASE_CODE FROM BASE
WHERE (GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE) AND (BASE_BATIMENT=1))))
UPDATE BASE SET GESTIONNAIRE_CODE=BASE_CODE WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
END

FETCH NEXT FROM tbase_cursor INTO @base_code

END

CLOSE tbase_cursor
DEALLOCATE tbase_cursor


/*
Traiter les autres informations rattachées à ce gestionnaire
*/
DELETE FROM VENTILATION WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM REPARTITION WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM TRESORERIE WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM POSTES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM PRODUITS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM BANQUES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM STAGES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM MANDATS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM RESPONSABILITES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM UTILISATEUR_PARAMS WHERE (UTILISATEUR_CODE IN (SELECT
UTILISATEUR_CODE FROM UTILISATEURS WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE))
DELETE FROM DROITS_UTILISATEURS WHERE (UTILISATEUR_CODE IN (SELECT
UTILISATEUR_CODE FROM UTILISATEURS WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE))
DELETE FROM UTILISATEURS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

DELETE FROM TYPE_ATTRIBUT WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

/* fermer le gestionnaire */
UPDATE GESTIONNAIRE SET GESTIONNAIRE_TYPE=0 WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

return
"

Qu'est-ce que ça vous inspire en terme d'intégrité ? de perf ?

Je pensais qu'il valait mieux mettre l'ensemble dans une transaction...

Merci pour votre réponse

2 réponses

Avatar
Fred BROUARD
Bonjour,

1) indentez votre code afin qu'il soit lisible. C'est une marque de politesse
lorsque l'on demande de l'aide

2) il est dangereux de mettre à jour la table sous jacente à un curseur et en
particulier sans faire appel au prédicat WHERE CURRENT OF ...

3) il est contre preformant d'utiliser un curseur. Vous pouvez vous en passer.
Lisez l'article que j'ai écrit à ce sujet

4) il est préférable de gérer une transaction et dana votre cas au niveau
d'isolation REPEATABLE READ.

A +

--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************

LuckyMan a écrit:
Bonsoir,

Soit la SP suivante

"
CREATE Procedure dbo.DESACTIVE_GESTIONNAIRE
(
@GESTIONNAIRE_CODE numeric
)

As

/*
Traiter les bases de ce gestionnaire une par une
*/
DECLARE tbase_cursor CURSOR FOR SELECT BASE_CODE FROM BASE WHERE
(GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE)
OPEN tbase_cursor
DECLARE @base_code numeric
FETCH NEXT FROM tbase_cursor INTO @base_code

WHILE (@@FETCH_STATUS <> -1)
BEGIN

IF (@@FETCH_STATUS <> -2)
BEGIN

DELETE FROM ATTRIBUT WHERE (RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))
DELETE FROM RESP_RIB WHERE (RESP_RIB_RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))
DELETE FROM RESP_RGP WHERE (RESP_CODE IN (SELECT RESP_CODE FROM
RESP_BASE WHERE (BASE_CODE=@BASE_CODE )))

UPDATE BASE SET GESTIONNAIRE_CODEºSE_CODE WHERE (BASE_CODE IN (SELECT
BASE_CODE FROM RGP_BASE WHERE BATIMENT_CODE IN (SELECT BASE_CODE FROM BASE
WHERE (GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE) AND (BASE_BATIMENT=1))))
UPDATE BASE SET GESTIONNAIRE_CODEºSE_CODE WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
END

FETCH NEXT FROM tbase_cursor INTO @base_code

END

CLOSE tbase_cursor
DEALLOCATE tbase_cursor


/*
Traiter les autres informations rattachées à ce gestionnaire
*/
DELETE FROM VENTILATION WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM REPARTITION WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM TRESORERIE WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM POSTES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM PRODUITS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM BANQUES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM STAGES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM MANDATS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM RESPONSABILITES WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE
DELETE FROM UTILISATEUR_PARAMS WHERE (UTILISATEUR_CODE IN (SELECT
UTILISATEUR_CODE FROM UTILISATEURS WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE))
DELETE FROM DROITS_UTILISATEURS WHERE (UTILISATEUR_CODE IN (SELECT
UTILISATEUR_CODE FROM UTILISATEURS WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE))
DELETE FROM UTILISATEURS WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

DELETE FROM TYPE_ATTRIBUT WHERE GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

/* fermer le gestionnaire */
UPDATE GESTIONNAIRE SET GESTIONNAIRE_TYPE=0 WHERE
GESTIONNAIRE_CODE=@GESTIONNAIRE_CODE

return
"

Qu'est-ce que ça vous inspire en terme d'intégrité ? de perf ?

Je pensais qu'il valait mieux mettre l'ensemble dans une transaction...

Merci pour votre réponse





Avatar
LuckyMan
Fred BROUARD wrote:
Bonjour,

1) indentez votre code afin qu'il soit lisible. C'est une marque de
politesse lorsque l'on demande de l'aide

2) il est dangereux de mettre à jour la table sous jacente à un
curseur et en particulier sans faire appel au prédicat WHERE CURRENT
OF ...

3) il est contre preformant d'utiliser un curseur. Vous pouvez vous
en passer. Lisez l'article que j'ai écrit à ce sujet

4) il est préférable de gérer une transaction et dana votre cas au
niveau d'isolation REPEATABLE READ.

A +




Merci infiniment,

Avec mes excuses pour le point 1 (ce n'est pas moi qui est écrit ce code -ce
qui explique mais ne m'absout en rien- j'en conviens d'autant plus qu'il est
vrai que je m'insurge comme vous contre la qualité des présentations
médiocres de code)

Bon Week-End,

LM


------
Mea culpa, et donc avec le recours de
http://www.wangz.net/cgi-bin/pp/gsqlparser/sqlpp/sqlformat.tpl

CREATE PROCEDURE DBO.DESACTIVE_GESTIONNAIRE(
@GESTIONNAIRE_CODE NUMERIC)
AS
/*
Traiter les bases de ce gestionnaire une par une
*/

DECLARE TBASE_CURSOR CURSOR FOR
SELECT BASE_CODE
FROM BASE
WHERE (GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE)
OPEN TBASE_CURSOR

DECLARE
@BASE_CODE NUMERIC
FETCH NEXT FROM TBASE_CURSOR
INTO @BASE_CODE
WHILE (@@FETCH_STATUS <> - 1)
BEGIN
IF (@@FETCH_STATUS <> - 2)
BEGIN
DELETE FROM ATTRIBUT
WHERE (RESP_CODE IN (SELECT RESP_CODE
FROM RESP_BASE
WHERE (BASE_CODE = @BASE_CODE)))
DELETE FROM RESP_RIB
WHERE (RESP_RIB_RESP_CODE IN (SELECT RESP_CODE
FROM RESP_BASE
WHERE (BASE_CODE @BASE_CODE)))
DELETE FROM RESP_RGP
WHERE (RESP_CODE IN (SELECT RESP_CODE
FROM RESP_BASE
WHERE (BASE_CODE = @BASE_CODE)))
UPDATE BASE
SET GESTIONNAIRE_CODE = BASE_CODE
WHERE (BASE_CODE IN (SELECT BASE_CODE
FROM RGP_BASE
WHERE BATIMENT_CODE IN (SELECT BASE_CODE
FROM BASE
WHERE
(GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE)
AND
(BASE_BATIMENT = 1))))
UPDATE BASE
SET GESTIONNAIRE_CODE = BASE_CODE
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

END
FETCH NEXT FROM TBASE_CURSOR
INTO @BASE_CODE

END
CLOSE TBASE_CURSOR
DEALLOCATE TBASE_CURSOR
/*
Traiter les autres informations rattachées à ce gestionnaire
*/
DELETE FROM VENTILATION
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM REPARTITION
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM TRESORERIE
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM POSTES
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM PRODUITS
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM BANQUES
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM STAGES
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM MANDATS
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM RESPONSABILITES
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM UTILISATEUR_PARAMS
WHERE (UTILISATEUR_CODE IN (SELECT UTILISATEUR_CODE
FROM UTILISATEURS
WHERE GESTIONNAIRE_CODE @GESTIONNAIRE_CODE))

DELETE FROM DROITS_UTILISATEURS
WHERE (UTILISATEUR_CODE IN (SELECT UTILISATEUR_CODE
FROM UTILISATEURS
WHERE GESTIONNAIRE_CODE @GESTIONNAIRE_CODE))

DELETE FROM UTILISATEURS
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE

DELETE FROM TYPE_ATTRIBUT
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE
/* fermer le gestionnaire */
UPDATE GESTIONNAIRE
SET GESTIONNAIRE_TYPE = 0
WHERE GESTIONNAIRE_CODE = @GESTIONNAIRE_CODE
RETURN