10

移行によってユーザーが作成されたことを確認する移行テストを作成しています。ユーザーが存在しない場合、テストはエラーをスローする必要があります。最初は、ゼロ除算エラーを使用して、必要なものを取得できると考えていました。

SET SESSION sql_mode = 'error_for_division_by_zero';
SELECT 1/COUNT(*) FROM mysql.user WHERE user = 'foo';

ただし、存在しなくてもエラーにfooはなりません。andステートメントerror_for_division_by_zeroのみに影響INSERTUPDATEすることが判明しました。

次に、間違った数の引数で関数を呼び出すことができるのではないかと考えました。

SELECT IF(COUNT(*) = 1, 1, date_format(1, 2, 3))
  FROM mysql.user WHERE user = 'foo';

fooしかし、おそらくパーサーが誤ったパラメーター数に気付いたために、存在する場合でもこれは停止します。

例外の発生をエミュレートする関数を書くことはできましたが、それを避けようとしていました。条件付きで実行時例外をスローするように MySQL を強制する方法はありませんか?

4

3 に答える 3

2

複数の行を返すサブクエリを実行するだけで、関数/プロシージャなしで例外を発生させることができますが、1つの行しか期待できません。通常、データベースにはそのためのテーブルが既にありますが、ここではその目的のためにテーブルを含めました。

create table t (a int);
insert into t values(1);
insert into t values(1);
select * from t;

以下の選択では、外側の選択では 1 つの値が期待されますが、内側の選択では複数の値が返されるため、例外が発生します。

select (select a from t);

あなたのケースにそれを適用することができます:

select case when 
    2*2 = 4 
    then 'OK' 
    else (select a from t)
    end;

select case when 
    2*2 = 5 
    then 'OK' 
    else (select a from t)
    end;

参照: https://dba.stackexchange.com/questions/78594/how-to-conditionally-raise-an-error-in-mysql-without-stored-procedure

于 2016-04-26T08:49:24.600 に答える
0

デビッド、

なぜ手続きが必要なの?関数内からSIGNALすることができます(そして、トリガーで関数を呼び出すこともできます)

delimiter go

create function f_raise(p_message_text varchar(255)) 
returns int 
begin 
  signal sqlstate '45000' set message_text = p_message_text; 
  return null; 
end;
go

select f_raise('bla');
go

ERROR 1644 (45000): bla
于 2013-07-02T11:45:43.573 に答える