Les procédures MySQL ne doivent renvoyer l'état qu'aux scripts Unix
P粉924915787
P粉924915787 2023-09-08 09:44:26
0
2
633

J'ai un programme MySQL qui a des paramètres et des instructions d'impression pour le débogage. J'appelle cette procédure à partir d'un script shell Unix et l'idée est d'attribuer le paramètre out à une variable Unix que j'utilise pour vérifier la condition plus tard. Mais la variable obtient également l'affectation de l'instruction d'impression. Je veux me débarrasser de l'instruction print et simplement attribuer les paramètres de sortie (entiers) aux variables.

Script Unix :

output_var=`mysql -sN test_db -e "call delete_me(@outs);select @outs"`
echo $output_var

Donne également des déclarations imprimées

proc started
proc ended
1043

Lorsque j'exécute le code dans un client SQL comme DBeaver..Je n'obtiens que les paramètres de sortie..

call delete_me(@out);select @out
@out 
----
1043

Je ne souhaite pas désactiver les instructions d'impression/débogage car elles sont utiles pour mes journaux. Mais je ne veux pas qu'ils apparaissent dans les variables mysql out et finalement dans mes variables unix également.

C'est un programme MySQL

CREATE PROCEDURE `delete_me`(out success int)
BEGIN
    
    DECLARE var1 INT;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        SHOW ERRORS;  
        ROLLBACK; 
        SET success=1;
    END;
    START TRANSACTION;
  
    select max(run_id) into var1 from job_run;
    
    select 'proc started';
    
    select 'proc ended';
    
    SET success:= var1;
    
END;

P粉924915787
P粉924915787

répondre à tous(2)
P粉203648742

Étant donné que l'instruction "debug" est sortie sur stdout et select @out; également sur stdout, le client MySQL ne peut pas les différencier. Le processus n'a pas de fonctionnalité de redirection de sortie.

Il faut donc penser de manière créative.

Une idée est de vous assurer que vos instructions de débogage ont un modèle commun afin de pouvoir les filtrer. Par exemple, utilisez le mot « #DEBUG » de manière cohérente.

...
select '#DEBUG: proc started';
...

Puis filtrez-le lorsque vous l'appelez depuis Bash :

output_var=$(mysql -sN test_db 
  -e "call delete_me(@outs); select @outs" 
  | grep -v '#DEBUG')

Une autre idée est de modifier le code afin que les instructions de débogage ne soient affichées que sous condition.

if @debug then
  select 'proc started';
end if;

Donc, si vous voulez une sortie de débogage, vous pouvez l'appeler comme ceci :

output_var=$(mysql -sN test_db 
  -e "set @debug=1; call delete_me(@outs); select @outs")

Si vous n'avez pas besoin de la sortie de débogage, ne définissez pas @debug=1.

Le plus important est que les procédures stockées MySQL sont vraiment gênantes dans de nombreuses situations. Pas de véritable débogueur, pas de packages, pas de compilateur, pas de bibliothèque standard, pas de déploiement atomique, etc. J'utilise MySQL depuis de nombreuses années, mais j'ai vu très peu de bonnes utilisations du programme.

P粉818561682

Hypothèse :

  • Les instructions de débogage et select @out sont affichées sur des lignes séparées (comme dans la question originale du PO)
  • Besoin de tout ajouter sauf la dernière ligne au fichier journal
  • La dernière ligne sera enregistrée dans une variable

Nous commencerons par une copie de la méthode actuelle de l'OP pour capturer toutes les sorties vers des variables :

all_output=$(mysql -sN test_db -e "call load_procedure(@out);select @out")

# for demo purposes I'll use:

all_output='proc started
proc ended
1043'

Pour tout ajouter sauf la dernière ligne au fichier journal :

$ printf "%s\n" "${all_output}" | head -n -1 >> logfile
$ cat logfile
proc started
proc ended

# sed alternative:

$ printf "%s\n" "${all_output}" | sed '$d' >> logfile
$ cat logfile
proc started
proc ended

Pour capturer la dernière ligne d'une nouvelle variable :

$ output_var="$(printf "%s\n" "${all_output}" | tail -1)"
$ printf "%s\n" "${output_var}"
1043
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal