8

I have a string with value

'MAX DATE QUERY: SELECT iso_timestamp(MAX(time_stamp)) AS MAXTIME FROM observation WHERE offering_id = 'HOBART''

But on inserting into postgresql table i am getting error:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "HOBART".

This is probably because my string contains single quotes. I don't know my string value. Every time it keeps changing and may contain special characters like \ or something since I am reading from a file and saving into postgres database.

Please give a general solution to escape such characters.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
shomik naik
  • 235
  • 1
  • 3
  • 12
  • The best way to do that depends on your database API. Is this a manual query typed into the console, or can you use a prepared statement API from a programming language? – deceze Jul 03 '13 at 06:50
  • 2
    In case you're wondering "why all the down-votes", I actually upvoted you (because I think all the downvotes are a bit over the top) but I'd say the reasons are: common question easily answered with a search; didn't show your code; didn't show PostgreSQL version; no sign of doing any research of searching first. – Craig Ringer Jul 03 '13 at 07:19
  • Actually,I dont know what would be my next string value.Let me explain..I am using the followingquery:INSERT INTO logs (dated, logger, level, message) VALUES('%d{yyyy-MM-dd HH:mm:ss.SSS}','%C','%p','%m').Here I dont message string value. Then How will I add one more single quote to escape another single quote.I am reading from a file and entering into message column. – shomik naik Jul 03 '13 at 08:22
  • Possible duplicate of [Which "special" characters are allowed in SQL Server varchar fields?](http://stackoverflow.com/questions/7038213/which-special-characters-are-allowed-in-sql-server-varchar-fields) – Ashraf Sada Jun 16 '16 at 19:42

5 Answers5

15

As per the SQL standard, quotes are delimited by doubling them, ie:

insert into table (column) values ('I''m OK')

If you replace every single quote in your text with two single quotes, it will work.

Normally, a backslash escapes the following character, but literal backslashes are similarly escaped by using two backslashes"

insert into table (column) values ('Look in C:\\Temp')
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Using a backslash for escaping characters is deprecated (because it's non-standard) and disabled in current Postgres versions. `'Look in C:\Temp'` will work just fine. –  Jul 03 '13 at 06:58
  • @a_horse_with_no_name [version 9 doc](http://www.postgresql.org/docs/9.0/static/sql-syntax-lexical.html) says double backslash is still the way to do it. Have you got a link? – Bohemian Jul 03 '13 at 07:05
  • 1
    @Bohemian It also says you have to use `E''` style strings to enable C-style backslash escapes on the page you link to. Usually `standard_conforming_strings` is turned on, and you use regular SQL-standard quote doubling. See http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html – Craig Ringer Jul 03 '13 at 07:12
  • See the "Caution" block in chapter 4.1.2.2 (in the link you posted) –  Jul 03 '13 at 07:14
  • Actually,I dont know what would be my next string value.Let me explain..I am using the followingquery:INSERT INTO logs (dated, logger, level, message) VALUES('%d{yyyy-MM-dd HH:mm:ss.SSS}','%C','%p','%m').Here I dont message string value. Then How will I add one more single quote to escape another single quote.I am reading from a file and entering into message column. – shomik naik Jul 03 '13 at 08:25
  • If you use JDBC and prepared statements with placeholders, the driver does all the escsping for you. Ie don't reinvent the wheel by constructing your own SQL – Bohemian Jul 03 '13 at 09:02
13

You can use double dollar quotation to escape the special characters in your string. The above query as mentioned insert into table (column) values ('I'm OK')

changes to insert into table (column) values ($$I'm OK$$).

To make the identifier unique so that it doesn't mix with the values, you can add any characters between 2 dollars such as
insert into table (column) values ($aesc6$I'm OK$aesc6$).

here $aesc6$ is the unique string identifier so that even if $$ is part of the value, it will be treated as a value and not a identifier.

Sandeep Sukhija
  • 1,156
  • 16
  • 30
5

You appear to be using Java and JDBC. Please read the JDBC tutorial, which describes how to use paramaterized queries to safely insert data without risking SQL injection problems.

Please read the prepared statements section of the JDBC tutorial and these simple examples in various languages including Java.

Since you're having issues with backslashes, not just 'single quotes', I'd say you're running PostgreSQL 9.0 or older, which default to standard_conforming_strings = off. In newer versions backslashes are only special if you use the PostgreSQL extension E'escape strings'. (This is why you always include your PostgreSQL version in questions).

You might also want to examine:

While it is possible to explicitly quote values, doing so is error-prone, slow and inefficient. You should use parameterized queries (prepared statements) to safely insert data.

In future, please include a code snippet that you're having a problem with and details of the language you're using, the PostgreSQL version, etc.

If you really must manually escape strings, you'll need to make sure that standard_conforming_strings is on and double quotes, eg don''t manually escape text; or use PostgreSQL-specific E'escape strings where you \'backslash escape\' quotes'. But really, use prepared statements, it's way easier.

Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
1

Some possible approaches are:

  1. use prepared statements
  2. convert all special characters to their equivalent html entities.
  3. use base64 encoding while storing the string, and base64 decoding while reading the string from the db table.

Approach 1 (prepared statements) can be combined with approaches 2 and 3.

Approach 3 (base64 encoding) converts all characters to hexadecimal characters without loosing any info. But you may not be able to do full-text search using this approach.

raj kumar
  • 11
  • 1
-1

Literals in SQLServer start with N like this:

update table set stringField = N'/;l;sldl;'''mess'
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213