0

I am trying to create an SQL select statement in PL/pgSQL procedure. It was all fine until I had to add a date to the select. The problem is that to compare dates in select clause my date must be enclosed in single quotes '' (e.g. '01.01.2011'), but in my case it is already a text type and I can't add it there.

Below is a sample code that should have same problem:

CREATE OR REPLACE FUNCTION sample(i_date timestamp without time zone)
  RETURNS integer AS
$BODY$
DECLARE
  _count integer := 0;
  _sql text := '';
BEGIN

  IF i_date IS NOT NULL THEN
   _cond := _cond || ' AND t.created>' || i_date;
END IF;

_sql := 'SELECT count(*) FROM test t WHERE 1=1' || _cond;

EXECUTE _sql INTO _count;
RETURN _count;

END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Is there any other way to "escape" date? Or some other suggestions?

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
srumjant
  • 155
  • 7

1 Answers1

2

To use insert values safely and efficiently into a dynamically build and executed SQL string, there are a number of possibilities. The best one is to use the USING clause like this:

CREATE OR REPLACE FUNCTION sample(_date timestamp without time zone)
RETURNS integer AS
$BODY$
BEGIN
    RETURN QUERY EXECUTE '
    SELECT count(*)::int
    FROM   test t
    WHERE  t.created > $1'
    USING  _date;
END;
$BODY$ LANGUAGE plpgsql VOLATILE;

This is actually a bad example, because it could be simplified to:

CREATE OR REPLACE FUNCTION sample(_date timestamp)
RETURNS integer AS
$BODY$
    SELECT count(*)::int
    FROM   test
    WHERE  created > $1;
$BODY$ LANGUAGE sql;

Another way would be to use quote_literal().
I wrote more about dynamic SQL in plpgsql here.

Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228