I just released a new module, SQL::Tiny. It’s intended for creating simple SQL statements where speed is not as important as having maintainable code.

SQL::Tiny is a very simple SQL-building library. It’s not for all your SQL needs, only the very simple ones.

In my test suites, I have a lot of ad hoc SQL queries, and it drives me nuts to have so much SQL code lying around. SQL::Tiny is for generating SQL code for simple cases.

I’d far rather have:

my ($sql,$binds) = SQL::Tiny::sql_insert(
        name      => 'Dave',
        salary    => 50000,
        phone     => undef,
        status    => 'Active',
        dateadded => \'SYSDATE()',

than hand-coding:

my $sql =
    'INSERT INTO users (name,salary,phone,status,dateadded) '.
    'VALUES (:name,:status,NULL,:salary,SYSDATE())';

my $binds = {
    ':name'   => 'Dave',
    ':salary' => 50000,
    ':status' => 'Active',

or even the positional:

my $sql =
    'INSERT INTO users (name,salary,phone,status,dateadded) '.
    'VALUES (?,?,NULL,?,SYSDATE())';
my $binds = [ 'Dave', 50000, 'Active' ];

The trade-off for that brevity of code is that SQL::Tiny has to make new SQL and binds from the input every time. You can’t cache the SQL that comes back from SQL::Tiny because the placeholders could vary depending on what the input data is. Therefore, you don’t want to use SQL::Tiny where speed is essential.

The other trade-off is that SQL::Tiny handles only very simple code. It won’t handle JOINs of any kind.

SQL::Tiny isn’t meant for all of your SQL needs, only the simple ones that you do over and over.

I looked at the fine SQL::Abstract, but it was more complex than I wanted to deal with, and more importantly, I didn’t want to bring in a trail of depencies.