Вставить текст с одинарными кавычками в PostgreSQL
У меня есть таблица test(id,name)
.
Мне нужно вставить такие значения, как: user log
, 'my user'
, customer's
.
insert into test values (1,'user log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
Я получаю сообщение об ошибке, если я запускаю любое из приведенных выше инструкций.
Если есть способ сделать это правильно, поделитесь. Я не хочу никаких подготовленных заявлений.
Возможно ли использование механизма экранирования sql?
Ответы
Ответ 1
Сбрасывание одиночных кавычек '
удвоением их → ''
является стандартным способом и, конечно же, работает.
'user log' -- incorrect syntax (unbalanced quote)
'user' log'
В старых версиях или если вы все еще выполняете standard_conforming_strings = off
или, как правило, если вы добавили строку в E
чтобы объявить синтаксис строки escape-кода Posix, вы также можете сбежать с обратным слэшем \
:
E'user\ log'
Но это вообще не предпочтительнее.
Если вам приходится иметь дело со многими одинарными кавычками или несколькими слоями экранирования, вы можете избежать цитирования ада в PostgreSQL со строками, закодированными в долларах:
'escape '' with '''''
$$escape ' with ''$$
Чтобы избежать путаницы между долларовыми котировками, добавьте уникальный токен каждой паре:
$token$escape ' with ''$token$
Который может быть вложен в любое количество уровней:
$token2$Inner string: $token1$escape ' with ''$token1$ is nested$token2$
Обратите внимание, если символ $
должен иметь особое значение в вашем клиентском программном обеспечении. Возможно, вам придется избежать этого. Это не относится к стандартным клиентам PostgreSQL, таким как psql или pgAdmin.
Это очень полезно для написания функций plpgsql или специальных команд SQL. Он не может облегчить необходимость использования подготовленных операторов или какого-либо другого метода для защиты от SQL-инъекции в вашем приложении, когда пользовательский ввод возможен. Ответ @Craig имеет больше об этом. Подробнее:
Ответ 2
Это так много миров плохого, потому что ваш вопрос подразумевает, что у вас, вероятно, есть зияющие дыры SQL injection в вашем приложении.
Вы должны использовать параметризованные операторы. Для Java используйте PreparedStatement
с заполнителями. Вы говорите, что не хотите использовать параметризованные утверждения, но вы не объясняете, почему, и, откровенно говоря, это очень хорошая причина не использовать их, потому что они самый простой и безопасный способ исправить проблему, которую вы пытаетесь решить.
См. Предотвращение внедрения SQL в Java. Не будьте Бобби следующей жертвой.
В PgJDBC нет публичной функции для строкового цитирования и экранирования. Это отчасти потому, что это может показаться хорошей идеей.
В PostgreSQL есть встроенные функции кавычек quote_literal
и quote_ident
, но они предназначены для PL/PgSQL
функций, которые используют EXECUTE
. В наши дни quote_literal
в основном устаревает EXECUTE ... USING
, что является параметризованной версией, потому что это безопаснее и проще. Вы не можете использовать их для объяснения здесь, потому что это серверные функции.
Представьте, что произойдет, если вы получите значение ');DROP SCHEMA public;--
от злоумышленника. Вы будете производить:
insert into test values (1,'');DROP SCHEMA public;--');
который разбивается на два оператора и комментарий, который игнорируется:
insert into test values (1,'');
DROP SCHEMA public;
--');
У вас есть база данных.
Ответ 3
Согласно Документация PostgreSQL (4.1.2.1. Строковые константы):
To include a single-quote character within a string constant, write two
adjacent single quotes, e.g. 'Dianne' horse'.
См. также параметр standard_conforming_strings, который контролирует, работает ли экранирование с помощью обратных косых черт.
Ответ 4
В postgresql, если вы хотите вставить в него значения с '
, то для этого вам нужно предоставить дополнительные '
insert into test values (1,'user' log');
insert into test values (2,'''my users''');
insert into test values (3,'customer''s');
Ответ 5
вы можете использовать функцию postrgesql chr (int):
insert into test values (2,'|| chr(39)||'my users'||chr(39)||');
Ответ 6
Если вам нужно выполнить работу внутри Pg:
to_json(value)
https://www.postgresql.org/docs/9.3/static/functions-json.html#FUNCTIONS-JSON-TABLE