简体   繁体   English

PostgreSQL 9.1中的UPDATE似乎滥用了占位符类型

[英]UPDATE in PostgreSQL 9.1 seems to misuse placeholder types

Given the following schema (as an example) 给定以下架构(作为示例)

CREATE TABLE "test" (
  "id" int, 
  "title" varchar
);

in NodeJS, I try to do an UPDATE with the following 在NodeJS中,我尝试使用以下命令进行更新

client.query(
            'WITH new_vals ("id","title") AS (VALUES($1,$2)) ' +
            'UPDATE "test" "t" SET "id"=nv.id, "title"=nv.title ' +
            'FROM new_vals nv ' +
            'WHERE "t"."id"=nv.id;',
        [1,'test'],
        function(err, res){ ... }
);

And it gives me the following error: 'error: operator does not exist: integer = text' 它给了我以下错误: '错误:运算符不存在:整数=文本'

Ok, let's try to stop using "t"."id"=nv.id and just reuse one the available parameters: 好的,让我们尝试停止使用"t"."id"=nv.id而仅重用一个可用参数:

client.query(
            'WITH new_vals ("id","title") AS (VALUES($1,$2)) ' +
            'UPDATE "test" "t" SET "id"=nv.id, "title"=nv.title ' +
            'FROM new_vals nv ' +
            'WHERE "t"."id"=$1;',
        [1,'test'],
        function(err, res){ ... }
);

Still 'error: operator does not exist: integer = text' . 仍然是“错误:运算符不存在:integer = text”

Ok, now let's add another $3 placeholder: 好的,现在让我们添加另一个$3占位符:

client.query(
            'WITH new_vals ("id","title") AS (VALUES($1,$2)) ' +
            'UPDATE "test" "t" SET "id"=nv.id, "title"=nv.title ' +
            'FROM new_vals nv ' +
            'WHERE "t"."id"=$3;',
        [1,'test',1],
        function(err, res){ ... }
);

Another error: 'error: column "id" is of type integer but expression is of type text' 另一个错误: “错误:列“ id”的类型为整数,但表达式的类型为文本”

I'm completely lost. 我完全迷路了。 Why doesn't it use the int operator classes in WHERE? 它为什么不在WHERE中使用int运算符类? What's wrong here? 怎么了

Strangely, the standard UPDATE form without the WITH clause works fine... 奇怪的是,不带WITH子句的标准UPDATE表单可以正常工作...

In case you need the code to play with: https://gist.github.com/kolypto/7455957 如果您需要使用以下代码: https : //gist.github.com/kolypto/7455957

In this context: 在这种情况下:

WITH new_vals ("id","title") AS (VALUES($1,$2))

PostgreSQL has no idea what type $1 or $2 are going to be so they will end up being treated as text values. PostgreSQL不知道$1$2是什么类型,因此它们最终将被视为文本值。 The fine manual notes this : 精美的手册指出

When VALUES is used in INSERT , the values are all automatically coerced to the data type of the corresponding destination column. INSERT使用VALUES ,所有值都将自动强制转换为相应目标列的数据类型。 When it's used in other contexts, it might be necessary to specify the correct data type. 在其他上下文中使用它时,可能有必要指定正确的数据类型。

and in values($1, $2) , the types cannot be inferred so you have to be explicit: 并且在values($1, $2) ,无法推断类型,因此必须明确:

WITH new_vals ("id", "title") AS (VALUES($1::integer, $2::text))

The cast on $2 isn't necessary but I like to be consistent. 不必对$2进行强制转换,但我希望保持一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM