2

I have postgres function in which i am appending values in query such that i have,

DECLARE
    clause text = '';

after appending i have some thing like,

clause = "and name='john' and age='24' and location ='New York';"

I append above in where clause of the query i already have. While executing query i am getting "and" just after "where" result in error

How to use regex_replace so that i remove the first "and" from clause before appending it to the query ?

klin
  • 112,967
  • 15
  • 204
  • 232
user3664724
  • 425
  • 1
  • 6
  • 18
  • Have you tried leave `'and'` from the start of `clause`? I don't think manipulating an sql query with regular expressions is a good idea. – pozs May 27 '14 at 09:17
  • it will append and in query because there are conditions on which it is appending query and it is not possible to stop it thats why after appending i am removing it from clause – user3664724 May 27 '14 at 09:23

5 Answers5

2

Instead of fixing clause after the fact, you could avoid the problem by using concat_ws (concatenate with separator):

clause = concat_ws(' and ', "name='john'", "age='24'", "location ='New York'") 

will make clause equal to

"name='john' and age='24' and location ='New York'"
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
2

This can be even simpler. Use right() with a negative offset.

Truncates the first n characters and you don't need to specify the length of the string. Faster, simpler.

Double quotes (") are for identifiers in Postgres (and standard SQL) and incorrect in your example. Enclose string literals in single quotes (') and escape single quotes within - or use dollar quoting:
Insert text with single quotes in PostgreSQL

Since this is a plpgsql assignment, use the proper assignment operator :=. The SQL assignment operator = is tolerated, too, but can lead to ambiguity in corner cases.

Finally, you can assign a variable in plpgsql at declaration time. Assignments in plpgsql are still cheap but more expensive than in other programming languages.

DECLARE
   clause text := right($$and name='john' and age='24' ... $$, -5)

All that said, it seems like you are trying to work with dynamic SQL and starting off on the wrong foot here. If those values can change, rather supply them as values with the USING clause of EXECUTE and be wary of SQL injection. Read some of the related questions and answers on the matter:
https://stackoverflow.com/search?q=[plpgsql]+[dynamic-sql]+EXECUTE+USING

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

You do not need regex:

clause = substr(clause, 5, 10000);
clause = substr(clause, 5, length(clause)- 4); -- version for formalists
klin
  • 112,967
  • 15
  • 204
  • 232
1

concat_ws sounds like the best option, but as a general solution for things like this (or any sort of list with a delimiter) you can use logic like (pseudocode):

delim = '';
while (more appendages)
    clause = delim + nextAppendage;
    delim = ' AND ';
OGHaza
  • 4,795
  • 7
  • 23
  • 29
0

If you want to do it with regular expression try this:

result = regexp_replace(clause, '^and ', '')
miindlek
  • 3,523
  • 14
  • 25