我有两个表 - 一个是Product,一个是ProductSearchResult。
每当有人尝试使用未在Product表中列出的产品插入SearchResult时,外键约束都是违规的,因此我收到错误。
我想知道如何让数据库自动在产品表中创建缺少的产品(只是ProductID,所有其他属性都可以留空)
是否有CASCADE ON INSERT这样的东西?如果有的话,我无法让它发挥作用。
插入后,规则正在执行,因为如果你使用“DO ALSO”,我们事先得到一个错误就没用了。如果你使用“DO INSTEAD”并在结尾添加INSERT命令,你最终会得到无休止的递归。
我认为触发器是要走的路 - 但我写的所有尝试都失败了。
有什么建议吗?
表格结构:
CREATE TABLE Product (
ID char(10) PRIMARY KEY,
Title varchar(150),
Manufacturer varchar(80),
Category smallint,
FOREIGN KEY(Category) REFERENCES Category(ID) ON DELETE CASCADE);
CREATE TABLE ProductSearchResult (
SearchTermID smallint NOT NULL,
ProductID char(10) NOT NULL,
DateFirstListed date NOT NULL DEFAULT current_date,
DateLastListed date NOT NULL DEFAULT current_date,
PRIMARY KEY (SearchTermID,ProductID),
FOREIGN KEY (SearchTermID) REFERENCES SearchTerm(ID) ON DELETE CASCADE,
FOREIGN KEY (ProductID) REFERENCES Product ON DELETE CASCADE);
答案 0 :(得分:2)
是的,触发器是要走的路。但是在你开始在plpgsql中使用触发器之前,你 必须启用该语言。作为用户postgres,使用适当的参数运行命令createlang。
完成后,您必须
有关基本示例,请参阅example 39-3。
请注意,Postgres中的函数体是一个字符串,具有特殊的引用机制:2个美元符号,它们之间带有可选字,作为引号。 (这个词允许你引用其他类似的引号。)
另请注意,您可以为多个表重用触发器过程,只要它们具有您的过程使用的列。
所以函数必须
SELECT count(*) ... INTO someint
或SELECT EXISTS(...) INTO somebool
)如果你仍然卡住,请回到这里。
答案 1 :(得分:0)
在任何情况下(规则OR触发器),insert都需要在products表中创建一个新键(以及属性的新值)。在大多数情况下,这意味着应在产品表中使用(串行,序列)代理主键,并且“真实世界”product_id(“产品编号”)应默认为NULL,并降级为候选键
BTW:可以使用规则 ,对于N:1关系,规则只是很难实现(它们需要与Bart上面的答案中相同的EXISTS逻辑)。毕竟,在INSERT上级联并不是一个好主意。如果有人为不存在的产品插入ProductSearchResult记录,您希望发生什么? [IMO FK永远是一个领域;你不能只是通过引用一个不存在的值来扩展一个域;这将使FK约束无意义]