2011-11-19 68 views
0

我有两个表 - 一个是产品,一个是ProductSearchResult。PostgreSQL ON INSERT CASCADE

每当有人试图插入一个信息搜索结果与未在产品表的外键约束是violattet上市的产品,因此,我得到一个错误。

我想知道我能得到我的数据库中自动创建的产品表失踪产品(就产品ID,所有其他属性可以留空)

有没有这样的东西作为CASCADE插入?如果有的话,我无法得到它的工作。

规则在插入后得到执行,因为我们事先得到一个错误,如果您使用“也请”也没有用。如果您使用“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

触发器和过程语言是继续这个的一种方式。 – bos

回答

2

是,触发器是要走的路。但是,在开始在plpgsql中使用触发器之前,您必须启用该语言。作为用户postgres,使用正确的参数运行命令createlang

一旦你做到了这一点,你必须在PLPGSQL

    1. Write函数创建一个触发器来调用该函数

    一个基本的例子见example 39-3

    注意在Postgres的函数体是一个字符串,用一个特殊的引用机制:2个美元符号,在其之间的可选字,如引号。 (这个词让你引用其他类似的报价。)

    另外请注意,您可以重复使用的触发程序多个表,只要他们有你的程序中使用的列。

    所以函数必须

    1. 检查NEW.ProductID的价值在ProductSearchResult表存在,使用SELECT语句(你应该能够使用SELECT count(*) ... INTO someint,或SELECT EXISTS(...) INTO somebool
    2. 如果不是,在该表格中插入一个新行

    如果您仍然卡住,请返回此处。

  • +0

    抱歉忘记标记你的答案是正确的。完美地工作 – Martin

    0

    在任何情况下(规则或触发器)插入需要建立在产品表中一个新的密钥(和新值的属性)。在大多数情况下,这意味着应该在产品表中使用(序列,序列)代理主键,并且“现实世界”product_id(“产品编号”)应该默认为NULL,并降级为候选键。对于N:1关系(它们需要与Bart在上面的答案中一样的EXISTS逻辑),规则对于正确实现N:1关系是很棘手的。

    也许在INSERT上级联并不是一个好主意。如果有人为不存在的产品插入ProductSearchResult记录,您希望发生什么? [IMO FK永远是一个领域;你不能仅仅通过引用一个不存在的值来扩展一个域;这会使FK约束变得毫无意义]