为什么我的mysql代码不起作用

时间:2017-06-13 15:04:16

标签: mysql

我编写了这段代码,当我执行它时,它说我在更新语句附近遇到mysql语法问题

set @s1 = (select if ((select count(*) from information_schema.columns where table_name='foo' and column_name='bar_id') > 0,
                      'select 1',
                      'alter table foo add column bar_id bigint; update foo set bar_id = baz_id;'));
prepare stmt from @s1;
execute stmt;
deallocate prepare stmt;

如果我将代码更改为

set @s1 = (select if ((select count(*) from information_schema.columns where table_name='foo' and column_name='bar_id') > 0,
                      'select 1',
                      'alter table foo add column bar_id bigint;'));
prepare stmt from @s1;
execute stmt;
deallocate prepare stmt;
update foo set bar_id = baz_id;

然后它的工作原理。但是我想在if条件中使用update语句。

我无法将其变成SP。

错误:

  

错误1064(42000):您的SQL语法有错误;检查与MySQL服务器版本对应的手册,以便在第1行的'update foo set bar_id = baz_id'附近使用正确的语法

2 个答案:

答案 0 :(得分:2)

在第一个代码块中,您尝试准备一个包含两个 SQL语句的字符串。不幸的是,MySQL prepare / execute cannot have multiple statements

如果你不能使用SP,我想我建议这样做:

set @s1 = (select if ((select count(*) from information_schema.columns where table_name='foo' and column_name='bar_id') > 0,
                      'select 1',
                      concat('alter table foo add column bar_id bigint default ', baz_id)));

prepare stmt from @s1;
execute stmt;
deallocate prepare stmt;

alter table foo alter column bar_id drop default;

但是,说实话,我建议您尽量减少DDL更改,因为这些更改可能会产生不可预测的运行时行为。在这种情况下,这意味着在带外添加foo.bar_id并根据需要执行更新。

答案 1 :(得分:0)

问题是MySQL准备好的语句不支持多语句。

如果要编写数据库结构更新的脚本,最简单的方法是使用没有动态SQL的过程(在执行更改时,您可能还需要检查table_schema)。

create procedure sp_fix_structure()
begin

declare v_cnt int;

select count(*) into v_cnt
from information_schema.columns
where table_schema=database() and table_name='foo' and column_name='bar_id';

if (v_cnt=0) then
  alter table foo add column bar_id bigint;
  update foo set bar_id = baz_id;
end if;

end