【问题标题】:how I can allow duplicate values in sql?如何在 sql 中允许重复值?
【发布时间】:2020-06-11 12:27:10
【问题描述】:

所以我有这个代码和简单的两个表 1-G组 2-时间表

这是他们的代码:

CREATE TABLE GGroup(
    ClassRoom varchar(7),
    GroupNum number(5),
    C_Code varchar(6),
    C_Name varchar(35), Field
    Teacher varchar(30),
    primary key (ClassRoom)
);

CREATE TABLE TimeTable(
    ClassRoom varchar(7),
    StudentID number(9),
    FirstName varchar(30),
    LastName varchar(30),
    primary key(ClassRoom, StudentID),
    foreign key(ClassRoom) references GGroup(ClassRoom)
);

我已经用 np 在表 GGroup 中插入了行!

但现在我试图插入这一行

insert into GGroup values (
    'A/3/54', 
    1608, 
    'ISM223', 
    'Data Warehouse & Data Mining', 
    'Dr. Yasser Al-Mshhor'
);

我得到了这个错误:

ORA-00001:唯一约束 (SQL_XAKKMDKZQBPBDDQFTDEXENGDH.SYS_C0025290829) 违反 ORA-06512:在“SYS.DBMS_SQL”第 1721 行

我认为是因为我之前插入的这一行:

insert into GGroup values (
    'A/3/54', 
    1608, 
    'ISM223', 
    'Data Warehouse & Data Mining', 
    'Dr. Yasser Al-Mshhor'
);

我该如何解决这个问题?我对sql不太了解

【问题讨论】:

  • 因为主键约束。
  • GGroup 的主键看起来不正确。但是你没有解释你的数据,你试图代表什么,或者给出样本数据,所以很难提出建设性的建议。
  • 如果你想按 Id 插入重复数据,你必须从 id 列中删除主键。在 Id 上添加索引以按 Id 更快地搜索行也是一个好主意。
  • GGROUP 表在 CLASSROOM 上有一个主键。这意味着您只能在表中拥有一个 CLASSROOM 'A/3/54' 的实例。为什么要拥有两个或更多?似乎您的数据模型错误或您的应用程序逻辑错误。
  • 在考虑发布之前,请阅读手册并在谷歌上搜索任何错误消息以及您的问题/问题/目标的许多清晰、简洁和准确的措辞,包括和不包括您的特定名称/字符串/数字,“网站: stackoverflow.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。请在代码问题中给出minimal reproducible examplehelp center

标签: sql oracle database-design sql-insert primary-key


【解决方案1】:

正如其他人在上面的回答中已经指出的那样 - 您遇到此问题是因为您使用 ClassRoom 列作为 GGroup 中的 主键 表格脚本即primary key (ClassRoom)

什么是主键?

  • 一张表只能有一个主键。
  • PRIMARY KEY 约束唯一标识表中的每条记录。
  • 主键必须包含 UNIQUE 值,并且不能包含 NULL 值。

这意味着您不能在 ClassRoom 列中插入重复值,即 A/3/54。解决此错误的最简单方法之一是添加另一列,例如GroupId 通过更改或删除表格。

注意:如果 GGroup 表中有很多行,则使用 ALTER TABLE(已在前面的答案中显示)语句而不是使用 DROP TABLE 语句。

第一步:

DROP TABLE GGroup;

第 2 步:

CREATE TABLE GGroup(
    GroupId NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
    ClassRoom varchar(7),
    GroupNum number(5),
    C_Code varchar(6),
    C_Name varchar(35), Field
    Teacher varchar(30)
);

完成这两个步骤后,您就可以插入重复值而不会出现任何ORA-00001: unique constraint 错误。

【讨论】:

    【解决方案2】:

    GGroup 将列ClassRoom 定义为主键。这明确禁止此列中的重复项。您的代码失败,因为您试图插入一条带有 ClassRoom 'A/3/54' 的记录,而另一条记录已存在于该列中具有相同值的表中。

    可能的选择:

    • 将列的主键更改为更能代表您的用例的其他内容

    • 将新插入记录中ClassRoom的值改为表中尚不存在的值

    • 忽略此错误:由于两条记录似乎完全重复,这可能是您最好的选择

    【讨论】:

      【解决方案3】:

      在第一个表中,您将 ClassRoom 字段声明为主键

      primary key (ClassRoom)
      

      这意味着 ClassRoom 字段是行的唯一标识符,这意味着它必须是唯一的。我不确定您的数据应该在那里代表什么,但如果您的意思是这些教室中有小组正在开会,您可能不想将教室用作唯一标识符,因为小组可能会重复使用相同的标识符教室。像这样为表创建一个单独的唯一标识符怎么样(从你的问题看起来你正在使用 Oracle,对吧?)

          CREATE TABLE GGroup(
          GGGroupId NUMBER GENERATED by default on null as IDENTITY,
          ClassRoom varchar(7),
          GroupNum number(5),
          C_Code varchar(6),
          C_Name varchar(35), Field
          Teacher varchar(30)
      );
      

      【讨论】:

        【解决方案4】:

        主键,必须唯一,你的教室设置为主键,不允许重复添加。

        将另一个变量(如增加的 id)设置为主键,这样您就可以更频繁地添加房间。

        问题是你为什么要添加两次相同的信息?

        如果您想在时间表中填写房间,则无需多次向 GGroup 添加房间

        【讨论】:

          【解决方案5】:

          您需要添加其他列的主键,例如递增的 ID,并创建一个序列来递增您的 ID。例如,您可以使用触发器来做到这一点:

             CREATE TABLE GGroup(
              Id NUMBER(10)    NOT NULL,
              ClassRoom varchar(7),
              GroupNum number(5),
              C_Code varchar(6),
              C_Name varchar(35), Field
              Teacher varchar(30)
          );
          
          You need to add a PRIMARY KEY constraint:
          
              ALTER TABLE GGroup
            ADD (
              CONSTRAINT GGroup_pk PRIMARY KEY (Id)
            );
          
          You need also to create a SEQUENCE that will be utilized to generate the unique, auto incremented value.
          
              CREATE SEQUENCE GGroup_sequence;
          
          Finaly you need a trigger which is a stored procedure that is executed when the insert occured:
          
              CREATE OR REPLACE TRIGGER GGroup_on_insert
            BEFORE INSERT ON GGroup
            FOR EACH ROW
          BEGIN
            SELECT GGroup_sequence.nextval
            INTO :new.Id
            FROM dual;
          END;
          

          【讨论】:

            猜你喜欢
            • 2012-05-27
            • 1970-01-01
            • 1970-01-01
            • 2015-10-20
            • 1970-01-01
            • 1970-01-01
            • 2017-11-12
            • 2014-04-08
            • 2018-01-08
            相关资源
            最近更新 更多