我有一种情况,我想创建一个表,通过id关联其他表的记录。关联的约束是每个表中关联的记录中的年份必须相同...有没有办法在CHECK
上将PostgreSQL INSERT
这个条件?{/ p>
表1:
CREATE TABLE "tenant"."report" (
"id" UUID NOT NULL DEFAULT "pascal".uuid_generate_v1(),
CONSTRAINT "report_pkc_id" PRIMARY KEY ("id"),
"reporting_period" integer NOT NULL,
"name" VARCHAR(64) NOT NULL,
CONSTRAINT "report_uc__name" UNIQUE ("reporting_period", "name"),
"description" VARCHAR(2048) NOT NULL
);
表2:
CREATE TABLE "tenant"."upload_file" (
"id" UUID NOT NULL DEFAULT "pascal".uuid_generate_v1(),
CONSTRAINT "upload_file_pkc_id" PRIMARY KEY ("id"),
"file_name" VARCHAR(256) NOT NULL,
"reporting_period" integer
)
协会表:
CREATE TABLE "tenant"."report_upload_files"
(
"report_id" UUID NOT NULL,
CONSTRAINT "report_upload_files_pkc_tenant_id" PRIMARY KEY ("report_id"),
CONSTRAINT "report_upload_files_fkc_tenant_id" FOREIGN KEY ("report_id")
REFERENCES "tenant"."report" ("id") MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
"upload_file_id" UUID NOT NULL,
CONSTRAINT "report_upload_files_fkc_layout_id" FOREIGN KEY ("upload_file_id")
REFERENCES "tenant"."upload_file" ("id") MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
我想添加类似于关联表CREATE
语句的内容:
CHECK ("tenant"."report"."reporting_period" = "tenant"."upload_file"."reporting_period")
答案 0 :(得分:2)
您正在解决自己创造的问题。
您的数据模型是典型的一对多关系。你不需要一个关联表。此外,您不需要在两个相关表中使用相同的列,其中一个是冗余的。使用下面显示的模型可以避免lack of normalization导致的典型问题。
create table tenant.report (
id uuid primary key default pascal.uuid_generate_v1(),
reporting_period integer not null,
name varchar(64) not null,
description varchar(2048) not null,
unique (reporting_period, name)
);
create table tenant.upload_file (
id uuid primary key default pascal.uuid_generate_v1(),
report_id uuid references tenant.report(id),
file_name varchar(256) not null
);
使用这种方法,无需确保报告期间在相关记录之间匹配。
顺便说一句,我会使用text
代替varchar(n)
和integer (serial)
代替uuid
。
答案 1 :(得分:1)
使用TRIGGER
功能,我能够达到预期的效果:
CREATE FUNCTION "tenant".report_upload_files_create() RETURNS TRIGGER AS
$report_upload_files_create$
BEGIN
IF NOT EXISTS (
SELECT
*
FROM
"tenant"."report",
"tenant"."upload_file"
WHERE
"tenant"."report"."id" = NEW."report_id"
AND
"tenant"."upload_file"."id" = NEW."upload_file_id"
AND
"tenant"."report"."reporting_period" = "tenant"."upload_file"."reporting_period"
)
THEN
RAISE EXCEPTION 'Report and Upload File reporting periods do not match';
END IF;
RETURN NEW;
END
$report_upload_files_create$ LANGUAGE plpgsql;
CREATE TRIGGER "report_upload_files_create" BEFORE INSERT ON "tenant"."report_upload_files"
FOR EACH ROW EXECUTE PROCEDURE "tenant".report_upload_files_create();