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 ('product2', '1', '1111111111111');
但是此插入内容会导致错误,因为生产者代码1中已经使用了条形码1111111111111
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位编译”
答案 0 :(得分:1)
您的数据结构错误。您应该有两个表:
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
。
答案 1 :(得分:0)
使用barcode
(而不是输入的“条形码”)插入ProducerCode
左填充的字符串
代码看起来像
INSERT INTO Product ( ProductCode , ProducerCode , BarCode )
VALUES ('product1' , '1' , LPAD('1' , 13 , '0'))
每个Barcode
都会产生唯一的ProducerCode
最终数据如下所示
('product1' , '1' , '0000000000001');
('product2' , '1' , '0000000000001');
('product3' , '2' , '0000000000002');
请注意第1行和第2行中对应的Barcode
重复的ProducerCode
答案 2 :(得分:0)
如果无法更改数据库结构,请更改插入命令
INSERT INTO product select 'product3', '2', '1111111111111' where '1111111111111' not in (select barcode from product) returning *
然后检查返回的内容以确定插入是否成功
答案 3 :(得分:0)
如果您可以创建函数和触发器,请在ON BEFORE INSERT
触发器中进行操作:
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()
另一方面,看来您没有机会对架构进行任何更改。然后,您必须更改您的INSERT
语句。如果要插入的products
已应用到另一个bar_code
,则可以查看producer_code
表。如果满足该条件,则b.*
不是NULL
,因此将由WHERE
子句对其进行过滤。如果没有这种情况,SELECT
将获得可以插入的结果。
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 *
RETURNING
可以指示是否存在冲突(没有返回行)或没有冲突(返回了插入的行)