in reply to Re^6: Query database in Prolog
in thread Query database in Prolog

Ah.

Yes, that works and is portable. However whenever I've dealt with code that tried to remember column names by position, it has been a maintainance issue. Every single time. (It wasn't always obvious to other people around me that it was a maintainance issue since the work of maintaining it and the routine failures in doing so were just accepted as normal.)

Therefore even though you can do things that way, I strongly recomment that you not do so. Albeit for different reasons than what I thought you were talking about.

Replies are listed 'Best First'.
Re^8: Query database in Prolog
by zby (Vicar) on Dec 30, 2005 at 23:03 UTC
    I welcome ideas how to make the code independent on column position - I clearly expressed in the main article that I am waiting for other ideas how to convert the database relations to logic. The example is much complicated by the dependence on column order - but i don't know how to get rid of it in a simple way.
      I tend to use raw DBI and fetchrow_hashref. Now I have columns by name. That won't be portable across databases (different databases handle capitalization of field names differently) but I've generally only found myself working with one database at a time so it isn't an issue for me.

      Note that if you're processing large amounts of data, making those anonymous hashes is slower. I've never found that to be a bottleneck for me, but I've always had to deal with remote databases and have never worked with more than a few billion rows. (And on large datasets, my performance expectations were already set by the amount of data.) YMMV.

        I tend to use raw DBI and fetchrow_hashref. Now I have columns by name. That won't be portable across databases (different databases handle capitalization of field names differently)
        If you set $dbh->{fetchHashKeyName} = NAME_uc or NAME_lc at the top of your scripts, then the hash fetches will be portable across databases since they'll all be in either uc or lc.
        It is not about DBI - but about converting relations to logic predicates. I know how to get the data from the database (and if you looked at my first post in this thread you would discover that I use an ORM for that - that is order independent), it is the conversion that is the difficult and in my solution order dependent step. I don't want to be rude but I think you did not read the whole thread here and now you attack me with some straw man tactics. It is insulting when you suppose that I don't know basic facts.

        > Note that if you're processing large amounts of data, making those anonymous hashes is slower.

        Yep. I have had that be an occasional performance bottleneck. Solved it thusly (IIRC):

        $sth = $dbh->prepare("Select * FROM datatable"); $sth->execute; my %map; { my @col = @{ $sth->{NAME_lc} }; for (0..$#col) { $map{$col[$_]} = $_ } } while( my $row = $sth->fetchrow_arrayref ) { # I want the cols named ID, name, city, in that order printf "%d: %s from %s\n" ,$row->{$map{id}} ,$row->{$map{name}} ,$row->{$map{city}}; }

        In this way, you use the fastest fetchrow (fetchrow_arrayref) on each iteration, which seems to be much faster.

        Granted, specifying the field order in the SELECT and then using constants to reference field order (or just passing the list to printf) is faster still. But, if (like me) someone else updates the SQL that your code is calling (like when you just call stored procedures), the code above just keeps working, whereas using numerical constants could break.

        I second the cry of YMMV, but this has always worked well for me.

        <-radiant.matrix->
        A collection of thoughts and links from the minds of geeks
        The Code that can be seen is not the true Code
        "In any sufficiently large group of people, most are idiots" - Kaa's Law