我有一个表测试(id,名称)。
我需要插入值,如:用户的日志,'我的用户',客户的。
insert into test values (1,'user's log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
我得到一个错误,如果我运行上述任何语句。
如果有任何正确的方法,请分享。我不想要任何事先准备好的声明。
是否可以使用sql转义机制?
我有一个表测试(id,名称)。
我需要插入值,如:用户的日志,'我的用户',客户的。
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.;字符串常量):
若要在字符串常量中包含单引号字符,请写入 两个相邻的单引号,例如:“戴安的马”。
另请参阅standard_conforming_strings参数,该参数控制是否使用反斜杠进行转义。
这是非常糟糕的情况,因为您的问题暗示您的应用程序中可能存在巨大的SQL注入漏洞。
您应该使用参数化语句。对于Java,使用带占位符的PreparedStatement。你说你不想使用参数化语句,但你没有解释为什么,坦率地说,这必须是一个很好的理由不使用它们,因为它们是解决你试图解决的问题的最简单、最安全的方法。
请参见防止Java中SQL注入。别成为鲍比的下一个受害者。
PgJDBC中没有用于字符串引用和转义的公共函数。这在一定程度上是因为它可能看起来是个好主意。
在PostgreSQL中有内置的引号函数quote_literal和quote_ident,但它们是用于使用EXECUTE的PL/PgSQL函数的。这些天quote_literal基本上被EXECUTE淘汰了…使用,这是参数化的版本,因为它更安全、更简单。您不能将它们用于这里解释的目的,因为它们是服务器端函数。
想象一下,如果您从恶意用户那里获得值');DROP SCHEMA public;——会发生什么。你会产生:
insert into test values (1,'');DROP SCHEMA public;--');
它分解为两个语句和一个被忽略的注释:
insert into test values (1,'');
DROP SCHEMA public;
--');
哎呀,这就是你的数据库。
字符串字面值
转义单引号'通过双引号→"是标准方法,当然有效:
'user's log' -- incorrect syntax (unbalanced quote)
'user''s log'
纯单引号(ASCII / UTF-8代码39),注意,不是反引号,反引号在Postgres中没有特殊用途(不像某些其他RDBMS),也不是双引号”,用于标识符。
在旧版本中,或者如果你仍然使用standard_conforming_strings = off,或者通常,如果你在字符串前加上E来声明Posix转义字符串语法,你也可以使用反斜杠\转义:
E'user\'s 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注入的需要。克雷格的回答有更多关于这方面的内容。更多的细节:
Postgres函数中的SQL注入vs准备好的查询
Postgres中的值
当处理数据库中的值时,有几个有用的函数可以正确地引用字符串:
quote_literal()或quote_nullable()——后者为空输入输出字符串NULL。 在需要获得有效SQL标识符的地方,还可以使用quote_ident()对字符串进行双引号。 format()使用格式说明符%L等效于quote_nullable()。 例如:format('%L', string_var) Concat()或concat_ws()通常不适合此目的,因为它们不能转义嵌套的单引号和反斜杠。
在postgresql中,如果你想插入带有' In it '的值,那么你必须给额外的'
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(值)
https://www.postgresql.org/docs/9.3/static/functions-json.html#FUNCTIONS-JSON-TABLE
你可以使用postrgesql chr(int)函数:
insert into test values (2,'|| chr(39)||'my users'||chr(39)||');
当我使用Python在PostgreSQL中插入值时,我也遇到了一个问题:列“xxx”不存在。
我在wiki.postgresql中找到了原因:
PostgreSQL对此只使用单引号(即WHERE name = 'John')。双引号用于引用系统标识符;字段名,表名等(即WHERE "last name" = 'Smith')。 MySQL使用'(重音标记或反标记)来引用系统标识符,这显然是非标准的。
这意味着PostgreSQL只能对字段名、表名等使用单引号。所以你不能在值中使用单引号。
我的情况是:我想插入值“它是adj的sb和它是adj的sb的差异”到PostgreSQL。
我是如何解决这个问题的:
我把' with '和' with '替换掉。因为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' 正确的方法:“用户的日志”
问题:
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');