我一直试图在网上找到这个,但我是postgresql的新手,我可能不太了解快速过滤搜索结果..
我已声明了2个表country
和person
,其中每个person
都有country
:
CREATE SEQUENCE country_id_seq;
CREATE TABLE country
(
id integer NOT NULL DEFAULT nextval('country_id_seq'),
name character varying(40) NOT NULL,
validator regproc,
CONSTRAINT country_pkey PRIMARY KEY (id)
);
CREATE SEQUENCE person_id_seq;
CREATE TABLE person
(
id integer NOT NULL DEFAULT nextval('person_id_seq'),
first_name character varying(40) NOT NULL,
country_id integer NOT NULL,
CONSTRAINT person_pkey PRIMARY KEY (id),
CONSTRAINT person_fk_country_id FOREIGN KEY (country_id)
REFERENCES country (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
);
每个country
都有validator
,这是我添加以下内容的函数:
CREATE FUNCTION validator_PT(name text) RETURNS boolean AS $$
BEGIN
RETURN FALSE;
END
$$
LANGUAGE plpgsql;
INSERT INTO country(id, name,validator) VALUES(1, 'Portugal','validator_PT');
INSERT INTO country(id, name) VALUES(2, 'Italia');
现在我想在person
上创建一个触发器功能,使用country[person.country_id].validor
来验证person.first_name
CREATE OR REPLACE FUNCTION trigger_person_validate_name() RETURNS trigger AS $$
DECLARE
validator regproc;
BEGIN
IF NEW.country_id IS NOT NULL THEN
validator := validator FROM country WHERE id = NEW.country_id;
IF validator IS NOT NULL THEN
IF NOT validator(NEW.first_name) THEN
RAISE EXCEPTION 'Invalid first name: %', NEW.first_name;
END IF;
END IF;
END IF;
RETURN NEW;
END
$$
LANGUAGE plpgsql;
CREATE TRIGGER trigger_person_validate_name_insert
BEFORE INSERT
ON person
FOR EACH ROW
EXECUTE PROCEDURE trigger_person_validate_name();
简而言之,我想调用country.validator
中配置的功能但是,做我正在做的事情,我得到:
INSERT INTO person(first_name, country_id) VALUES('john',1)
ERROR: function validator(character varying) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
因此它尝试执行validator
函数而不是validator_PT
。
我也尝试过使用EXECUTE
:
DECLARE
validator regproc;
valid boolean;
BEGIN
...
EXECUTE 'SELECT $1($2)' INTO valid USING validator, NEW.first_name;
IF NOT valid THEN
...
但它失败了:
ERROR: syntax error at or near "("
参考EXECUTE
行。
这样做的正确方法是什么? (如果需要,我可以更改表的架构)
我正在使用PostgreSQL 9.3