如果我发现重复或以其他方式插入数据,如何更新记录?

时间:2010-07-27 12:12:32

标签: sql mysql perl dbi

在下面的代码中,有一个哈希,其中包含namepidtypetime1等字段的记录。 pidname是包含重复项的重复字段。

我重复发现更新需要修改的字段 否则插入,此处namepid有重复项(重复字段)。

其余的都是独一无二的。在创建表Serial no时,我也有一个唯一的字段。我该怎么办?我在这段代码中只做了一次插入。我不知道如何使用Perl将检索到的记录存储到数组中。请指导我。

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";

    $db_handle = &getdb_handle;
    $sth       = $dbh->prepare("Select username,pid,sno from svn_log1");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
    my $ref = $sth->fetchall_arrayref();
    print "hai";
    print "****$ref";
    $sth = $dbh->prepare("INSERT INTO svn_log1 values('$sno','$test11','$test1','$test4','$test2','$test3')");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
}

3 个答案:

答案 0 :(得分:2)

你想说的是你不想尝试插入一些数据,如果你已经在数据库中有这个名字/ pid组合,但我不能告诉我,所以我无法帮助你。

但是,这里有一些可以清理代码的东西。首先,选择合理的变量名称。其次,始终始终在SQL语句中始终使用占位符来保护它们:

for my $test11 ( sort keys %seen ) {
    my $name  = $seen{$test11}{'name'};
    my $pid   = $seen{$test11}{'pid'};
    my $type  = $seen{$test11}{'type'};
    my $time1 = $seen{$test11}{'time1'};

    my $dbh = getdb_handle();
    my $sth = $dbh->prepare("Select username,pid,sno from svn_log1");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
    my $ref = $sth->fetchall_arrayref();
    # XXX why are we fetching this data and throwing it away?

    $sth = $dbh->prepare("INSERT INTO svn_log1 values(?,?,?,?,?,?)");
    $sth->execute( $sno, $test11, $name, $time1, $pid, $type )
      or die "SQL Error: $DBI::errstr\n";
}

假设您不想在数据库中插入内容,如果有“$ name”和“$ pid”(并进行一些清理以避免反复编写相同的SQL):

my $dbh = getdb_handle();
my $seen_sth   = $dbh->prepare( "Select 1 from svn_log1 where username = ? and pid = ?");

# This really needs to be "INSERT INTO svnlog1 (@columns) VALUES (@placeholders)
my $insert_sth = $dbh->prepare("INSERT INTO svn_log1 values(?,?,?,?,?,?)");
for my $test11 ( sort keys %seen ) {
    my $name  = $seen{$test11}{'name'};
    my $pid   = $seen{$test11}{'pid'};
    my $type  = $seen{$test11}{'type'};
    my $time1 = $seen{$test11}{'time1'};

    $seen_sth->execute($name, $pid) or die "SQL Error: $DBI::errstr\n";
    my @seen = $seen_sth->fetchrow_array;
    next if $seen[0];

    $insert_sth->execute( $sno, $test11, $name, $time1, $pid, $type )
      or die "SQL Error: $DBI::errstr\n";
}

这不是我写这个的方式,但是相当清楚。我怀疑它并不是你想要的,但我希望它让你更接近解决方案。

答案 1 :(得分:2)

您想要插入一些数据,但如果存在,则更新现有行?

如何测试数据库中是否已存在数据?你使用的是用户名和pid吗?

如果是这样,您可能希望更改数据库的结构: ALTER TABLE svn_log1 ADD UNIQUE (username, pid);

这会在usernamepid上创建一个复合且唯一的索引。这意味着每个用户名/ pid组合必须是唯一的。

这允许您执行以下操作:

INSERT INTO svn_log1 (username, pid, ...) VALUES (?, ?, ...) ON DUPLICATE KEY UPDATE time = NOW();

答案 2 :(得分:1)

这是什么数据库?

我的感觉是您需要UPDATEINSERT查询,通常称为UPSERT查询。

如果这是PostgreSQL,您可以创建一个upsert函数来处理您需要的内容。请参阅comments以获得一个体面的例子。否则,搜索Stack Overflow以获取“upsert”,您应该找到所需内容。