Slashdot Mirror


Transferring Data 'Tween Databases

Sysbotz writes "A common request our company gets is how to get data from Access, Paradox, or some other database format and transfer it to a MySQL database. Well we have written a article on how to do this. W accomplish this task by writing a PHP script to read a database file through ODBC and then to construct a SQL file of the data that can then be read into MySQL. I think some slashdotters would like this."

51 comments

  1. Standarization. by noselasd · · Score: 2, Insightful

    Wouldn't it be nice if the protocol to RDBMS'es were standarized. Every DB server would use a standard protocol to talk to clients, sort of LDAP, which is a protocol and vendors implement that protocol..

    1. Re:Standarization. by samael · · Score: 4, Funny

      You mean some kind of Open DataBase Connectivity?

      Or does ODBC not ring any bells?

    2. Re:Standarization. by noselasd · · Score: 2, Informative

      Er.. didn't I say protocol ? Yes I did. ODBC is an API. Big diffrence. ODBC loads (transparently) drivers that each know how to actually do the conversation with the database server. This is not the same as a protocol.

    3. Re:Standarization. by samael · · Score: 1

      Aah, gotcha.

      Yeah, that would be good. You could standardise around SQL for commands and then an XML syntax for data.

    4. Re:Standarization. by Directrix1 · · Score: 1

      Or you can standardize around SOAP, and have it send the data back in a negotiated compressed format. All I want though is a keyed, querieable, relational file system, with a pluggable architecture to provide whatever remoting interface I need.

      --
      Occam's razor is the blind faith in the natural selection of least resistance and in universal oversimplification. -- EF
    5. Re:Standarization. by Anonymous Coward · · Score: 1, Informative

      That's what the Open Database Connectivity Router does ... http://odbcRouter.com/

    6. Re:Standarization. by Anonymous Coward · · Score: 0
      Er.. didn't I say protocol ? Yes I did. ODBC is an API. Big diffrence. ODBC loads (transparently) drivers that each know how to actually do the conversation with the database server. This is not the same as a protocol.

      With ODBC Router, you can (transparently) put all of those drivers on a central box and then any [Mac/Linux/Win32] machine in your network can access any SQL database at will.

    7. Re:Standarization. by Anonymous Coward · · Score: 0

      XML, when sql results are the one textbook situation in which CSV is entirely, completely, utterly appropriate? you're sick.

  2. Is this really worthy of a /. article? by herrlich_98 · · Score: 4, Insightful

    Summary: to get data from a db to MySQL use PHP to read the db and print out a MySQL script that loads all the data.

    It is nice to highlight that you can read lots of different databases using odbc in PHP, but still.

    This basic concept is obvious to anyone with familiarity with MySQL. I mean, come on, "pick a language that can read the database in question and use it to dump the data into a format that can be read my MySQL".

    This program could have been written in Visual Basic or C# or anything that can read the database you want to convert.

    A more interesting PHP program that could have taken *any* two arbitrary odbc databases (MySQL can be accessed through odbc) and dumped table definitions and data from one db to the other.

    1. Re:Is this really worthy of a /. article? by cymen · · Score: 2, Interesting

      No, it is not worthy of a /. article in my opinion (but my opinion doesn't matter as I'm not in @slashdot.org.corp), this is just a lame script.

      No new techniques and code that almost any person with a day of PHP experience would have already written. The only reason I checked it out was that I wanted to see if they figured out how to grab column names or tables names via ODBC. I'd love to be able to grab meta-data about the databases themselves. If this isn't part of the SQL ANSI standard...

    2. Re:Is this really worthy of a /. article? by PsiComa · · Score: 1

      This *really* sucks.
      It's a lame braindead extremely ordinary task every near-decent php/db programmer had to do at some point, when he finally realized mysql sucks and he's gotta move everything into postgresql :p
      Clearly, lame publicity for the company in cause, which now turned into bad publicity.

    3. Re:Is this really worthy of a /. article? by Random+Hamster · · Score: 1

      I know I am taking the dead horse round the block for a quick flog, but to do this in general is a non trivial task as the data types in different databases will have different names, and the way what Access calls 'autonumber' fields is different from, say, the way it is done in Oracle.
      In fact, since the autonumbers are generated - duh - automatically, copying between two access databases can be distinctly non-trival (indeed, if you have relations defined AND autonumber fields determining a way to put the data into the database is probably a quite complex problem in graph theory).

      Then of course there are name constraints, Access allows spaces, Oracle doesn't, Oracle has numerous reserved words and has a 30 character limit.

      This is as nothing to the delights of trying to use ODBC Linked Tables for an Oracle database in Access. Hint - don't do it.

    4. Re:Is this really worthy of a /. article? by zatz · · Score: 1

      The ANSI SQL-92 standard does indeed specify a uniform mechanism for accessing metadata.
      Try select * from information_schema.columns for a taste.

      --

      Java: the COBOL of the new millenium.
  3. Why not use PHP as glue? by miked50 · · Score: 1

    Why wouldn't you just add a parameter to your script that could do the inserts directly to the MySQL database right from PHP, instead of going to a file first? A simple type switch would be good. Then you could say if($type == "file") write data to file, else if($type == "db") write directly to the MySQL DB... It's a simple solution, and it could be easily configured for clients as a turnkey solution to getting their data.

    1. Re:Why not use PHP as glue? by j_kenpo · · Score: 1

      You know, I was thinking the same thing as I was reading this. Or even out put to a Comma-delimited filed and using the MySQL load file. I didn't really see the point. Its a good tutorial for begginers though, even if it doesnt teach the most efficient solution to the problem.

  4. Been there.. by JohnFluxx · · Score: 1, Informative

    I found a script on freshmeat that could read an access file and produce the appropriate sql commands.

    This was a few years back, and it had some problems with special characters - like spaces iirc - since access is more leniant.

    I kept meaning to write a script to turn the forms it created into glade xml.

  5. Perl DBI? by merlyn · · Score: 4, Informative

    The Perl DBI can talk to all of those listed databases and more. It'd be trivial to fetch everything from one database and store it in another, without worrying about local quoting conventions, as long as you use the DBI placeholders.

  6. Why not use a real target database? by lowmagnet · · Score: 1

    I mean, seriously. MySQL just isn't that good with stored procedures. What's the point of going from more capable to less capable database?

    --
    Heute die Welt, morgen das Sonnensystem!
    1. Re:Why not use a real target database? by Radical+Rad · · Score: 1

      You consider Access and Paradox as more advanced?

    2. Re:Why not use a real target database? by KoolyM · · Score: 1

      Dunno about Paradox, but Access at least has views (something any decent relational database should have, IMHO - after all, that's kind of the point, no?). So I'd say "yes, kinda ..."

      And yes, my day job involves MySQL and I quite like it, but I'm not deluded enough to think it's the be all and end all of databases.

  7. Dang by droyad · · Score: 0, Offtopic

    I just have to say Wooooopppppiiiieeeeee

  8. How we used the DBI to do this by fizbin · · Score: 3, Informative

    In fact just recently I wrote a one-off script here that did essentially what this PHP script does - it takes data out of a local sybase db and reformats it as a bunch of SQL statements. (We don't have direct access to the database into which this needs to be loaded, so there needs to be an intermediate form anyway)

    I suppose this _might_ be worth a post on perlmonks, as an example of using the DBI, (and of working around the fact that DBD::Sybase doesn't really implement column_info) but not much more than that.

    This code generates an SQL load file for each table that has a column named "DataSrcId" where that column has the value "35". It also substitutes the value 'guy' for any column named 'AudUsrId' and does not include any column named 'AudTmst' in the load output. As I said, it's a one-off hack.

    #!perl
    use DBI;
    use DBD::Sybase;

    my($dbh);

    sub dumpstatement {
    my ($tablename, $statement) = @_;
    my $sth;
    $sth = $dbh->prepare($statement);
    $sth->execute();
    while ( my(@row) = $sth->fetchrow_array ) {
    my @names = @{$sth->{NAME}};
    @row = map { $names[$_] eq 'AudUsrId'?'guy':$row[$_] } (0..$#row);
    @row = map { $names[$_] eq 'AudTmst'?qw():$row[$_] } (0..$#row);
    @names = grep(! /^AudTmst$/, @names);
    print "INSERT $tablename (", join(',',@names), ")\n";
    print "VALUES (", join(",",
    map {$dbh->quote($row[$_],$sth->{TYPE}->[$_])}
    (0..$#row)
    ), ")\n";
    }
    print "\n";
    }

    my($user, $password) = qw[sa confusion];
    $dbh = DBI->connect("dbi:Sybase:server=njdscope;database= TEST_ATRB", $user, $password);

    my($sth) = $dbh->table_info('%','%','%', '%');

    my(@tables);
    my($hashr);
    while ($hashr = $sth->fetchrow_hashref("NAME_uc")) {
    my($ctable) = $hashr->{TABLE_NAME};
    push @tables, $ctable;
    }
    $sth = undef;

    foreach my $table (@tables) {
    $dbh->{PrintError} = 0;
    my $teststatement = $dbh->prepare("SELECT max(DataSrcId) FROM $table WHERE DataSrcId = 35");
    $teststatement->execute;
    if ($teststatement->err) {next;}

    $dbh->{PrintError} = 1;
    print "-- for $table \n";
    dumpstatement($table, "SELECT * FROM $table WHERE DataSrcId = 35");
    }

    By the way - slashdot inserts an extra ";" in this code, even though it is NOT there in what I copy/paste in. Go figure.

  9. Bigger project by mnmn · · Score: 1

    It would be quite nice to have a C-based converter, that could be used to replace databases within an hour... for apps that support both the BEFORE and AFTER database types.. without using ODBC.

    What I have in mind is mysql, pgsql, oracle 9i, msaccess, db2, firebird, minisql.

    Wonder if its possible.

    --
    "Give orange me give eat orange me eat orange give me eat orange give me you." -Nim Chimpsky
  10. As simple minded as the mods letting it pass by Sembiance · · Score: 5, Informative

    This is totally worthless.
    Do mods just let anything with the words 'PHP' and/or 'MySQL' make it on the website?

    The article is less than 2 screen pages long, it's not much more than a code dump, and it's totally hardcoded for a specific and individual database table.

    It also only covers Windows installations of PHP and and person who knows that they need to move from one database to another, and what PHP is, is smart enough to do what this author wrote.

    I don't diss the author on this, it looks as if he is just new to computers and doesn't know any better.
    But geez, if this is the crap that we allow on slashdot now, I'm just gonna start submitting articles on 'How cool Google is'

    1. Re:As simple minded as the mods letting it pass by Anonymous Coward · · Score: 0
      $addr1 = odbc_result($stmt, 6);
      $addr2 = odbc_result($stmt, 7);
      $address="$addr1\n$addr2";
      $address=addslashes($address);
      $address = addslashes(odbc_result($stmt, 6)."\n".odbc_result($stmt, 7));
      I assume declaring variables for no reason was in chapter 1 of 'beginning PHP'. I don't see the value of this article either, whats next in the series hello_world.php??
  11. msaccess by oliverthered · · Score: 2, Interesting

    You could give me a hand with this if you want. (a C++ library for reading access databases).

    The projects been dormant for a while, (work makes my head hurt too much for real development)

    --
    thank God the internet isn't a human right.
  12. No. by Matz+L.E. · · Score: 1
    The article covers a dumb trainee-job and doesn't even describe an elegant way to do this (e.g. via meta data).

    If this is all it takes to get a dev-article to /., I'll just dump my everyday work here and become the uber-geek ;-).

  13. Java by FortKnox · · Score: 2, Interesting

    Java would have been a much better language if you wanted the project to be reusable. JDBC means that we have the same code for every type of DB's. So you could have a 'read all from DB' set of code and a 'write all to DB' set of code, then simply plug the two DB's into an XML config file, and voila, you have exactly what is needed for any type of DB with JDBC drivers (which is everything except the extremely rare and extremely obscure).

    That is something worth writing an article about. Not just one very specific case.

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
    1. Re:Java by yintercept · · Score: 2, Funny

      Java would have been a much better language if you wanted the project to be reusable.

      Gosh, with the Java/XML combo...I am surprised that there still is such a thang as a database. Dang, if you designed the blasted thang in UML with Java/XML there wouldn't even be a question of reusability...cause you would be in computer nirvana.

      PS: I don't code...just read the trade journals and play foosball.

    2. Re:Java by j3110 · · Score: 1

      Exactly, and I think you should have pointed out for those unfortunate programmers that have never used JDBC that you can query the schema in an independant way, then create the schema in another database in that same way such that from JDBC, the two datasources would be indestinguishable except for constraints, views, and stored procedures.

      --
      Karma Clown
    3. Re:Java by Anonymous Coward · · Score: 0

      Java would have been a much better language if you wanted the project to be reusable.

      More reuseable? Bull! Prove it!

  14. Testing and Whatnot by Inexile2002 · · Score: 3, Informative

    Despite some of the criticisms above it's nice to see stuff like this. As part of my job I have to occasionally go into companies and review database conversions after the fact to confirm that they did everything correctly.

    As obvious as the technique used above is to some /.ers, DB conversions are not always obvious to the people who actually do them IRL. I've seen some of the most horrific improvisations involving a third database as a data warehouse or worse, the process done manually with SQL dumping data into Notepad which is then copy/pasted into new SQL.

    The one thing though - testing. Post conversion testing is essential unless you were doing all this for shits and giggles. If you can't show someone through rigorous testing that your conversion worked, no responsible person out there should rely on the new DB. (Assuming they were relying on the old one.)

    1. Re:Testing and Whatnot by Anonymous Coward · · Score: 0

      We're talking MS Access -> MySQL. I don't think anyone really cares how accurate the data is after conversion.

  15. Moo by Chacham · · Score: 2, Informative

    If this is something you do alot, get SQL Server DTS. It does this beautifully, as well as many other tasks.

    1. Re:Moo by merlin_jim · · Score: 1

      If this is something you do alot, get SQL Server DTS. It does this beautifully, as well as many other tasks.

      Not to mention that its pretty much free. The SQL Server Tools install is free if you have SQL Server installed anywhere. There's no licensing anyways, and the DTS stuff is redistributable whether you have one or not...

      --
      I am disrespectful to dirt! Can you see that I am serious?!
  16. java tool does this between most JDBC databases by Anonymous Coward · · Score: 0

    check out hypersonic. a small footprint java RDBMS with a jdbc driver which stores its data on the filesystem. most people never get past checking the database out BUT....

    it comes with an incredibly useful TRANSFER TOOL which can transfer tables and/or data from one JDBC source to another. i have only tried it with a limited amount of databases, including mySQL, Oracle, and AdabasD. the newer version has some problems with Oracle, but with a little "hand tuning" in the source code you should be able to get it to work.

    my "favorite" uses for it are:
    - making a quick copy of an oracle schema to my laptop, so i can continue developing my database driven webapp at home (use an object persistence layer like castor to make sure that your code is not database specific)
    - prepared databases with test cases. just check out of CVS and you are ready to go...

  17. Octopus by grugruto · · Score: 4, Informative
    The Enhydra Octopus project seems to be the right tool to do this and you can specify data transformations in an XML file.

    You should check it out, it's open source.

    1. Re:Octopus by Tablizer · · Score: 1

      I would note that XML is not a very compact format because it repeats the tags or field names over and over again for each record. More compact formats state the column list (and order) once as a table header, and the data ordering indicates which column it belongs with.

      On another note, one thing about writing xfer routines is that SQL lacks a hybrid statement that says something like, "if this record is already there, then updated it, else insert a new one". Instead you have to check for each record. It needs an "UPSERT" operation.

      While on the topic of SQL annoyances, why is the syntax for INSERT significantly different than UPDATE?

  18. More Evidence that MySQL is a toy by bwt · · Score: 4, Informative
    Here's another example from real world use that shows that MySQL is a toy compared to a real database like Oracle. You shouldn't have to write that much code to freaking load data. For industrial strength uses the method given will be horribly slow because it doesn't use bind variables. This results in each INSERT statement being different and having to be parsed separately by the RDBMS. SLOW!

    Frankly, even the overhead of having to construct the INSERT sql string is waste. You also don't want to maintain the indexes in the target table for each row update. MySQL doesn't have transactions, so you don't have to worry about commit-frequency, but if your load stops in the middle somewhere, I'm not sure what you do.

    Oracle provides a loader utility called sql*loader that eliminates the overhead of the per-row maintenance. It has a mode called "Direct Load" which can bypass trigger processing and directly write binary datablock output. This is the fastest way to load data. Of course bypassing triggers is of no interest to MySQL users because MySQL doesn't have triggers, but if it did you'd have another thing to worry about with loading data into MySQL.

    As an alternate to sql*loader, you could use external tables or Oracle Generic Connectivity to create an oracle table whose data was supplied by a flat file or ODBC connection. Then you would type
    INSERT INTO target_table
    VALUES ( [[field_list]] )
    (SELECT [[field_list]] from external_table)
    or (faster)
    CREATE TABLE target_table AS (SELECT * from external_table)
    Both of which would blow away the proposed method speed-wise.
    1. Re:More Evidence that MySQL is a toy by Anonymous Coward · · Score: 0

      What a crappy article/question...

      It seemed to more than anything try and generate interest in their company..

      If someone cannot figure out how to get data into mysql from almost any datasource, they should not be working with computers.

      The quality of /. articles has been going down lately, this should have been thrown on the trash pile.

    2. Re:More Evidence that MySQL is a toy by babbage · · Score: 1

      Not that you're on the wrong track -- Oracle is more powerful than MySQL, there's no questioning that assertion -- but the functionality you describe exists in MySQL as well. For an equivalent to Oracle's sql*loader, MySQL offers the command line tool mysqlimport, or the SQL command LOAD DATA INFILE. I believe there are also equivalents to the CREATE/INSERT ... SELECT. For all the advantages that Oracle has over MySQL, these aren't among them :-)

    3. Re:More Evidence that MySQL is a toy by bwt · · Score: 1


      Well, mysqlimport or LOAD DATA INFILE seems like it would be a MUCH better MySQL solution than building an INSERT for each row. Why the author of the original article did not use this method is rather perplexing.

      However, I don't see how the CREATE TABLE AS SELECT or INSERT AS SELECT could possibly work here unless MySQL has a way to link a table from an external source.

  19. MSSQL already does this by Anonymous Coward · · Score: 0

    MSSQL has built in easy to use wizards to do this easily with Enterprise Manager.

    This is news? In this century?

  20. access2sql by Anonymous Coward · · Score: 1, Informative
  21. SQLyog by Anonymous Coward · · Score: 0

    ODBC Import...

  22. Delphi! by laa · · Score: 2, Insightful

    I wrote a small app for that once. It has basicly two comboboxes containing all ODBC DSN:s found on the system. Then you choose from which DSN to which DSN and click copy - regardless of database vendors (as long as they have ODBC drivers, that is). Just to show off, it gives the user a list of all available tables, so that he/she may copy only a subset.

    Coding it was a piece of cake - the Borland Database Enginge has it upsides every once in a while (but I never thought I'd admit that)!

    --
    Why does the kernel go through stable and then unstable forks? Can't it always be a stable build, like with Windows?
  23. No.. by lowmagnet · · Score: 1

    but I consider PostgreSQL and Oracle to be real databases (and obviously more advanced)

    --
    Heute die Welt, morgen das Sonnensystem!
  24. You know you've seen too much porn when... by Anonymous Coward · · Score: 0

    ...you read the article's title as "Transferring Data Teen Databases"

  25. Re:Is this really worthy of a /. article? (OT) by cymen · · Score: 1

    Thanks, I'll try that. I really should brush up on my ANSI SQL. Now lets just hope that MS Access ODBC, not my choice, supports some SQL-92!

  26. Depends on the type of conversion by Anonymous Coward · · Score: 0

    Having been doing this for some time with my clients, there is an excellent tool : OpenAdaptor ( http://www.openadaptor.org) that I have been using. Of course, you could try the Oracle's hetrogeneous services. Again the coversion depends on many times what is exactly required 1) One time conversion 2) Conversion in batch : hourly, daily, monthly etc 3) Real time conversion : convert only when required, ex when somebody requests past 3 months data 4)Accessability all the time : jdbc, odbc, etc

  27. quick transfers by sdibb · · Score: 1
    I'm surprised nobody's mentioned MySQL-Front.

    I've used it before on importing an MS Access db to MySQL with 3000 rows and 50+ columns. Worked like a charm.

    It can also import any ODBC connection. I've never had any problems with it.