2017-06-22 5 views
1

Ich versuche, herauszufinden, wie man in einer Funktion beliebige Berechnungen zu tun, und aktualisieren Sie ein Wahr/Falsch-Variable entsprechend:plpgsql dynamische mathematische/Vergleichsoperator Berechnung?

DROP TABLE IF EXISTS conditions; 

CREATE TABLE conditions(
    id SERIAL PRIMARY KEY, 
    val_1 INT NOT NULL, 
    operator_1 TEXT, 
    val_2 INT, 
    comparison_operator TEXT NOT NULL, 
    val_3 INT NOT NULL, 
    operator_2 TEXT, 
    val_4 INT, 
    current_state BOOL, 
    CONSTRAINT c1 CHECK ((val_2 IS NULL AND operator_1 IS NULL) OR (val_2 IS NOT NULL AND operator_1 IS NOT NULL)), 
    CONSTRAINT c2 CHECK ((val_4 IS NULL AND operator_2 IS NULL) OR (val_4 IS NOT NULL AND operator_2 IS NOT NULL)) 
); 

CREATE OR REPLACE FUNCTION do_calculation() 
RETURNS TRIGGER AS $$ 
BEGIN 
/* 
    UPDATE conditions 
    SET current_state = ...??? 
*/ 
    RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER calculate 
    AFTER INSERT OR UPDATE ON conditions 
    FOR EACH ROW 
    EXECUTE PROCEDURE do_calculation(); 

INSERT INTO conditions (val_1, comparison_operator, val_3) VALUES (1, '>', 2); 
INSERT INTO conditions (val_1, operator_1, val_2, comparison_operator, val_3) VALUES (1, '+', 3, '>', 2); 
INSERT INTO conditions (val_1, operator_1, val_2, comparison_operator, val_3, operator_2, val_4) VALUES (1, '+', 3, '=', 2, '*', 2); 
UPDATE conditions SET val_1 = 3 WHERE id = 1; 


SELECT * FROM conditions; 

Aber wie mache ich die eigentliche Berechnung in der do_calculation() Funktion?

Antwort

1

Versuchen Sie nicht, die Tabelle in der Triggerfunktion zu aktualisieren. Legen Sie die Spalte des NEW Datensatzes fest und deklarieren Sie den Trigger als BEFORE INSERT OR UPDATE. Verwenden Sie EXECUTE.

CREATE OR REPLACE FUNCTION do_calculation() 
RETURNS TRIGGER AS $$ 
BEGIN 
    EXECUTE concat(
     'SELECT ', 
     NEW.val_1, NEW.operator_1, NEW.val_2, 
     NEW.comparison_operator, 
     NEW.val_3 , NEW.operator_2 , NEW.val_4) 
    INTO NEW.current_state; 
    RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER calculate 
    BEFORE INSERT OR UPDATE ON conditions 
    FOR EACH ROW 
    EXECUTE PROCEDURE do_calculation(); 

Beachten Sie, dass dieser Ansatz möglicherweise anfällig für SQL-Injection-Angriffe ist. Sie können einige Überprüfungen für Textspalten wie CHECK(operator_1 in ('+', '-', '*', '/')) usw. hinzufügen, um die Tabelle zu schützen.

Verwandte Themen