in reply to DBD::SQLite, how to pass array in query via placeholder?

When you execute a single SQL statement (regardless of how, or with what language, you attempt to do it...), a single placeholder necessarily corresponds to a single value that will be placed into a single column of a single row.

That is “how the SQL model-of-reality works.”

In short ... you are attempting to place a list of scalar values into a “slot” (a single column of a single database row) that can only possibly contain one scalar value.   And in this regard, it truly makes not one whit of difference which flavor of SQL engine you are attempting to use!   Alas, you have “several square pegs,” and “exactly one (square...) hole.”

“Perl or not ...”   ... “SQLite or not...”   ... you can’t do it.

Replies are listed 'Best First'.
Re^2: DBD::SQLite, how to pass array in query via placeholder?
by cavac (Prior) on Apr 10, 2011 at 20:18 UTC

    That is partially correct. For example, PostgreSQL supports arrays. In that case, you use an array reference to put it into a single placeholder.

    Ok, lets make a test table:

    CREATE TABLE arraytesttable ( array_id text NOT NULL, array_values text[] NOT NULL, CONSTRAINT arraytesttable_pk PRIMARY KEY (array_id) ) WITH ( OIDS = FALSE );

    Now, we use Perl to insert some rows:

    #!/usr/bin/perl use strict; use warnings; use DBI; my $dbh = DBI->connect("dbi:Pg:dbname=MY_DB;host=localhost", 'MY_Server', 'VERYSECRET', {AutoCommit => 0}) or die("Can't connect"); my $sth = $dbh->prepare_cached("INSERT INTO arraytesttable (array_id, array_values) VALUES (?, ?)") or die($dbh->errstr); my @english = qw(Hello world); my @german = qw(Hallo Welt); $sth->execute('ger', \@german) or die($dbh->errstr); $sth->execute('eng', \@english) or die($dbh->errstr); $dbh->commit;

    That worked very beautifull, now let's read the values back. First all rows, then by finding the languages when we know the full translation (e.g. selecting by array):

    #!/usr/bin/perl use strict; use warnings; use DBI; my $dbh = DBI->connect("dbi:Pg:dbname=MY_DB;host=localhost", 'MY_Server', 'VERYSECRET', {AutoCommit => 0}) or die("Can't connect"); # SELECT ALL ROWS my $fullsth = $dbh->prepare_cached("SELECT array_id, array_values FROM arraytesttable") or die($dbh->errstr); $fullsth->execute or die($dbh->errstr); while((my $line = $fullsth->fetchrow_hashref)) { print $line->{array_id} . ': ' . join(',', @{$line->{array_values} +}) . "\n"; } $fullsth->finish; # SELECT BY ARRAY my $arrsth = $dbh->prepare_cached("SELECT array_id, array_values FROM arraytesttable WHERE array_values = ?") or die($dbh->errstr); my @german = qw(Hallo Welt); $arrsth->execute(\@german) or die($dbh->errstr); while((my $line = $arrsth->fetchrow_hashref)) { print $line->{array_id} . ': ' . join(',', @{$line->{array_values} +}) . "\n"; } $arrsth->finish; $dbh->rollback;

    As expected, this outputs:

    ger: Hallo,Welt eng: Hello,world ger: Hallo,Welt

    So, we established that the single value in single column statement doesn't hold true. PostgreSQL allows a single column holds an array model, which DBD::Pg allows us to use through array references.

    Don't use '#ff0000':
    use Acme::AutoColor; my $redcolor = RED();
    All colors subject to change without notice.
Re^2: DBD::SQLite, how to pass array in query via placeholder?
by duelafn (Parson) on Apr 10, 2011 at 12:26 UTC

    Well, except for when you can

    Good Day,
        Dean

      Well, yes, “and then there’s Postgres.”   :-)   But Postgres goes beyond the traditional SQL model – and does so very well – in many ways beyond just this.   Good point.

        FWIW, I think arrays passed as parameters to prepared queries is in the SQL:2003 standard as of S201-01.

        --Daniel