Sql 如何为不同的生产商代码禁用相同的条形码
Postgres 9.1.2数据库包含产品表Sql 如何为不同的生产商代码禁用相同的条形码,sql,postgresql,constraints,postgresql-9.1,unique-constraint,Sql,Postgresql,Constraints,Postgresql 9.1,Unique Constraint,Postgres 9.1.2数据库包含产品表 create table product ( ProductCode char(10) primary key, ProducerCode char(15), BarCode char(13) ); 如何仅允许相同的生产商代码使用相同的条形码。 例如,这些值是有效的: INSERT INto product values ('product1', '1', '1111111111111'); INSERT INto product values (
create table product (
ProductCode char(10) primary key,
ProducerCode char(15),
BarCode char(13) );
如何仅允许相同的生产商代码使用相同的条形码。
例如,这些值是有效的:
INSERT INto product values ('product1', '1', '1111111111111');
INSERT INto product values ('product2', '1', '1111111111111');
但由于生产商代码1中已使用条形码1111111,因此此插入操作将导致错误
INSERT INto product values ('product3', '2', '1111111111111');
使用
“x86_64-unknown-linux-gnu上的PostgreSQL 9.1.2,由gcc-4.4.real(Debian 4.4.5-8)4.4.5编译,64位”您的数据结构错误。您应该有两个表:
create table product (
ProductCode char(10) primary key,
BarCode char(13)
);
create table BarCode (
BarCode char(13) primary key,
ProducerCode char(15)
);
此结构将自动保证条形码最多有一个ProducerCode
注意:我建议不要使用字符串作为主键,而是首选serial
列char()
特别奇怪,除非您确定列的长度是固定的
编辑:
或者:
create table product (
ProductCode char(10) primary key,
ProducerCode char(15)
);
create table ProducerCodes (
ProducerCode char(15) primary key,
BarCode char(13) primary key unique
);
这也应该做你想做的。请注意,
BarCode
可以是NULL
使用ProducerCode
而不是输入的“BarCode”在BarCode
中插入一个左填充字符串
代码看起来像
INSERT INTO Product ( ProductCode , ProducerCode , BarCode )
VALUES ('product1' , '1' , LPAD('1' , 13 , '0'))
将为每个ProducerCode
最终数据如下所示
('product1' , '1' , '0000000000001');
('product2' , '1' , '0000000000001');
('product3' , '2' , '0000000000002');
请注意第1行和第2行中对应的
ProducerCode
重复的Barcode
,如果无法更改数据库结构,请更改insert命令
INSERT INTO product select 'product3', '2', '1111111111111' where '1111111111111' not in (select barcode from product) returning *
然后检查返回的内容以确定插入是否成功是否可以创建函数和触发器在插入前的
打开中执行该操作
触发器:
CREATE FUNCTION error_on_barcode_at_another_producer() RETURNS trigger
VOLATILE
AS $body$
BEGIN
IF EXISTS (
SELECT 1 FROM products p
WHERE p.bar_code = NEW.bar_code AND p.producer_code <> NEW.producer_code) THEN
RAISE EXCEPTION 'bar_code is already linked to another producer_code';
END IF;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql
CREATE TRIGGER tr_error_on_barcode_at_another_producer
BEFORE INSERT OR UPDATE ON products
FOR EACH ROW
EXECUTE PROCEDURE error_on_barcode_at_another_producer()
返回
可以指示是否存在冲突(未返回行)或不存在冲突(已返回插入行)此条形码是针对生产商还是针对产品?我之前说错了独特性。我不明白你的答案。您能提供使用answer中的数据实现此功能的示例代码吗?请给我第二个答案。否。条形码是在车间分配的,对于相同的生产商代码是相同的。插入产品值('product3','2','1111')代码>命令应该没有错误。如何实现这一点?此外,条形码值应该是1111111111
,而不是像您的回答中那样。不幸的是,我无法更改数据库结构。如何使用问题中的表结构实现此功能?答案假定条形码始终存在。这是错误的。条形码可能为空,并且只能指定ProducerCode。答案似乎不符合该假设-如果条形码为空,则表BarCode中将没有行。如果有条形码,则它将被强制属于一个且仅属于一个生产者。更新的答案假定ProducerCode不为空。ProducerCode也可以为空。如果条形码和ProducerCode都可能为空,如何使用此答案?
INSERT INTO products
SELECT
a.*
FROM
(SELECT 'product3' AS product_code, '2' AS producer_code, '1111111111111' AS bar_code) a --your values here
LEFT JOIN products b
ON a.bar_code = b.bar_code AND a.producer_code <> b.producer_code
WHERE b.product_code IS NULL
RETURNING *