在Postgres中转义类似关键字的列名

时间:2011-10-04 16:58:40

标签: sql postgresql

如果Postgres表中的列名称为year,那么应该如何查询INSERT查询以设置该列的值?

例如:INSERT INTO table (id, name, year) VALUES ( ... );字附近发出错误。

3 个答案:

答案 0 :(得分:168)

只需将year括在双引号中即可将其解释为keyword

INSERT INTO table (id, name, "year") VALUES ( ... );

来自documentation

  

还有第二种标识符:分隔标识符或   引用标识符。它是通过包围任意序列形成的   双引号(“)中的字符。分隔标识符始终是   标识符,永远不是关键字。所以“select”可以用来指代a   名为“select”的列或表,而未加引号的选择将是   作为关键词,因此会引发解析错误   用于需要表名或列名的地方。

答案 1 :(得分:0)

如果您未在任何字段/列中提供引号,则默认情况下,Postgres将使用小写字母。当涉及到列名时,Postgres将跳过检查关键字。

对于您而言,我认为在columns上添加引号不是强制性的。 但是,如果您使用keywords(由Postgres注册)作为TableSchemaFunctionTrigger等的名称,则必须使用用双引号引起来,或者您可以使用点串联来指定架构名称。

让我们假设 order 是Postgres注册的关键字。在某些情况下,您必须使用此关键字作为表名。

那时,Postgres将允许您使用keywords创建一个表。那就是Postgres的美丽。

要访问订单表,要么必须使用双引号,要么可以在表名之前使用架构名称。

E.G。

1。

select * from schema_name.order;

2。

select * from "order";

同样,您可以使用这种类型的组合。希望对您有帮助。

答案 2 :(得分:-1)

为了安全起见,您必须使用带分隔符的标识符来构建插入语句。

SQL 2003指定分隔的标识符应用双引号@{Id=1, Count=24 Name="Some name"} etc 引起来,并且如果标识符中出现双引号,则必须重复双引号。参见BNF:

https://ronsavage.github.io/SQL/sql-2003-2.bnf.html#delimited%20identifier

这是引用标识符的代码:

"

这是构建插入的代码:

static String delimited_identifier (String identifier)
{
  return "\"" + identifier.replaceAll ("\"", "\"\"") + "\"";
}

示例:

static String build_insert (String table, String[] columns)
{
  StringBuilder sql = new StringBuilder ();
  StringBuilder values = new StringBuilder ();

  sql.append ("INSERT INTO ");
  sql.append (delimited_identifier (table));
  sql.append (" (");
  int c = 0;
  if (columns.length > 0) {
    sql.append (delimited_identifier (columns[c]));
    values.append ("?");
  }
  for (++c; c < columns.length; c++) {
    sql.append (", ");
    sql.append (delimited_identifier (columns[c]));
    values.append (", ?");
  }
  sql.append (") VALUES (");
  sql.append (values.toString ());
  sql.append (")");

  return sql.toString ();
}