我使用DBI
模块和DBD:mysql
在Perl中有这两个插入查询。
此字段将字段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'中插入前两个表的ID。
这将是这样的:
$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和数据库的新手,因此很难制定我想做的事情。我希望我很清楚。
答案 0 :(得分:0)
这样的事情应该做你需要的(未经测试,但它确实编译)。
首先构建Perl哈希,将协调文件与文章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);
}