【问题标题】:Java & SQL - Can't create duplicate values in my primary and foreign keyJava & SQL - 无法在我的主键和外键中创建重复值
【发布时间】:2018-10-09 23:47:50
【问题描述】:

放轻松,正在上 CS 课的中学老师。我有一个 Java 程序,它询问用户名、身高、体重,进行一些计算并将结果提供给用户。我现在需要将这些数据存储在数据库中。在开始使用主键和外键之前,我可以获取要存储的数据。

这是我无法弄清楚的错误: 错误:java.sql.SQLIntegrityConstraintViolationException:该语句已中止,因为它会导致在“USERPROFILE”上定义的“SQL180429151131780”标识的唯一或主键约束或唯一索引中出现重复键值。

这是我的桌子:

drop table stayfitapp.userdata;
drop table stayfitapp.userprofile;
drop schema stayfitapp restrict;

create schema stayfitapp;

create table stayfitapp.userprofile
(
    profileName varchar(255) not null primary key, 
    profileGender varchar(255) not null
);

create table stayfitapp.userdata
( 
    profileAge double not null,
    profileWeight double not null,
    profileHeight double not null,
    profileWaistCircumference double not null,
    profileHipCircumference double not null,
    profileName varchar(255),
    foreign key (profileName) references stayfitapp.userprofile(profileName)
);

这是写入表的“应用程序”部分...

public void save(){
    try {
        String query = "insert into stayfitapp.userprofile" + "(profileName, profileGender)" + "values" + "(?,?)"; 

        String query2 = "insert into stayfitapp.userdata" + "(profileAge, profileWeight, profileHeight, profileWaistCircumference, profileHipCircumference)" + "values" + "(?,?,?,?,?)";


    Connection myConnection = DriverManager.getConnection("jdbc:derby://localhost:1527/stayfitDB2", "username", "password");

    Statement myStatement = myConnection.createStatement();
    //Statement myStatement2 = myConnection.createStatement();

    PreparedStatement prepared = myConnection.prepareStatement(query);
    prepared.setString(1, profileName);
    prepared.setString(2, profileGender);

    PreparedStatement prepared2 = myConnection.prepareStatement(query2);
    prepared2.setDouble(1, profileAge);
    prepared2.setDouble(2, profileWeight);
    prepared2.setDouble(3, profileHeight);
    prepared2.setDouble(4, profileWaistCircumference);
    prepared2.setDouble(5, profileHipCircumference);

    int rowsAffected = prepared.executeUpdate(); 
    int rowsAffected2 = prepared2.executeUpdate();

    if(rowsAffected==0)
    {
        System.out.println("Warning: User data did not save!");
    }
    else
    {
        System.out.println("User info saved!");
    }
}
catch(SQLException e)
{
    System.out.println("Error: "+e.toString());
}

【问题讨论】:

  • userprofile,列:profileName varchar(255) not null primary key, - 主键意味着,该列中的值必须是唯一的,您不能在该列中有两条或多条具有相同值的记录。例如,您正在尝试插入 John,但另一个 John 已经在表中,并且数据库会抱怨。
  • 谢谢。这个想法是用户回来使用该程序并存储他们的新数据(相同的用户名)。
  • varchar(255) 用于性别代码?
  • 用户输入他们的性别。

标签: java sql netbeans derby


【解决方案1】:

您的 save() 方法将尝试将用户添加到 stayfitapp.userprofile 表。此表有一个名为 profileName 的字段。 profileName 是“主键”,因此不允许重复值。 您收到的错误是您无法将记录添加(插入)到表中,因为该表已经有一条同名的记录。 如果您每次使用不同的名称,您的程序是否可以正常运行?

您需要在程序中添加一些逻辑来处理表中已经存在 profileName 的情况。这可能涉及删除或更新现有记录。

【讨论】:

  • 是的,不同的配置文件名称更新表就好了。我需要为每个用户创建多条记录,因为程序稍后会平均当前用户的体重、BMI 等。
  • 如果您希望每个用户有多个记录,那么您可能不希望将 profileName 设为主键。
  • 如果该用户过去使用过该程序,我可以跳过更新主键表吗?还是那种糟糕的形式?
  • 这将有助于更多地了解课堂作业。我的猜测是,您将努力拥有一个 UserProfile(id,name) 表和一个 UserDetail 表(id​​、体重、身高等)。这两个表将通过主键和外键链接。
  • 你基本上猜对了... 1) 我们创建了一个Java 应用程序,它收集了用户名、年龄、身高、体重、臀围、腰围。 2) 我们对该数据进行了计算 3) 我们将该数据存储在 ArrayLists 中并计算了平均值、最大值和最小值 4) 我们创建了表(如上所示)并通过 SQL 将数据存储在这些表中 5) 我们现在正在集成Java 应用程序和表。这些表将存储数据而不是 ArrayList。我们将对表格中的数据执行平均值、最小值和最大值计算。
【解决方案2】:

这就是问题所在。

insert into stayfitapp.userprofile" 
+ "(profileName, profileGender)" + "values" , etc

您无需检查记录是否已存在。像这样的东西会更好。

insert into stayfitapp.userprofile
profileName, profileGender
select distinct ?, ?
from someSmallTable
where not exists (
select 1
from stayfitapp.userprofile
where profileName = ?
)

someSmallTable 位取决于您未指定的数据库引擎。

【讨论】:

  • 我不确定“数据库引擎”到底是什么意思。也许 jdbc:derby
  • 数据库引擎是softwareRelational Data Base Management System (RDBMS) 的另一个词。示例包括 Sql Server、Oracle、Sybase 和 MySQL。
【解决方案3】:

我最终编写了一个方法来检查用户名是否已经在配置文件表中。如果用户名重复,我只写入数据表。如果用户名是新用户名,我会写信给两个表。

感谢您的帮助!我确信有一种更有效的方法(形象地和字面意义上的),但我正在进行我的最后一个项目,并且几乎可以在实际的 CS 课程中幸存下来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多