PostgreSQL中的撇号和引号 - 如何替换撇号?

3

在SQL中,查询字符串中的撇号引号有哪些角色?如何替换撇号?主要关注它们在PostgreSQL中的特定作用。如果省略撇号,会导致SQL查询出现问题,例如:

SELECT role FROM "USER_ROLES" WHERE "USER_ROLES".login = admin;

当管理员是一个值时,会出现“列'admin'不存在”的错误。写成'admin'可以解决这个问题。
SELECT role FROM "USER_ROLES" WHERE "USER_ROLES".login = 'admin';

实际问题是在另一个上下文中使用查询:

<module-option name="rolesQuery" value="SELECT 'role', 'Roles' FROM &quot;USER_ROLES&quot; WHERE login='?'"/>

按要求,表定义如下:

CREATE TABLE "USER_ROLES" (
  login text NOT NULL,
  role text,
  CONSTRAINT "USER_ROLES_pkey" PRIMARY KEY (login ),
  CONSTRAINT "USER_ROLES_login_fkey" FOREIGN KEY (login)
      REFERENCES "USER" (login) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

PostgreSQL版本9.1。


1
请展示您的确切表定义,以便我们知道标识符是否实际上是大写字母。另外,请告知您使用的PostgreSQL版本。 - Erwin Brandstetter
你的表中没有“ROLES”列? - Erwin Brandstetter
4个回答

9
你可以在PostgreSQL中使用美元引用来替换单引号'),以避免它们在不同上下文中的特殊含义。(虽然不确定美元符号是否也有特殊含义):
<module-option name="rolesQuery" value="SELECT role FROM &quot;USER_ROLES&quot; WHERE login = $$?$$"/>

另一个想法是使用&apos;代替单引号:
<module-option name="rolesQuery" value="SELECT role FROM &quot;USER_ROLES&quot; WHERE login = &apos;?&apos;"/>

1
一旦您使用美元引用代替单引号,您可能会在整个SQL字符串周围使用单引号而不是双引号,从而使需要使用双引号时可以直接使用它们。 - qqx

3
SELECT role FROM "USER_ROLES" WHERE "USER_ROLES".login = 'admin';

这里讲的单引号是指字符串。如果您直接对字符串进行操作,就需要用到这些引号。但如果您处理的是String对象,则不需要引号,可以直接使用该对象。
当您在列中直接引用字符串时,使用单引号(')。而双引号(")用于引用表对象。(您可以直接引用表名而不需要任何引号)
SELECT role FROM "USER_ROLES" WHERE "USER_ROLES".login = 'admin';

这里的'admin'是一个直接的字符串,它是相应列中一个单元格的值。

var string_object = 'admin';
SELECT role FROM "USER_ROLES" WHERE "USER_ROLES".login = string_object;

这里的 string_object 是存储某个字符串的对象,该存储的字符串代表相应列中一个单元格的值。


1
好的,仍然无法将该查询包含在XML文件中。 - jacktrades

2

单引号(')用于字符串。

当您省略引号时,解释器将把它视为名称,并尝试查找与该名称关联的值(通常是列)。

因此,无效的写法:

SELECT *
FROM yourtable
WHERE yourcolumn = xyz -- fails because there is no column named xyz
                       -- also, if it would exist, it would compare to the
                       -- value in that column rather than to the value 'xyz'

并且是有效的:

SELECT *
FROM yourtable
WHERE yourcolumn = 'xyz'

在数据库中,引号(")用于名称。

原因是PostgreSQL不接受大写字母作为表名(列名等),除非您将它们放在引号中。您也可以将其放在小写名称周围,在这种情况下没有区别。此外,这允许您使用保留名称作为表或列名称。因此,"index"可以用作列名,因为引号表示名称。不使用引号的index表示处理索引的保留字。

所以,这是无效的:

SELECT index -- invalid, reserved name
FROM YourTable -- invalid, capital letters

这是有效的代码:

SELECT "index"
FROM "YourTable"

有没有办法避免值中的 ''? - jacktrades
所以问题实际上是关于jboss配置的?对于双引号,你不能转义它们吗?对于问号,你不能简单地省略引号吗?接受参数的常规系统会根据您提供的值的类型包括所需的内容(例如单引号和转义值以避免破坏查询)。 - René Wolferink
虽然我曾经使用过不允许我使用大写字母或重命名表名称的系统。您可以重新命名您的表,或使用小写创建方法/视图。 - René Wolferink

0

你可以通过添加另一个撇号来替换撇号。

select replace('hi''','''','m')--  replaces apostrophe with m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接