我有一个 mysql 程序,它有 out 参数和一些用于调试的打印语句。 我从 Unix shell 脚本调用这个过程,想法是将 out 参数分配给一个 unix 变量,我用它来检查以后的条件。但是变量正在获取打印语句也被分配。我想摆脱打印语句,而只将输出参数(整数)分配给变量。
Unix 脚本:
output_var=`mysql -sN test_db -e "call delete_me(@outs);select @outs"` echo $output_var
也给出打印语句
proc started proc ended 1043
当我在像 DBeaver 这样的 SQL 客户端中运行代码时..我只得到输出参数..
call delete_me(@out);select @out
@out ---- 1043
我不想禁止打印/调试语句,因为它们对我的日志很有帮助。但我不希望它们出现在 mysql out 变量中,最终也出现在我的 unix 变量中。
这是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粉2036487422023-09-09 07:57:11
由于“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粉8185616822023-09-09 00:57:17
假设:
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