2013-03-13 61 views
2

我想打一個關係表用Perl這兩個表之間並在其中插入數據:用Perl DBI模塊關係表

$create_query = qq{ 
    create table article(
     id_article int(10) auto_increment NOT NULL, 
     url MEDIUMTEXT COLLATE utf8_general_ci, 
     html_extr_text TEXT COLLATE utf8_general_ci, 
     concord_file TEXT COLLATE utf8_general_ci, 
     sys_time VARCHAR(50), 
     primary key (id_article) 
     ) 
}; 
$dbh->do($create_query); 

$create_query = qq{ 
    create table event(
     id_event int(10) auto_increment NOT NULL, 
     event MEDIUMTEXT COLLATE utf8_general_ci, 
     primary key (id_event) 
     ) 
}; 
$dbh->do($create_query); 

現在的關係表如下:

$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); 

有人知道爲了填充'article_event_index'表應該是什麼perl語句? 因爲我使用數組爲它看起來像這樣每個表中的其他表:

my $i_event; 
my $id_event = 0; 
my @event_index; 
for ($i_event = 0; $i_event < @event_prepare; $i_event++){ 
    $dbh->do(" 
     INSERT INTO `event`(`id_event`, `event`) 
     VALUES ('$id_event', '$event_prepare[$i_event]') 
     ") || die $dbh->errstr; 
    push @event_index, $i_event; 
} 
$id_event++; 

在這種情況下,「id_event」是由$ id_event的增量產生。如果我想在索引表中重用此ID,這是一個很好的做法嗎?

回答

0

由於id_event字段被定義爲auto_increment,您可以讓數據庫爲您生成id值,這是我通常如何避免競爭條件的機會。 (即,如果兩個單獨的用戶/進程試圖同時插入行並且都生成相同的id值,那麼提交第二個將失敗。)

插入一行後,可以使用DBI的last_insert_id方法獲得價值新行自動生成的ID,如果你需要它用作另一個表的外鍵:

my $id = $dbh->last_insert_id(undef, undef, 'event', 'id_event'); 
+0

是的,whit'last_insert_id'方法我得到了id的列表。但是,如何在「文章」和「事件」之間建立一對多的關係?因爲一篇文章可能有多個事件。所以它會是:1 - 1,1 - 2,2 - 3,2 - 4,2 - 5 ...等等。第一個數字是文章,第二個是事件。再次感謝 – user2007958 2013-03-13 09:30:57

+3

一對多關係在這裏由你如何填充表格來定義。如果在你的映射表上,你插入相同的偶數id,幾個文章ID(這是你的映射表定義允許的),你有一個一對多的關係。我覺得你正在尋找一種'神奇'的方式來創建一對多的關係,而無需處理idx和交叉表。你應該看看'DBIx :: Class',它可以讓你這樣做(但是比API更復雜的API)。 – Mattan 2013-03-13 09:37:30

1

除了戴夫Sherohman的迴應,這裏是你的代碼的一些意見:

您應該考慮使用準備好的聲明進行插入:

my $sth = $dbh->prepare("INSERT INTO `event`(`id_event`, `event`) VALUES (?,?)"); 

然後在你的循環,你可以只是這樣做的每一行,你需要插入:

$sth->execute($id_event, $event_prepare[$i_event]); 

這是簡單(它爲您處理引用),安全(防止SQL注入),和更快。

此外,你不需要使用C風格for循環只是爲了通過一個數組。您可以使用這些形式之一:

for my $i_event (0..$#event_prepare){ 
    #if you need the array index. 
} 

for my $event (@event_prepare) { 
    #if you don't need the array index. 
} 

而且,這僅僅是一個喜好,但我不喜歡{ ... }作爲字符串分隔符,因爲它們看起來太像代碼塊。