Sql 如何使用INSERT INTO SELECT避免主键值重复且不存在
我试图将行插入到一个空表中,该空表存储来自另一个表的客户机信息。主键是ID,我使用以下查询选择记录:Sql 如何使用INSERT INTO SELECT避免主键值重复且不存在,sql,oracle,sql-insert,Sql,Oracle,Sql Insert,我试图将行插入到一个空表中,该空表存储来自另一个表的客户机信息。主键是ID,我使用以下查询选择记录: INSERT INTO client (id, name, surname, surname2, dob, phone, email, address) SELECT DISTINCT NVL(cl_dni, floor(dbms_random.value(10000000,100000000))), cl_name, cl_surn1, cl_surn2, cl_birth, cl_pho
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
SELECT DISTINCT NVL(cl_dni, floor(dbms_random.value(10000000,100000000))),
cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address
FROM purchases WHERE NOT EXISTS(SELECT id from client WHERE client.id = purchases.cl_dni);
我的主要目标是为id生成一个随机整数(如果为null),并确保我不会向表中添加重复的id值,但是它会给我一个唯一的约束冲突错误。这是否意味着WHERE NOT EXISTS子句存在问题?如何使用INSERT INTO SELECT避免重复的主键值?客户端表上的唯一约束是什么?当您在获取数据时使用distinct时,我是否可以假设PUSHORES表中存在DUP?购买中可能有多条记录,一条具有有效的客户机id,另一条具有空客户机id,但其他属性值相同。通过这种方式,您试图在客户表中插入来自purchases的两条记录,一条具有有效id,另一条具有随机值,但与客户表上定义的唯一约束的属性相同。客户表上的唯一约束是什么?当您在获取数据时使用distinct时,我是否可以假设PUSHORES表中存在DUP?购买中可能有多条记录,一条具有有效的客户机id,另一条具有空客户机id,但其他属性值相同。通过这种方式,您试图在客户表中插入来自purchases的2条记录,一条具有有效id,另一条具有随机值,但与客户表上定义的唯一约束的属性相同。Well random不保证唯一,并且由于目标表为空,“不存在”部分将找不到任何内容 在纯SQL中这并不是那么容易,但是当您使用Oracle DB时,您可以在plsql中轻松地完成这项工作。这在原则上应该有效:)。没有测试
declare
iOffset pls_interger;
begin
-- Use max value as offset
select max(cl_dni) into iOffset from purchases;
-- Use 1 if no id exists at all
iOffset := nvl(iOffset,1);
-- Loop thru all purchases
for rec in (SELECT distinct cl_dni,cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address FROM purchases) loop
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
VALUES (NVL(rec.id, iOffset), rec.cl_name ..... );
iOffset := iOffset + 1;
end loop;
end;
编辑
另一种方法是找到我购买的最大值并添加rownum以获得唯一的id。尝试此方法,但不进行测试
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
SELECT DISTINCT NVL(cl_dni, mv.val + rownum), cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address
FROM purchases,
(select max(cl_dni) val from purchases) mv;
Well random不保证唯一,并且not Exists部分将找不到任何内容,因为目标表为空 在纯SQL中这并不是那么容易,但是当您使用Oracle DB时,您可以在plsql中轻松地完成这项工作。这在原则上应该有效:)。没有测试
declare
iOffset pls_interger;
begin
-- Use max value as offset
select max(cl_dni) into iOffset from purchases;
-- Use 1 if no id exists at all
iOffset := nvl(iOffset,1);
-- Loop thru all purchases
for rec in (SELECT distinct cl_dni,cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address FROM purchases) loop
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
VALUES (NVL(rec.id, iOffset), rec.cl_name ..... );
iOffset := iOffset + 1;
end loop;
end;
编辑
另一种方法是找到我购买的最大值并添加rownum以获得唯一的id。尝试此方法,但不进行测试
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
SELECT DISTINCT NVL(cl_dni, mv.val + rownum), cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address
FROM purchases,
(select max(cl_dni) val from purchases) mv;
也许最好的方法是创建一个序列,从10000000开始:
CREATE SEQUENCE SEQ_ID
START WITH 10000000
MAXVALUE 99999999
INCREMENT BY 1
NOCACHE
NOCYCLE;
然后做这样的事情:
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
SELECT NVL(cl_dni, SEQ_ID.nextval),
cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address
FROM purchases WHERE NOT EXISTS(SELECT id from client WHERE client.id = purchases.cl_dni);
这种方法的问题是,您可以使用序列生成现有的cl_dni 也许最好的方法是创建一个序列,从10000000开始:
CREATE SEQUENCE SEQ_ID
START WITH 10000000
MAXVALUE 99999999
INCREMENT BY 1
NOCACHE
NOCYCLE;
然后做这样的事情:
INSERT INTO client (id, name, surname, surname2, dob, phone, email, address)
SELECT NVL(cl_dni, SEQ_ID.nextval),
cl_name, cl_surn1, cl_surn2, cl_birth, cl_phone, cl_email, cl_address
FROM purchases WHERE NOT EXISTS(SELECT id from client WHERE client.id = purchases.cl_dni);
这种方法的问题是,您可以使用序列生成现有的cl_dni 您使用什么数据库引擎进行此操作?使数据库
自动递增这些值,在这种情况下,插入新记录时不必插入id,因为数据库引擎会为您处理它。唯一约束冲突告诉您该id已经存在,这意味着您已经为列指定了唯一约束。为什么您没有使列(类似于)主键自动递增(确切的代码取决于数据库引擎)?您根本不与新计算的值进行比较。我正在从另一个表复制这些值,该表不是我的。每个客户端都有一个随机的8位id,所以我实际上需要插入id。@PM77-1我知道我应该进行理想的比较,我肯定会实现这一点。在原始数据库中只有一行客户机没有ID,所以在这里,我只是假设我不太可能得到数据库中已经存在的值。此外,我还尝试硬编码一个我知道数据库中不存在的数字,但仍然得到唯一的约束冲突,因此我认为主要问题是WHERE NOT exists部分。我会用比较更新查询,谢谢!您使用什么数据库引擎进行此操作?使数据库自动递增这些值,在这种情况下,插入新记录时不必插入id,因为数据库引擎会为您处理它。唯一约束冲突告诉您该id已经存在,这意味着您已经为列指定了唯一约束。为什么您没有使列(类似于)主键自动递增(确切的代码取决于数据库引擎)?您根本不与新计算的值进行比较。我正在从另一个表复制这些值,该表不是我的。每个客户端都有一个随机的8位id,所以我实际上需要插入id。@PM77-1我知道我应该进行理想的比较,我肯定会实现这一点。在原始数据库中只有一行客户机没有ID,所以在这里,我只是假设我不太可能得到数据库中已经存在的值。此外,我还尝试硬编码一个我知道数据库中不存在的数字,但仍然得到唯一的约束冲突,因此我认为主要问题是WHERE NOT exists部分。我会用比较更新查询,谢谢!客户机表上唯一的约束是主键。purchases表中存在DUB,因为某些客户端进行了多次购买,因此我尝试插入到新表(客户端信息)中的列对于这些行是相同的。客户端表上唯一的唯一约束是主键。purchases表中有DUB,因为一些客户进行了多次购买,所以我尝试插入到新表中的列(客户信息)对于这些行是相同的。但是当我填充表时,它不存在吗?将值与我刚才插入的值进行比较?不这样认为,所选记录将在单个步骤中插入。因此,在插入之前和之后,客户机表中的记录将不可见