At 1:24 PM +0000 7/10/05, Greg Sabino Mullane wrote:
Sure, I don't have a problem with the :foo form, I was just saying
that for short examples, the '?' format is simpler:

$sth->execute(101);

vs.

$sth->execute( { "myfirstarg", 101 });
or
$sth->bind_param("myfirstarg", 101 ...);
$sth->execute();

My implication is that when you want to use named host parameters, you would be using names that are descriptive, like this:

  $sth = $dbh->prepare(
    "select * from foo where bar = :search_text or baz = :search_text" );
  $sth->execute( 'search_text' => 'abc' );

Looks better then, doesn't it?

As for the cases where descriptive names aren't so important, such as with an ad-hoc query for doing arbitrary math, the code which is generating this statement from the little pieces anyway would also generate :foo names such as :p1, :p2, etc; that is a named equivalent to the ? format.

The can already generate the SQL without a database connection. I guess
the real advantage is in pre-parsing the SQL and turning it into a
form more amenable to passing to the database server, by quoting values
and/or changing placeholder forms. I could possibly see a place for this,
and I like the option of allowing some things to possible be done before
the database is connected, but I don't really see much of a real-world
time saving. But where would this method live? It obviously could not
be called via $dbh->compile, nor could it be DBI->compile. You would
almost need a new connection mtehod, or perhaps a flag on the current
connect() method that tells the driver to load, but defer actually
conecting to the database.

If my other suggestion about declaring and opening a database connection is adopted, then that provides what is needed; you can do $dbh->compile() on a $dbh that hasn't been opened.

I just want to make sure that we keep
DBI as an abstraction layer. Additional hooks are fine: additional
tasks are not.

I agree.

 >> A $sth should not contain any methods for fetching the result of
  an executed statement;
...
     my $rlh = $sth->execute();
     my $rowset = $rlh->fetchrow_arrayref();

At the very least, you'll need a different interface, as execute()
already returns a value (number of rows affected).

If you are striving for full backwards compatability, that is true. If you are not, then in this example, the number of rows affected can be gained by invoking a method of $rlh.

 > Not to me.  I see a statement as a program function.  You prepare it,
 invoke it with arguments, and it returns a result.  The result is
 separate from the function.

I see a statement as an object. The results are attributes of the statement
object, and there are methods for getting at that information. The
results are closely tied to that particular statement, so disassociating
them gains nothing, and adds possible confusion. And what do call finish()
with - rlh or sth?

That depends entirely on whether DBI will let you execute() a $sth a second time, and afterwards continue to read results of the previous execution from the previous $rlh. If another execute() will kill the previous results, then you invoke finish() on the $sth; if several can work concurrently (as you can have several prepared statements concurrently, I think), then you call it on the $rlh instead. Having a separate $rlh gives an API to allowing several concurrent executes on the same $sth.

In any event, if the kill-previous scenario is what always happens, ...

I've had a partial re-thinking on this matter and am now inclined to agree with you, to remove the rlh object. In that case, a $sth would continue to work more or less as it already has, but that it should be possible to get all types of return values, whether a row set or count of rows affected, using an appropriate $sth method. This would be a complement or mixin with the current bind_param() functionality, where you act like the result of a statement is placed in an 'OUT/INOUT' host parameter rather than being something different.

SQL itself has a structure that lends itself to this approach already. For example, in a SQL stored function, if you want to store/return the result of a query, you can't do this, that I'm aware of, but I would be happy if it would work:

  SET myvar = SELECT * FROM foo;

or

  RETURN SELECT * FROM foo;

But rather you have to:

  SELECT * INTO myvar FROM foo;
  RETURN myvar;

or just the first line assuming that myvar is an OUT/INOUT function parameter.

If we have to use the OUT/INOUT parameter thing anyway, then a DBI interface akin to bind_param(), or a new $sth.get_out_param() would work to get the result. With no separate object for results required.

-- Darren Duncan

Reply via email to