Maison  >  Questions et réponses  >  le corps du texte

Les procédures MySQL ne doivent renvoyer l'état qu'aux scripts Unix

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粉924915787P粉924915787378 Il y a quelques jours522

répondre à tous(2)je répondrai

  • P粉203648742

    P粉2036487422023-09-09 07:57:11

    É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.

    répondre
    0
  • P粉818561682

    P粉8185616822023-09-09 00:57:17

    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

    répondre
    0
  • Annulerrépondre