NAME
SQL::Template - A new way to organize your database code
VERSION
Version 0.2.4
SYNOPSIS
use SQL::Template;
my $sql = SQL::Template->new(-filename=>"my-custom-sqls.xml");
my $dbh =DBI->connect("dbi:SQLite:dbname=example.sqlite","","");
#Simple record insert
$sql->do("insert_country", $dbh, {COUNTRY_ID=>'ES', NAME=>'SPAIN'} );
# fetch records
my $stmt = $sql->select_stmt("query_for_persons", $dbh, {NAME=>'JOHN'} );
while( my $hr = $stmt->fetchrow_hashref ) {
print $hr->{NAME}, "\n";
}
$stmt->finish;
### file: my-custom-sqls.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<st:sql>
<st:do name="insert_country" >
INSERT INTO COUNTRY(COUNTRY_ID, NAME)
VALUES( ${COUNTRY_ID}, ${NAME} )
</st:do>
<st:select name="query_for_persons" >
SELECT * FROM PERSON
<st:if test="${NAME}" prepend="WHERE">
NAME=${NAME}
</st:if>
</st:select>
</st:sql>
DESCRIPTION
Write SQL sentences in external files and use them from Perl.
Imagine this situation: you know DBI and you like it, because you can make use of your SQL knowledge. But you are not happy having the SQL code into the Perl code. You can use other CPAN modules, which let us to abstract SQL code. But we want to write SQL code, we feel confortable with it.
This module decouples SQL sentences from Perl code, writting sentences in a XML file, that you can use in different parts of your code. SQL::Template allows dynamic test of expressions, and reuse of fragments.
The SQL handled sentences are SQL-inyection free; SQL::Template make use of parameter binding.
XML file
The XML file contains the SQL sentences that you will use with SQL::Template. This is more than a dictionary container, it allows us to build dinamyc SQL and reuse fragments.
General
The different parts are enclosed between <st:sql>
and </st:sql>
<?xml version="1.0" encoding="iso-8859-1"?>
<st:sql>
<!-- file contents -->
</st:sql>
st:do
This command is used to make DDL sentences or INSERT, UPDATE and DELETE. For example:
<st:do name="update_named_1" >
UPDATE AUTHOR SET NAME=${NAME}, FIRST_NAME=${FIRSTNAME, SQL_VARCHAR}
WHERE AUTHOR_ID=${ID}
</st:do>
This simple command shows us important things:
- name
-
The name attribute is mandatory, and it will be used to link the Perl code with the SQL
- parameters
-
Parameters tou pass with a HASH reference to SQL::Template are binding to the SQL. In the previous example,
${NAME}
and${FIRSTNAME, SQL_VARCHAR}
. The fisrt is the simple use, where the parameter will be replaced (using DBI bind). The second one will be used if you need to indicate the data type.
st:select
If we need to make SELECT sentences, the command st:select
will be used. This is a simple example:
<st:select name="query_for_author" >
SELECT * FROM AUTHOR WHERE AUTHOR_ID=${ID}
</st:select>
Like the previous one, you can bind parameters with the ${variable}
syntaxt
st:fragment
When we are writting SQL sentences, there are many of them similar, changing specific parts. I think that you can reuse SQL fragments in order to reduce the code you write, and to make the maintenance easier.
- define a fragment
-
<st:fragment name="filter_authors_with_A"> AND NAME LIKE 'A%' </st:fragment>
- use it
-
<st:select name="query_for_authors_with_A" > SELECT * FROM AUTHOR WHERE AUTHOR_ID=${ID} <st:include name="filter_authors_with_A"/> </st:select>
Dynamic sentences
SQL::Template dynamic feature is simple and strong. It allow us to write comple SQL sentences that can be different depending on parameters values. For example:
<st:select name="query_named_1" >
SELECT * FROM AUTHOR
WHERE YEAR=${YEAR}
<st:if test="${GENDER} eq 'F'" prepend="AND">
CITY != ${CITY}
</st:if>
<st:else>
AGE > 18
</st:else>
</st:select>
As you can see, <st:if>
command is used to build dynamic SQL. The "if" command can be used in <st:do>
and <st:fragment>
. It's composed by:
- test
-
Any valid Perl expression, where you can bind the parameters. SQL::Templante will eval this expression in order to calculate the result. Boolean "true" or "false" rules are the same that Perl uses in boolean expressions
- prepend
-
If the test expression returns "true", prepend this text to the SQL block enclosed by "st:if". It isn't mandatory.
- <st:else>
-
The common "else" section in any "if" block. It isn't mandatory, and it will be used if the test expression returns false.
METHODS
SQL::Template methods are written in a way that it's similar to DBI interface, so I hope you will be confortable with them.
new ( option=>value )
The new()
function takes a list of options and values, and returns a new SQL::Template object which can then be used to use SQL sentences. The accepted options are (one of them is mandatory):
- -filename
-
This determines the XML file which contains the SQL sentences. The object creation phase involves parsing the file, so any error (like syntax) cause an exception throw. If everything is fine, all commands searched are cached in order to improve the performance
- -string
-
If you prefer to build a string with XML-syntax, you can build a SQL::Template object in that way.
select_stmt ( $name, $dbh, $params, $attrs )
This method search in the command cache, and if it's found, SQL::Template try to apply the params and execute in provided database handle. These are the arguments:
- $name
-
The name of SQL sentence to use. This must match with a sentence in the XML file.
- $dbh
-
The database handle to be used. Note tat SQL::Template doesn't establish a connection with your DB, it only use the one you want.
- $params
-
When the SQL sentence needs parameters, you must provide them with a hash reference variable.
- $attrs
-
Any aditional attribute you need to pass to the database driver, it will be used in the DBI commands. Typically, you don't use this param.
This methods use the following DBI functions: prepare, bind_param, execute. It returns a DBI::st handle, you can fetch in the habitual way. For example:
my $stmt = $sql->select_stmt("query_for_persons", $dbh, {NAME=>'JOHN'} );
while( my @row = $stmt->fetchrow_array ) {
print "@row\n";
}
$stmt->finish;
selectrow_array ( $name, $dbh, $params, $attrs )
This method interface is similar to the previous you have seen in section "select_stmt". In this case, SQL::Template makes a call to DBI fetchrow_array
function and finish
the statement handle, returning an array with the results
selectrow_arrayref ( $name, $dbh, $params, $attrs )
This method interface is similar to the previous you have seen in section "selectrow_array". In this case, SQL::Template makes a call to DBI fetchrow_arrayref
function and finish
the statement handle, returning an array reference with the results
selectrow_hashref ( $name, $dbh, $params, $attrs )
This method interface is similar to the previous you have seen in section "selectrow_array". In this case, SQL::Template makes a call to DBI fetchrow_hashref
function and finish
the statement handle, returning a hash reference with the results
selectall_arrayref
This method combines "prepare", "execute" and "fetchall_arrayref" into a single call. It returns a reference to an array containing a reference to an array (or hash, see below) for each row of data fetched. This method interface is similar to the previous you have seen in section "selectrow_array".
See DBI selectall_hashref
method for more details.
selectall_hashref
This method combines "prepare", "execute" and "fetchall_arrayref" into a single call. It returns a reference to an array containing a reference to an hash for each row of data fetched. This method interface is similar to the previous you have seen in section "selectrow_array".
See DBI selectall_hashref
method for more details.
do ( $name, $dbh, $params, $attrs )
This method interface is similar to the previous you have seen in section "select_stmt". The main use of this function is to execute DDL commands and INSERT, UPDATE or DELETE commands. In this case, SQL::Template makes a call to DBI execute
function and returns its results to the caller.
AUTHOR
prz, <niceperl at gmail.com>
BUGS
Please report any bugs or feature requests to bug-sql-template at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=SQL-Template. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc SQL::Template
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
COPYRIGHT & LICENSE
Copyright 2009 prz.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.