NAME
SQL::Catalog - test, label, and retrieve SQL queries
SYNOPSIS
shell% cd sql_lair/city,date/weather/1/
shell% cat concrete.sql
select city, date from weather where temp_lo < 20;
shell% sql_test concrete.sql
shell% cat testexec.out # see results of prepare, execute on this
shell% cat abstract.sql
select city, date from weather where temp_lo < ?;
shell% sql_test abstract.sql 55 # send in placeholder value
shell% cat testexec.out # to see results... looks good
shell% sql_register abstract.sql basic_weather
[hi_and_low] inserted as
[select city from weather where temp_lo > ? and temp_hi > ? LIMIT 10]
... then in a Perl program (e.g. test.pl in this distribution)
my $dbh = SQL::Catalog->db_handle; # optional - get the handle as you please
my $sql = SQL::Catalog->lookup('hi_and_low');
my $sth = $dbh->prepare($sql);
$sth->execute(55);
my $rows = $sth->rows;
DESCRIPTION
Over time, it has become obvious that two things about SQL queries are necessary. One, you want to be able to get a query by a label. Two, you want to be able to look through old queries to see if someone else has written one similar to what you want. Three, you want the database guru to develop queries on his own and be able to register them for your use without interfering with him. Four, you want to be able to answer questions such as "what queries are doing a select on such-and-such tables".
Well, wait no longer, for your solution has arrived.
Common Steps to Usage
Develop your "concrete query in a db shell"
The first step to developing a database query is to play around at the db shell. In this case, you normally dont have any placeheld values. You just keep mucking with the query until it gives you what you want.
When you finally get what you want, save it in a file, say concrete.sql
for example. Here is a concrete query:
select city, date from weather where temp_hi > 20
Abstract your query with placeholders
Now it's time to make your query more abstract. So we do the following:
select city, date from weather where temp_hi > ?
and save in a different file, say abstract.sql
.
But let's test this query next:
sql_test abstract.sql 34
And let's cat testexec.out to see the results.
Register your query
sql_register abstract.sql city_date_via_temp_hi
and the system tells you
[city_date_via_temp_hi] saved as
[select city, date from weather where temp_hi > ?]
Use your query from DBI:
use SQL::Catalog;
my $dbh = SQL::Catalog->db_handle;
my $SQL = SQL::Catalog->lookup('city_date_via_temp_hi') or die "not found";
my $sth = $dbh->prepare($SQL, $cgi->param('degrees'));
.... etc
What you must do
edit sub db_handle so it gets a database handle.
copy the sql_* scripts to a place on your
$PATH
create a table named sql_catalog. a script for Postgresql is provided.
What SQL::Catalog does
It stores each query in a database table. I could have gone for something more fancy in database design but wanted to maintain database independence without requiring extra tools for schema creation and database use.
The queries are stored in this table:
CREATE TABLE sql_catalog (
query varchar(65535) , # the actual query
tables varchar(255) , # tables used
columns varchar(255) , # fields selected
cmd varchar(40) , # SELECT, INSERT, UPDATE, etc
phold int4 # number of bind_values
);
Query field omitted for brevity. It has (wouldya guess) the SQL query.
mydb=# select label,cmd,columns,tables,phold from sql_catalog;
label | cmd | columns | tables | phold
---------------+--------+---------------------------------------------------
weather_hi | SELECT | weather.city,weather.date | weather | 1
hi_and_low | SELECT | weather.city | weather | 2
AUTHOR
T. M. Brannon, <tbone@cpan.org>
SEE ALSO
Class::Phrasebook::SQL performs a similar function. It stores a "phrasebook" of SQL in XML files. It doesn't support placeholders. It also has some rather daunting satellite module requirements.
DBIx::SearchProfile does query labeling and also has some convenience functions for query retrieval. It does not store the SQL in a database or make it searchable by table, column, or number of placeholders.