提问人:MAHI 提问时间:9/7/2012 最后编辑:Erwin BrandstetterMAHI 更新时间:3/15/2023 访问量:689125
在 PostgreSQL 中插入带单引号的文本
Insert text with single quotes in PostgreSQL
问:
我有一张桌子。test(id,name)
我需要插入以下值:、、。user's log
'my user'
customer's
insert into test values (1,'user's log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
如果我运行上述任何语句,我会收到错误。
如果有任何方法可以正确执行此操作,请分享。我不想要任何准备好的发言。
是否可以使用sql转义机制?
答:
根据 PostgreSQL 文档 (4.1.2.1.字符串常量):
若要在字符串常量中包含单引号字符,请编写 两个相邻的单引号,例如“Dianne's horse”。
另请参阅 standard_conforming_strings
参数,该参数控制使用反斜杠转义是否有效。
评论
这真是太糟糕了,因为你的问题意味着你的应用程序中可能存在巨大的 SQL 注入漏洞。
应使用参数化语句。对于 Java,请使用带有占位符的 PreparedStatement
。你说你不想使用参数化语句,但你没有解释为什么,坦率地说,这必须是一个很好的理由不使用它们,因为它们是解决你试图解决的问题的最简单、最安全的方法。
请参阅在 Java 中防止 SQL 注入。不要成为鲍比的下一个受害者。
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;
--');
哎呀,你的数据库在那里。
评论
database is accessed by java
字符串
通过加倍引号来转义单引号→是标准方法,当然也有效:'
''
'user's log' -- incorrect syntax (unbalanced quote)
'user''s log'
纯单引号(ASCII / UTF-8 代码 39),请注意,不是反引号,它在 Postgres 中没有特殊用途(与某些其他 RDBMS 不同),也不是用于标识符的双引号。`
"
在旧版本中,或者如果您仍然使用 standard_conforming_strings = off
运行,或者通常,如果您在字符串前面加上 以声明 Posix 转义字符串语法,您也可以使用反斜杠转义:E
\
E'user\'s log'
反斜杠本身通过另一个反斜杠进行转义。但这通常不是可取的。
如果您必须处理许多单引号或多层转义,则可以避免在 PostgreSQL 中使用美元引号字符串引用地狱:
'escape '' with '''''
$$escape ' with ''$$
为了进一步避免美元报价之间的混淆,请为每对添加一个唯一的代币:
$token$escape ' with ''$token$
可以嵌套任意数量的级别:
$token2$Inner string: $token1$escape ' with ''$token1$ is nested$token2$
请注意该字符是否应在客户端软件中具有特殊含义。此外,您可能还必须逃避它。对于psql或pgAdmin等标准PostgreSQL客户端,情况并非如此。$
这对于编写 PL/pgSQL 函数或临时 SQL 命令非常有用。但是,当用户输入可能时,它无法缓解使用预准备语句或其他方法来防止应用程序中的 SQL 注入的需要。@Craig的回答还有更多。更多详情:
Postgres 中的值
在处理数据库中的值时,有几个有用的函数可以正确地引用字符串:
quote_literal(
) 或quote_nullable()
- 后者输出 null 输入的不带引号的字符串。
在需要获取有效 SQL 标识符的地方,还有quote_ident()
来双引号字符串。NULL
- 带有格式说明符的
format()
等效于 。
喜欢:%L
quote_nullable()
format('%L', string_var)
) 或concat(
通常不适合此目的,因为它们不会转义嵌套的单引号和反斜杠。concat_ws()
评论
SELECT $outer$OUT$inner$INNER$inner$ER$outer$;
E
在postgresql中,如果你想在其中插入值,那么你必须为此提供额外的'
'
insert into test values (1,'user''s log');
insert into test values (2,'''my users''');
insert into test values (3,'customer''s');
评论
如果您需要在 Pg 中完成工作:
to_json(value)
https://www.postgresql.org/docs/9.3/static/functions-json.html#FUNCTIONS-JSON-TABLE
评论
format()
quote_literal()
quote_nullable()
您可以使用 PostrgeSQL chr(int) 函数:
insert into test values (2,'|| chr(39)||'my users'||chr(39)||');
当我使用 Python 将值插入到 PostgreSQL 中时,我也遇到了一个问题:“xxx”列不存在。
我在wiki.postgresql中找到了原因:
PostgreSQL对此仅使用单引号(即 )。双引号用于引用系统标识符;字段名称、表名等(即 )。
MySQL使用(重音符号或反引号)来引用系统标识符,这显然是非标准的。WHERE name = 'John'
WHERE "last name" = 'Smith'
`
这意味着 PostgreSQL 只能对字段名称、表名等使用单引号。因此,您不能在值中使用单引号。
我的情况是:我想在PostgreSQL中插入值“sb的adj和sb的adj的差异”。
我如何解决这个问题:
我用 '替换 ',我用 '
替换 '
。
因为 PostgreSQL 值不支持双引号。
所以我认为您可以使用以下代码来插入值:
insert into test values (1,'user’s log');
insert into test values (2,'my users');
insert into test values (3,'customer’s');
评论
'
user''s log'
您必须添加一个额外的单引号 -> ' 并将它们加倍引号,如下例所示 -> ' ' 是标准方法,当然有效:
错误的方式:'user's log' 正确方式: 'user's log'
问题:
insert into test values (1,'user's log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
解决 方案:
insert into test values (1,'user''s log');
insert into test values (2,'''my users''');
insert into test values (3,'customer''s');
评论