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

时间:2013-11-13 20:35:32

标签: node.js postgresql sql-update operators postgresql-9.1

给出以下架构(作为示例)

CREATE TABLE "test" (
  "id" int, 
  "title" varchar
);
在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){ ... }
);

它给了我以下错误:'错误:运算符不存在:integer = text'

好的,让我们尝试停止使用"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){ ... }
);

仍然'错误:运算符不存在:integer = text'

好的,现在让我们添加另一个$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){ ... }
);

另一个错误:'错误:列“id”的类型为整数,但表达式的类型为text'

我完全迷失了。为什么不在WHERE中使用int运算符类?这有什么不对?

奇怪的是,没有UPDATE子句的标准WITH表单工作正常......

如果您需要使用代码:https://gist.github.com/kolypto/7455957

1 个答案:

答案 0 :(得分:2)

在此背景下:

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

PostgreSQL不知道$1$2将是什么类型,因此它们最终会被视为文本值。 fine manual notes this

  

VALUES中使用INSERT时,所有值都会自动强制转换为相应目标列的数据类型。当它在其他环境中使用时,可能需要指定正确的数据类型。

并且在values($1, $2)中,无法推断出类型,因此您必须明确:

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

$2上的演员阵容是不必要的,但我希望保持一致。