[Dbix-class] SQLA refactor: proposal

Darren Duncan darren at DarrenDuncan.net
Tue Nov 27 20:21:44 GMT 2007


At 12:13 PM -0600 11/27/07, Wade.Stuart at fallon.com wrote:
>Darren Duncan <darren at DarrenDuncan.net> wrote on 11/26/2007 10:26:04 PM:
>  > I alternately or additionally recommend generating SQL stored
>  > procedures where it is reasonable to do so.
>
>I do hope you are not recommending any type of dynamically created stored
>procedure backend?  The idea of my ORM making fugly dynamic stored
>procedures all over the place makes me long for SQL + DBI.  As far as my
>view on it -- if I want to optimize something down to a SP I would create
>it by hand (usable in my perl app and other db apps) and then call it via
>DBIC's already exposed API.
>
>  > As for DBMSs without stored procedure support, or where you don't
>>  want to alter the pre-existing schema, well then there is the
>  > generated Perl subs solution that I previously mentioned.

No part of my suggestion involved "making fugly dynamic stored 
procedures all over the place".

When SQL stored procedures are to be generated and persistently 
stored in a database, that only would happen when you explicitly ask 
it to happen, as per deploying a schema / creating tables in a 
database.

Also, Muldis D would be defining the stored procedures in a 
deterministic fashion, so you can know in advance what the resulting 
SQL interface should be, so that the SP can be reusable with all db 
apps not just the Perl ones.  The SP structure is also fairly 
deterministic as well, since you explicitly choose the names for all 
your parameters and variables et al as well (and for the table 
generators, you also explicitly choose names for your foreign/etc 
constraints), like when writing the SQL yourself.  After all, a 
relational database is supposed to be application-agnostic, like a 
library, in the general case.

When you don't want to change your database schema, the generated 
stored procedures can be temporary and/or anonymous; Oracle at least 
supports anonymous versions in that they are as transient as 
extra-procedure statements that a client executes against a server, 
but having multiple statements.

And barring support for the latter, then as I first suggested, the 
procedure can be faked on the Perl side, as a Perl anonymous routine, 
and no DBMS schema changes happen at all, this being essentially what 
you prefer to do.

Now, my more specific recommendation on this regard is context 
specific.  Generally speaking, there are 2 kinds of SQL statements 
that one would feed to a DBMS.

One kind is one that is effectively part of an application's source 
code (or the source code shared by all database-using applications as 
per a library); this kind of SQL is generally known in advance, and 
would be the best candidate for rendering as actual SQL stored 
procedures where appropriate, and schema deployment or schema update 
time.  These are not generated from user input and you would 
generally be fine-tuning them a lot more, so they wouldn't be fugly.

The other kind is SQL that is generated based on runtime user input, 
and that SQL is only used temporarily then discarded.  The main 
example for this is when the application is a generic database access 
tool such as Toad or SQL*Plus et al.  In this case, I recommend just 
transient SPs or faking it in Perl, but no schema changes in any 
event.

I think most of the time users would not be affecting the structure 
of the SQL queries.

Note that I am assuming throughout this whole discourse that any SQL 
being generated makes use of bind parameters where the values used in 
it would vary based on user input, so that the same kind of query, 
aside from input values, would only be generated just once and 
reused.  Which is the proper way to do it.  This approach translates 
to a stored procedure, whether in SQL or in Perl, paradigm very well, 
in which the parameters of the stored procedure correspond to the 
bind parameters / what might be variable at runtime.

Obviously, the utility of using stored procedures et al, can be 
affected by some general design decisions of the Perl programmers; it 
won't work as well if they don't use SQL parameters, and use of those 
has always been a good idea even if no AST or ORM was in the tool 
chain.

So, I defend generating SQL stored procedures from ASTs when done for 
good reasons, but regardless I defend the users having a choice 
between doing that or faking it in Perl instead.  Flexibility is one 
name of the game.

One more thing.  When you have a good AST, and a good generator, it 
is perfectly fine to use that rather than hand-crafting SPs.  The 
analogy is like with language compilers.  Sure, lots of people can 
choose to write assembly language because they don't trust their C 
compilers et al to do a good enough job with tuning, but the vast 
majority of the time, the compiler will do it 99% good enough, or 
will typically do it better than a non-expert assembler, and 
certainly do it with less developer effort.  If hand-crafting SQL is 
still necessary for general (non-esoteric) situations, it is because 
the ASTs and generators aren't good enough, in general.

For debugging SQL output, I'm sure anything that's generated can also 
be pretty-printed ala Perltidy.

-- Darren Duncan



More information about the DBIx-Class mailing list