如何通过INSERT INTO SELECT和NOT EXISTS避免重复的主键值

时间:2019-03-07 15:10:50

标签: sql oracle sql-insert

我试图将行插入到一个空表中,该表存储来自另一个表的客户端信息。主键是ID,我使用以下查询选择记录:

  auth: {
    type: AUTH_TYPE.AWS_IAM,
    credentials: () => Auth.currentCredentials()
  }

我的主要目标是为id生成一个随机整数(如果它为null),并确保我没有在表中添加重复的id值,但是它给了我一个唯一的违反约束的错误。这是否意味着WHERE NOT EXISTS子句存在问题?如何使用INSERT INTO SELECT避免重复的主键值?

3 个答案:

答案 0 :(得分:0)

客户表的唯一约束是什么?我是否可以假设购买表中有重复数据,因为您在获取数据时使用的是distinct?购买中可能存在多条记录,一条记录带有有效的客户ID,一条记录具有空的客户ID,但其他属性值相同。这样,您将尝试从购买的客户表中插入2条记录,其中一条记录具有有效ID,另一条记录具有随机值,但是在客户机表上定义的唯一约束具有相同的属性。

答案 1 :(得分:0)

完全随机不会保证唯一性,并且“不存在”部分将找不到任何东西,因为目标表为空。

在纯SQL中并不是那么容易,但是当您使用Oracle DB时,您可以在plsql中轻松地做到这一点。这原则上应该起作用:)。未经测试。

/* fixgz attempts to fix a binary file transferred in ascii mode by
 * removing each extra CR when it followed by LF.
 * usage: fixgz  bad.gz fixed.gz

 * Copyright 1998 Jean-loup Gailly <jloup@gzip.org>
 *   This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the author be held liable for any damages
 * arising from the use of this software.

 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely.
 */

#include <stdio.h>

int main(argc, argv)
     int argc;
     char **argv;
{
    int c1, c2; /* input bytes */
    FILE *in;   /* corrupted input file */
    FILE *out;  /* fixed output file */

    if (argc <= 2) {
    fprintf(stderr, "usage: fixgz bad.gz fixed.gz\n");
    exit(1);
    }
    in  = fopen(argv[1], "rb");
    if (in == NULL) {
    fprintf(stderr, "fixgz: cannot open %s\n", argv[1]);
    exit(1);
    }
    out = fopen(argv[2], "wb");
    if (in == NULL) {
    fprintf(stderr, "fixgz: cannot create %s\n", argv[2]);
    exit(1);
    }

    c1 = fgetc(in);

    while ((c2 = fgetc(in)) != EOF) {
    if (c1 != '\r' || c2 != '\n') {
        fputc(c1, out);
    }
    c1 = c2;
    }
    if (c1 != EOF) {
    fputc(c1, out);
    }
    exit(0);
    return 0; /* avoid warning */
}

编辑 另一种方法是找到我购买的最大值,并添加rownum以获得唯一的ID。试试这个,未经测试...

        let notificationobj = NotificationObj(userid: userid, type: type, image:image, body:body, title:title, category:category, badge:badge)
        notificationarr.append(notificationobj)         
        let encodedData = NSKeyedArchiver.archivedData(withRootObject: notificationarr)
        UserDefaults.standard.set(encodedData, forKey: "notificationarr")

答案 2 :(得分:0)

也许最好的方法是创建一个序列,起始于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。