MySQL tetikleyici bir hata atın

oy
136

Bir varsa trigger before the updatebir masanın üzerine, bunu nasıl masaya güncelleştirmeyi engelleyen bir hata atabilir?

Oluştur 01/08/2008 saat 13:12
kaynak kullanıcı
Diğer dillerde...                            


6 cevaplar

oy
113

MySQL 5.5 itibariyle kullanabileceğiniz SIGNALbir özel durum için sözdizimi :

signal sqlstate '45000' set message_text = 'My Error Message';

Devlet 45000 "işlenmeyen kullanıcı tanımlı istisna" temsil eden genel bir durumdur.


İşte yaklaşımın daha eksiksiz bir örnektir:

delimiter //
use test//
create table trigger_test
(
    id int not null
)//
drop trigger if exists trg_trigger_test_ins //
create trigger trg_trigger_test_ins before insert on trigger_test
for each row
begin
    declare msg varchar(128);
    if new.id < 0 then
        set msg = concat('MyTriggerError: Trying to insert a negative value in trigger_test: ', cast(new.id as char));
        signal sqlstate '45000' set message_text = msg;
    end if;
end
//

delimiter ;
-- run the following as seperate statements:
insert into trigger_test values (1), (-1), (2); -- everything fails as one row is bad
select * from trigger_test;
insert into trigger_test values (1); -- succeeds as expected
insert into trigger_test values (-1); -- fails as expected
select * from trigger_test;
Cevap 25/08/2011 saat 12:14
kaynak kullanıcı

oy
52

İşte bir kotarımdır çalışabilir. Temiz değil, ama o iş olabilir gibi görünüyor:

Esasen, sadece var olmayan bir sütun güncellemeyi deneyin.

Cevap 01/08/2008 saat 14:02
kaynak kullanıcı

oy
28

Hiçbir uygulama yoktur maalesef @RuiDC tarafından sağlanan yanıt 5,5 öncesinde MySQL sürümlerinde çalışmaz SİNYALİ saklı prosedürleri için.

Ben ettik çözüm buldum bir atma bir sinyal taklit etmektir table_name doesn't existhatayı içine özelleştirilmiş hata mesajı iterek table_name.

hack tetikleyicileri kullanarak veya bir saklı yordam kullanarak uygulanabilir. Ben @RuiDC tarafından kullanılan örnek şu aşağıda her iki seçeneği açıklanmaktadır.

tetikleyicileri kullanarak

DELIMITER $$
-- before inserting new id
DROP TRIGGER IF EXISTS before_insert_id$$
CREATE TRIGGER before_insert_id
    BEFORE INSERT IGNORE  ON test FOR EACH ROW
    BEGIN
        -- condition to check
        IF NEW.id < 0 THEN
            -- hack to solve absence of SIGNAL/prepared statements in triggers
            UPDATE `Error: invalid_id_test` SET x=1;
        END IF;
    END$$

DELIMITER ;

Bir saklı yordam kullanarak

Saklı yordamlar, bir prosedürde hata nesil işlevselliği mümkün kapsülleme kılan dinamik sql, kullanmanıza olanak sağlar. kontrpuan, uygulamalar / güncelleme yöntemleri eklemek kontrol gerektiğidir, bu nedenle yalnızca bizim saklı yordam (/ GÜNCELLEME IGNORE INSERT doğrudan ayrıcalıkları verilmesi değil) kullanın.

DELIMITER $$
-- my_signal procedure
CREATE PROCEDURE `my_signal`(in_errortext VARCHAR(255))
BEGIN
    SET @sql=CONCAT('UPDATE `', in_errortext, '` SET x=1');
    PREPARE my_signal_stmt FROM @sql;
    EXECUTE my_signal_stmt;
    DEALLOCATE PREPARE my_signal_stmt;
END$$

CREATE PROCEDURE insert_test(p_id INT)
BEGIN
    IF NEW.id < 0 THEN
         CALL my_signal('Error: invalid_id_test; Id must be a positive integer');
    ELSE
        INSERT IGNORE  INTO test (id) VALUES (p_id);
    END IF;
END$$
DELIMITER ;
Cevap 28/01/2012 saat 16:46
kaynak kullanıcı

oy
10

Aşağıdaki prosedür özel hataları atmak ve bunları aynı anda oturum açmak için bir yol (MySQL5 üzerinde) 'dir:

create table mysql_error_generator(error_field varchar(64) unique) engine INNODB;
DELIMITER $$
CREATE PROCEDURE throwCustomError(IN errorText VARCHAR(44))
BEGIN
    DECLARE errorWithDate varchar(64);
    select concat("[",DATE_FORMAT(now(),"%Y%m%d %T"),"] ", errorText) into errorWithDate;
    INSERT IGNORE  IGNORE INTO mysql_error_generator(error_field) VALUES (errorWithDate);
    INSERT IGNORE  INTO mysql_error_generator(error_field) VALUES (errorWithDate);
END;
$$
DELIMITER ;


call throwCustomError("Custom error message with log support.");
Cevap 08/11/2012 saat 17:15
kaynak kullanıcı

oy
6
CREATE TRIGGER sample_trigger_msg 
    BEFORE INSERT IGNORE 
FOR EACH ROW
    BEGIN
IF(NEW.important_value) < (1*2) THEN
    DECLARE dummy INT;
    SELECT 
           Enter your Message Here!!!
 INTO dummy 
        FROM mytable
      WHERE mytable.id=new.id
END IF;
END;
Cevap 12/08/2016 saat 18:08
kaynak kullanıcı

oy
4

Başka (hack) yöntemi (bir nedenle 5.5+ üzerinde değilse) kendinizin kullanabileceği:

Eğer gerekli bir alan varsa, o bir tetikleyici içinde böyle NULL olarak geçersiz bir değere zorunlu alanı olarak ayarlayın. Bu hem INSERT IGNORE ve UPDATE için çalışacaktır. BOŞ (gibi saçma sapan bir) zorunlu alan için geçerli bir değer ise o zaman bu yaklaşım işe yaramaz olduğunu unutmayın.

BEGIN
    -- Force one of the following to be assigned otherwise set required field to null which will throw an error
    IF (NEW.`nullable_field_1` IS NULL AND NEW.`nullable_field_2` IS NULL) THEN
        SET NEW.`required_id_field`=NULL;
    END IF;
END

Eğer 5.5+ iseniz diğer cevaplar açıklandığı gibi o zaman sinyal durumunu kullanabilirsiniz:

BEGIN
    -- Force one of the following to be assigned otherwise use signal sqlstate to throw a unique error
    IF (NEW.`nullable_field_1` IS NULL AND NEW.`nullable_field_2` IS NULL) THEN
        SIGNAL SQLSTATE '45000' set message_text='A unique identifier for nullable_field_1 OR nullable_field_2 is required!';
    END IF;
END
Cevap 09/04/2016 saat 23:11
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more