【问题标题】:How do I check for duplicate column values in the table before I insert them with Perl?如何在使用 Perl 插入表中的重复列值之前检查它们?
【发布时间】:2010-07-27 06:16:02
【问题描述】:

我正在读取每行包含一条记录的文件。我正在提取文件的内容并将其作为列值插入到表中。我面临的问题是,假设如果我在从文件中读取后将记录插入到表中,我想删除重复的字段。例如:

NAME age time
Tom   21  10:30
Tom   21  12:21

插入表格后,我希望它是:

NAME AGE TIME
tom   21  10:30
          12:21

它应该消除重复。如果我在创建表时添加一个唯一条件,我会遇到一个问题,即未插入不同的时间字段并导致 MySQL 出错。

那么我该怎么做呢?我想要一些建议。

for my $test11 (sort keys %seen) {
    my $test1 = $seen{$test11}{'name'};
    my $test2 = $seen{$test11}{'pid'};
    my $test3 = $seen{$test11}{'type'};
    my $test4 = $seen{$test11}{'time1'};
    print "$test11\t$test1$test2$test3$test4\n";
}

#sub query_execute()
{
    $db_handle = &getdb_handle;
    $sth       = $dbh->prepare("INSERT INTO tahle_new values('$sno','$id','$test1','$test4','$test2','$test3')");

$test1 和 $test2 包含重复项,但 $test3 不包含重复项。

【问题讨论】:

  • 请在您描述的每种情况下包括您用于写入数据库的代码。
  • for my $test11(sort keys %seen){ my $test1 = $seen{$test11}{'name'};我的 $test2 = $seen{$test11}{'pid'};我的 $test3 = $seen{$test11}{'type'};我的 $test4 = $seen{$test11}{'time1'};打印 "$test11\t$test1$test2$test3$test4\n"; } #sub query_execute() { $db_handle=&getdb_handle; $sth = $dbh->prepare("INSERT INTO tahle_new values('$sno','$id','$test1','$test4','$test2','$test3')");跨度>
  • 在上面的 $test1 和 $test2 包含重复但不包含 $test3

标签: mysql perl


【解决方案1】:

另一种方法是在 2 列上定义唯一键。您的密钥将是(姓名、年龄)并且是唯一的。 所以在插入时你会得到一个错误,或者添加到你的请求中:'... ON DUPLICATE KEY...' 并做一些事情(或什么都不做;))

正如 ysth 所说,我建议您不要插入带有空值的行作为第二行 (null,null, 12:21)

【讨论】:

    【解决方案2】:

    每一行的每一列都必须有一些值。您是否希望其他情况下重复的内容为 NULL?很难想象这样一张桌子的实际用途。

    一种方法是为您希望不重复的每一列创建另一个表,并将该列作为唯一键;在将行添加到主表之前,尝试将列值添加到每列表中;如果存在重复错误,请在尝试添加到主表之前清除该值。

    【讨论】:

    • 请注意,这不是检测重复数据的最有效方法,但操作简单,如果操作正确,应该可以防止竞争条件。
    【解决方案3】:

    ysth 是正确的,你不应该有空值。重复表明您需要两个表。一个用于日志,一个用于存储有关用户的信息。

    CREATE TABLE user (
        id     INTEGER   NOT NULL PRIMARY KEY AUTO_INCREMENT,
        name   TEXT      NOT NULL,
        age    INTEGER
    );
    
    CREATE TABLE log (
        user   INTEGER REFERENCES user,
        time   TIME
    );
    

    日志表存储用户的整数 id 和时间(以及其他任何内容)。您将插入一个条目:

    $dbh->do("INSERT INTO log VALUES (?,?)", undef, $uid, $time);
    

    在记录日志中的条目之前,您必须记住或获取用户的 ID。我建议不要使用名称作为键,因为它很容易更改。您可以在插入用户后使用$dbh->last_insert_id 来获取它。注意使用绑定参数来避免 SQL 转义和安全问题。

    【讨论】:

    • 我没有说他/她不应该有空值;我说很难想象会出现这样的情况。我实际上希望引出一些东西,说真正的问题是稍后从数据库中读取数据并输出时...... :)
    • @sreeja:进一步扩展这一点:数据库存储数据以通过查询检索。所以你可能例如想要提出一个查询,列出所有name 为Tom 的times。通过NULLifying 重复数据,您将失去这种能力(或者变得非常困难)。相反,您使用normalization 进行重复数据删除,即将我们的公共值分解到单独的表中。现在您的查询变成了连接:它们结合了两个表中的行。这就是关系数据库的用途。
    猜你喜欢
    • 2014-07-22
    • 1970-01-01
    • 2017-04-03
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多