in reply to Relational table with perl DBI
Also, to avoid sql injection and use good practice, try this to insert:Loop through files-to-be-processed { insert article fetch article_ID loop through events { insert event fetch event_ID insert (article_ID, event_ID) } }
my $sth_insert_article = $dbh->prepare( qq(INSERT INTO article (url, h +tml_extr_text, concord_file, sys_time) VALUES (?, ?, ?, ?))) or die " +Unable to prepare insert statement: " . $dbh->errstr; foreach my $article_index (0 .. @output_concord_files_prepare) { my $records_inserted = $sth_insert_article->execute($url_prepare[$ +article_index], $html_pages_files_extended[$article_index], $output_c +oncord_files_prepare[$article_index], $sys_time_prepare[$article_inde +x]); if ($records_inserted != 1) { die "Error inserting records, only [$records_inserted] got ins +erted: " . $sth->insert_article->errstr; } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Relational table with perl DBI
by M15U (Acolyte) on Mar 13, 2013 at 09:01 UTC | |
You are right, all the arrays are inserted in one go. It looks like this :
As you can see it's pretty complicated to get the neccessary data for each array that I'm going to use to populate each column of each table. The last table that I fill is the index one, and I get and error like this : "DBD::mysql::db do failed: Cannot add or update a child row: a foreign key constraint fails (`e_slide`.`article_event_index`, CONSTRAINT `article_event_index_ibfk_1` FOREIGN KEY (`id_article`) REFERENCES `article` (`id_article`)) at db2.pl line 262. Cannot add or update a child row: a foreign key constraint fails (`e_slide`.`article_event_index`, CONSTRAINT `article_event_index_ibfk_1` FOREIGN KEY (`id_article`) REFERENCES `article` (`id_article`)) at db2.pl line 262." By using "LAST_ID" and the autoincrement option of MySQL will I get all the id of the two tables or only the last one of each ? Thanks again! | [reply] [d/l] |
by M15U (Acolyte) on Mar 13, 2013 at 10:13 UTC | |
I tried using 'last_insert_id' and I get the id from my tables. The code looks like this :
So now, how do I get the one-to-many relationship in the third table? Because in this case one article contains multiple events. So the it would look like : 1 - 1, 1 - 2, 2 - 3, 2 - 4, 2 - 5 and so on. I also manage to have a "good practice" code for the insertion using the code that you provided :
But still I don't know how to make the one-to-manu relationship in perl. | [reply] [d/l] [select] |
by Neighbour (Friar) on Mar 13, 2013 at 12:30 UTC | |
In order to get the relations properly, you'll learn about another nifty feature of perl: hashes. A hash is an unsorted list of key-value pairs. We're going to loop through the files, accumulating the data per file in $hr_output and accumulating all per-file data in $ar_data. The prefixes hr_ and ar_ are not required by perl, but they help me to distinguish between references to hashes (hashref, or hr) and references to arrays (arrayref, or ar). I'm not quite sure what you intended to do to those html-pages, and i'm not sure that what's happening is what you really want, so I'm just going to skip that :P Next up is inserting all accumulated data: This follows the loop I described in my previous post. There are a few tricks here, which I'll leave for you to figure out (you can still ask though :)). The most unreadable trick is @{$hr_output}{@fields} which produces an array of the value-parts of the hashref for all @fields, in order of those @fields. | [reply] [d/l] [select] |
by M15U (Acolyte) on Mar 13, 2013 at 13:55 UTC | |
by M15U (Acolyte) on Mar 13, 2013 at 14:06 UTC | |
| |
by poj (Abbot) on Mar 14, 2013 at 10:43 UTC | |
It would be much simpler to forget using numerical keys and just use the $event itself as the primary key. Use a hash to eliminate duplicates like this ; With regard to the article table, I would use the n value from the filename outputcondord.n.txt as the primary key thus avoiding sorting and synchronising problems as well as making the data in the table more human readable. Your article_event_index would then just need to contain the n value from the filename and the text from the events in that file. poj | [reply] [d/l] [select] |