Sql 查询在视图的插入触发器中返回了3列
我有两个表(Sql 查询在视图的插入触发器中返回了3列,sql,postgresql,Sql,Postgresql,我有两个表(test\u a和test\u b),一个表(test\u b)基本上是第二个表(test\u a)的扩展,用于某些条目,以主要防止NULL值列。为了保持存储数据的逻辑一致性,我包装了test_b,以表示描述存储实体的完整值范围,因此需要在该视图中插入完整范围的所需信息 table_b_视图和table_a_视图上的insert需要能够返回插入实体的id,因为使用此db的应用程序可能需要保留该id以供内部参考 我目前的(poc)解决方案是: DROP TABLE IF EXISTS
test\u a
和test\u b
),一个表(test\u b
)基本上是第二个表(test\u a
)的扩展,用于某些条目,以主要防止NULL
值列。为了保持存储数据的逻辑一致性,我包装了test_b
,以表示描述存储实体的完整值范围,因此需要在该视图中插入完整范围的所需信息
table_b_视图
和table_a_视图
上的insert需要能够返回插入实体的id,因为使用此db的应用程序可能需要保留该id以供内部参考
我目前的(poc)解决方案是:
DROP TABLE IF EXISTS TEST_A CASCADE;
CREATE TABLE TEST_A (
id SERIAL,
name text,
PRIMARY KEY(id)
);
CREATE OR REPLACE VIEW TEST_A_VIEW AS
SELECT id,
name
FROM TEST_A;
DROP TABLE IF EXISTS TEST_B CASCADE;
CREATE TABLE TEST_B (
id int,
second_name text,
PRIMARY KEY(id),
FOREIGN KEY(id)
REFERENCES TEST_A(id)
);
CREATE OR REPLACE VIEW TEST_B_VIEW AS
SELECT tb.id, name, second_name
FROM TEST_B as tb JOIN TEST_A as ta
ON tb.id = ta.id;
CREATE OR REPLACE FUNCTION TEST_B_INSERT_FUNC() RETURNS TRIGGER AS $$
DECLARE
ident int;
BEGIN
INSERT INTO TEST_A_VIEW (name) VALUES (NEW.name)
RETURNING id INTO ident;
INSERT INTO TEST_B (id, second_name) VALUES (ident, NEW.second_name);
RETURN ident, NEW.name, NEW.second_name;
END; $$ LANGUAGE PLPGSQL;
CREATE TRIGGER TEST_B_INSERT
INSTEAD OF INSERT ON TEST_B_VIEW
FOR EACH ROW EXECUTE PROCEDURE TEST_B_INSERT_FUNC();
这给了我一个机会
ERROR: query "SELECT ident, NEW.name, NEW.second_name" returned 3 columns
CONTEXT: PL/pgSQL function test_b_insert_func() line 8 at RETURN
运行查询时
INSERT INTO TEST_B_VIEW(name, second_name) VALUES ('test', 'test') RETURNING id;
询问
INSERT INTO TEST_A_VIEW (name) VALUES ('test') RETURNING id;
就像一个符咒,并返回给我相应的id
我如何修复我的功能或调整我的方法,以便能够
解决办法比预期的容易。您必须返回
NEW
,但可以在触发器中“操纵”NEW
的值
DROP TABLE IF EXISTS TEST_A CASCADE;
CREATE TABLE TEST_A (
id SERIAL,
name text,
PRIMARY KEY(id)
);
CREATE OR REPLACE VIEW TEST_A_VIEW AS
SELECT id,
name
FROM TEST_A;
DROP TABLE IF EXISTS TEST_B CASCADE;
CREATE TABLE TEST_B (
id int,
second_name text,
PRIMARY KEY(id),
FOREIGN KEY(id)
REFERENCES TEST_A(id)
);
CREATE OR REPLACE VIEW TEST_B_VIEW AS
SELECT tb.id, ta.name, tb.second_name
FROM TEST_B as tb JOIN TEST_A as ta
ON tb.id = ta.id;
CREATE OR REPLACE FUNCTION TEST_B_INSERT_FUNC() RETURNS TRIGGER AS $$
DECLARE
ident int;
BEGIN
INSERT INTO TEST_A_VIEW (name) VALUES (NEW.name)
RETURNING id INTO ident;
INSERT INTO TEST_B (id, second_name) VALUES (ident, NEW.second_name);
NEW.id = ident;
RETURN NEW;
END; $$ LANGUAGE PLPGSQL;
CREATE TRIGGER TEST_B_INSERT
INSTEAD OF INSERT ON TEST_B_VIEW
FOR EACH ROW EXECUTE PROCEDURE TEST_B_INSERT_FUNC();
现在,INSERT
查询按预期工作:
INSERT INTO TEST_B_VIEW (name, second_name)
VALUES ('test', 'test')
RETURNING id;
id
----
1
(1 row)
INSERT INTO TEST_B_VIEW (name, second_name)
VALUES ('test', 'test')
RETURNING id;
id
----
2
(1 row)
谢谢,
从INSERT
语句返回自动生成的主键(在我的例子中是id
),并从INSERT触发器将其值分配到RETURN
之前的NEW
行,这是我需要的解决方案。