MySQL-Prozeduren sollten den Status nur an Unix-Skripte zurückgeben
P粉924915787
P粉924915787 2023-09-08 09:44:26
0
2
599

Ich habe ein MySQL-Programm, das Out-Parameter und einige Druckanweisungen zum Debuggen enthält. Ich rufe diese Prozedur über ein Unix-Shell-Skript auf und die Idee besteht darin, den Out-Parameter einer Unix-Variablen zuzuweisen, mit der ich später die Bedingung überprüfe. Aber die Variable erhält auch die zuzuweisende Druckanweisung. Ich möchte die print-Anweisung loswerden und einfach die Ausgabeparameter (Ganzzahlen) Variablen zuweisen.

Unix-Skript:

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

Gibt auch gedruckte Anweisungen

proc started
proc ended
1043

Wenn ich den Code in einem SQL-Client wie DBeaver ausführe, erhalte ich nur die Ausgabeparameter..

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

Ich möchte Druck-/Debug-Anweisungen nicht deaktivieren, da sie für meine Protokolle hilfreich sind. Aber ich möchte nicht, dass sie in MySQL-Out-Variablen und letztendlich auch in meinen Unix-Variablen erscheinen.

Dies ist ein MySQL-Programm

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

Antworte allen(2)
P粉203648742

由于“debug”语句输出到stdout,并且select @out;也输出到stdout,因此MySQL客户端无法区分它们。过程没有输出重定向功能。

所以你必须创造性地思考。

一个想法是确保您的调试语句具有一些通用模式,以便您可以将其过滤掉。例如,一致地使用“#DEBUG”一词。

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

然后在从 Bash 调用它时对其进行过滤:

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

另一个想法是更改代码,以便调试语句仅有条件地输出。

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

因此,如果您想要调试输出,可以这样调用它:

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

如果您不需要调试输出,则不要设置@debug=1

最重要的是,MySQL 存储过程在很多情况下确实很不方便。没有真正的调试器,没有包,没有编译器,没有标准库,没有原子部署等等。我已经使用MySQL很多年了,但我几乎没有见过程序的良好用途。

P粉818561682

假设:

  • 调试语句和select @out显示在单独的行上(与OP的原始问题一样)
  • 需要将除最后一行之外的所有内容附加到日志文件中
  • 最后一行将保存在变量中

我们将从 OP 当前捕获所有输出到变量的方法的副本开始:

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'

要将除最后一行之外的所有内容追加到日志文件中:

$ 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

要将最后一行捕获到新变量:

$ output_var="$(printf "%s\n" "${all_output}" | tail -1)"
$ printf "%s\n" "${output_var}"
1043
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage