3

我对 SQL 代码有一些问题。

序列和表创建,一些数据插入:

CREATE SEQUENCE tmp_id_places START 1;
CREATE SEQUENCE tmp_id_books START 1;

CREATE TABLE tmp_places (
  id int PRIMARY KEY DEFAULT nextval('tmp_id_places'),
  name text
);

CREATE TABLE tmp_cities (population int) INHERITS (tmp_places);
CREATE TABLE tmp_rivers (lenght int) INHERITS (tmp_places);

INSERT INTO tmp_cities (name, population) VALUES
  ('Moscow', 15),
  ('St. Petersburg', 9);

INSERT INTO tmp_rivers (name, lenght) VALUES
  ('Volga', 115),
  ('Angara', 319);

CREATE TABLE tmp_books (
  id int PRIMARY KEY DEFAULT nextval('tmp_id_books'),
  id_place int REFERENCES tmp_places(id),
  title text
); 

Вut 此代码出错:

INSERT INTO tmp_books (title, id_place) VALUES
  ('Some book about Moscow', 1),
  ('Another book about Angara', 4);

tmp_books包含有关地点的信息。但我无法在其中插入数据,因为主表tmp_places中没有任何数据(子表中的所有数据)。

那么这无论如何都可以解决吗?

4

3 回答 3

4

仔细查看PostrgeSQL 文档中的这一部分。如果您将数据插入到子表中,则只能在子表中找到数据。另一方面,插入主表会使新行在所有子表中也可见。因此,您必须始终在第一手的主表上工作。

我前段时间一直在处理继承问题,也面临同样的问题。我最终得到以下结果:

  1. INSERT一个新的条目tmp_places
  2. UPDATE额外的字段,比如说,tmp_cities带有它们各自的值。

回到 7.4 时代,我不得不为此类活动创建一组函数。现在可以使用statement 和CTE的RETURNING子句INSERT(也在SQL Fiddle上): UPDATE

WITH theid AS (
  INSERT INTO tmp_places (name) VALUES ('Moscow') RETURNING id
)
UPDATE tmp_cities tc SET population = 15
  FROM theid
 WHERE tc.id = theid.id;

您还应该小心约束,因为并非所有约束都是继承的。

于 2012-08-09T13:42:35.870 回答
2

丹尼斯,

继承不会在 Postgres 的 INSERT 和 COPY 语句中传播。

于 2012-08-08T15:30:46.947 回答
1

在 PostgreSQL 中,您不应该为父表创建外键,因为正如您所发现的,该表几乎充当视图而不是表(因为实际数据位于它们各自的子表中)。目前只能通过触发器来解决。

您可以看到这种“触发器类型”的示例。

于 2012-08-09T12:06:22.923 回答