idunno has asked for the wisdom of the Perl Monks concerning the following question:

I want to do something real simple: insert a sequence value into a database using DBI. At the sql prompt I can do this using "insert into blah (blah_key, blah_name) values (blah_seq.nextval, 'jim'), but in my perl script, I have the following execute command: "execute(blah_seq.nextval, $blah_name)", and that gives me an error. I've tried putting single quotes around blah_seq.nextval, but that doesn't work either.

How do you do that?

Thanks

Replies are listed 'Best First'.
Re: using sequences with dbi
by tommyw (Hermit) on Oct 03, 2001 at 18:41 UTC

    Perl doesn't have a clue what blah_seq.nextval means. Actually, neither does your sql environment, but it doesn't care: it just hands it over to the database server to deal with.

    $sth=$dbh->prepare(" insert into blah (blah_key, blah_name) values(blah_seq.nextval, ?)"); $sth->execute($blah_name);
    ought to do what you want.

Re: using sequences with dbi
by gbarr (Monk) on Oct 03, 2001 at 18:44 UTC
    It sounds like you are trying to add SQL to a statement using placeholders.

    Placeholder can only be used to insert values, you cannot use a placeholder to insert an SQL expression.

    You will have to put blah_seq.nextval directly into the SQL and only pass $blah_name to execute.

    If you want to be able to specify either to get the next value or a value of your own, without having to SQL statements then you could use

    ... VALUES( NVL(?,blah_seq.nextval),?)

    Then passing undef as the first argument will use the next value from the sequence.

Simple demo...
by Rhose (Priest) on Oct 03, 2001 at 18:50 UTC
    I assume since you are using SEQUENCE.NEXTVAL, that this is an Oracle environment, so maybe this will help a bit. (Please note, this is not "good" code, but it was quick. *Smiles*)

    use strict; use dbi; use dbd::oracle; #-- Define constants use constant TRUE => 1; use constant FALSE => 0; use constant ORA_USER => 'myschema'; use constant ORA_PASS => 'sesame'; use constant ORA_TNS => 'tst00'; use constant ERR_OK => 0; #-- Define variables my $mDBHandle; my $mSQLInsertHandle; my $mSQLSelectHandle; my $mSQLInsert = <<'EOSQL'; INSERT INTO test (val, name) VALUES (test_seq.nextval,?) EOSQL my $mSQLSelect = <<'EOSQL'; SELECT val, name FROM test EOSQL my @mTuple; #-- Connect to the database $mDBHandle = DBI->connect ( 'dbi:Oracle:' . ORA_TNS, ORA_USER, ORA_PASS, { AutoCommit => FALSE, PrintError => FALSE, RaiseError => FALSE, } ) || die $DBI::errstr.' - '.$DBI::err; #-- Prepare the SQL statements $mSQLInsertHandle = $mDBHandle->prepare($mSQLInsert) || die $DBI::errs +tr.' - '.$DBI::err; $mSQLSelectHandle = $mDBHandle->prepare($mSQLSelect) || die $DBI::errs +tr.' - '.$DBI::err; #-- Display records $mSQLSelectHandle->execute() || die $DBI::errstr.' - '.$DBI::err; print "Val\tName\n"; print "---\t----\n"; while (@mTuple = $mSQLSelectHandle->fetchrow_array) { print $mTuple[0],"\t",$mTuple[1],"\n"; } print "\n\n"; #-- Execute the SQL insert statements $mSQLInsertHandle->execute('test1') || die $DBI::errstr.' - '.$DBI::er +r; $mSQLInsertHandle->execute('test2') || die $DBI::errstr.' - '.$DBI::er +r; #-- Commit the inserts $mDBHandle->commit(); #-- Display records $mSQLSelectHandle->execute() || die $DBI::errstr.' - '.$DBI::err; print "Val\tName\n"; print "---\t----\n"; while (@mTuple = $mSQLSelectHandle->fetchrow_array) { print $mTuple[0],"\t",$mTuple[1],"\n"; } print "\n\n"; #-- Disconnect from the database $mDBHandle->disconnect(); #-- Exit exit(ERR_OK); #-- End of Script
Re: using sequences with dbi
by MZSanford (Curate) on Oct 03, 2001 at 18:23 UTC
    This has to do, from what i can tell, with the ? placeholders. So, you should be doing something like :

    my $sth = $dbh->prepare('INSERT INTO table (foo,bar) VALUES (?,?)'); foreach my $value (keys %huge_data_set_to_insert) { $sth->execute($huge_data_set_to_insert{$value},$value); } $sth->finish();
    I would guess either you don't have the ?'s in the prepare, or the Database driver (DBD) you are using does not support them. you really need to post the error and relevant code if you want more than that.
    "They shall not overcome. Whoever told them that the truth shall set them free was obviously and grossly unfamiliar with federal law."
        -- John Ashcroft
Re: using sequences with dbi
by BigJoe (Curate) on Oct 04, 2001 at 00:36 UTC
    idunno,

    You don't even need the ? like people are suggesting. You can do it very quickly:
    $sth = $dbh->prepare("insert into table (blah_key, blah_name) values ( +blah_seq.nextval, '$blah_name')");
    In "standard SQL" make sure if it is a non-number put single quotes around it. Sequence.nextval & Sequence.currval are like SYSDATE they are functions in the Database so you don't single quote them.

    --BigJoe

    Learn patience, you must.
    Young PerlMonk, craves Not these things.
    Use the source Luke.
      There are some very good reasons for using placeholders instead of quoting your arguments, or at the very least, using $dbh->quote(...).
        Not to be rude, but why make it more complicated than it is? I have read the links and it looks to like it is mostly personal opinion. When it is something simple and quick I don't use place holders. When it is complicated from the begining then I use place holders. But again that is my personnal opinion.

        --BigJoe

        Learn patience, you must.
        Young PerlMonk, craves Not these things.
        Use the source Luke.
Re: using sequences with dbi
by idunno (Beadle) on Oct 03, 2001 at 19:11 UTC
    Thanks for all the help guys. That solved my problem. I just needed to put the blah_seq.nextval in my prepare and take it out of my execute like you said.

    Thanks much.