0

我在 Perl 中使用DBI模块和DBD:mysql.

这个将字段url, html_extr_text, concord_file, 和sys_time插入到表中article

my @fields = (qw(url html_extr_text concord_file sys_time));
my $fieldlist = join ", ", @fields;
my $field_placeholders = join ", ", map {'?'} @fields;

my $insert_query = qq{
    INSERT INTO article ($fieldlist)
    VALUES ($field_placeholders)
};
my $sth = $dbh->prepare($insert_query);

my $id_article;
my @id_articles;
foreach my $article_index (0 .. @output_concord_files_prepare) {
    $field_placeholders = $sth->execute(
            $url_prepare[$article_index],
            $html_pages_files_extended[$article_index],
            $output_concord_files_prepare[$article_index],
            $sys_time_prepare[$article_index]);
    $id_article = $dbh->last_insert_id(undef, undef, 'article', 'id_article');
    push @id_articles, $id_article;
    if ($field_placeholders != 1) {
        die "Error inserting records, only [$field_placeholders] got inserted: " . $sth->insert->errstr;
    }
}
print "@id_articles\n";

而这个将字段event插入表中event

@fields = (qw(event));
$fieldlist = join ", ", @fields;
$field_placeholders = join ", ", map {'?'} @fields;

$insert_query = qq{
    INSERT INTO event ($fieldlist)
    VALUES ($field_placeholders)
};
$sth = $dbh->prepare($insert_query);

my $id_event;
my @id_events;
foreach my $event_index (0 .. @event_prepare){
    $field_placeholders = $sth->execute($event_prepare[$event_index]);
    $id_event = $dbh->last_insert_id(undef, undef, 'event', 'id_event');
    push @id_events, $id_event;
    if ($field_placeholders != 1){
        die "Error inserting records, only [$field_placeholders] got inserted: " . $sth->insert->errstr;
    }
}
print "@id_events\n";

我想创建第三个一对多关系表。因为,一篇文章包含多个事件,所以我有这个文件:

output_concord/concord.0.txt -> earthquake
output_concord/concord.0.txt -> avalanche
output_concord/concord.0.txt -> snowfall
output_concord/concord.1.txt -> avalanche
output_concord/concord.1.txt -> rock fall
output_concord/concord.1.txt -> mud slide
output_concord/concord.4.txt -> avalanche
output_concord/concord.4.txt -> rochfall
output_concord/concord.4.txt -> topple
...

如您所见,我使用LAST_INSERT_ID. 但是我真的不知道如何进行下一步。

使用此文件,我如何将前两个表的 ID 插入第三个表“article_event_index”。

它会是这样的:

$create_query = qq{
    create table article_event_index(
        id_article int(10) NOT NULL,
        id_event int(10) NOT NULL,
        primary key (id_article, id_event),
        foreign key (id_article) references article (id_article),
        foreign key (id_event) references event (id_event)
    )
};
$dbh->do($create_query);

它将包含遵循模式的关系

1-1, 1-2, 1-3, 2-4, 3-5 ...

我是 Perl 和数据库的新手,所以很难制定我想要做什么。我希望我足够清楚。

4

1 回答 1

0

像这样的东西应该可以满足您的需要(未经测试,但可以编译)。

它首先构建 Perl 哈希以将 concord 文件与文章 ID 和事件与事件 ID 相关联。然后读取该文件,并将一对 ID 插入到新表中,以便在现有表中找到每个关系。

请注意,哈希只是为了避免长序列

SELECT id_article FROM article WHERE concord_file = ?

SELECT id_event FROM event WHERE event = ?

陈述。

use strict;
use warnings;

use DBI;

use constant RELATIONSHIP_FILE => 'relationships.txt';

my $dbh = DBI->connect('DBI:mysql:database', 'user', 'pass')
        or die $DBI::errstr;

$dbh->do('DROP TABLE IF EXISTS article_event_index');

$dbh->do(<< 'END_SQL');
CREATE TABLE article_event_index (
    id_article INT(10) NOT NULL,
    id_event INT(10) NOT NULL,
    PRIMARY KEY (id_article, id_event),
    FOREIGN KEY (id_article) REFERENCES article (id_article),
    FOREIGN KEY (id_event) REFERENCES event (id_event)
)
END_SQL

my $articles = $dbh->selectall_hashref(
    'SELECT id_article, concord_file FROM article',
    'concord_file'
);
my $events = $dbh->selectall_hashref(
    'SELECT id_event, event FROM event',
    'event'
);

open my $fh, '<', RELATIONSHIP_FILE
        or die sprintf qq{Unable to open "%s": %s}, RELATIONSHIP_FILE, $!;

my $insert_sth = $dbh->prepare('INSERT INTO article_event_index (id_article, id_event) VALUES (?, ?)');

while (<$fh>) {
  chomp;
  my ($concord_file, $event) = split /\s*->\s*/;
  next unless defined $event;

  unless (exists $articles->{$concord_file}) {
    warn qq{No article record for concord file "$concord_file"};
    next;
  }
  my $id_article = $articles->{$concord_file}{id_article};

  unless (exists $events->{$event}) {
    warn qq{No event record for event "$event"};
    next;
  }
  my $id_event = $events->{$event}{id_event};

  $insert_sth->execute($id_article, $id_event);
}
于 2013-03-15T13:15:05.030 回答