首页 > 解决方案 > Postgresql:减号运算符不能与参数一起使用吗?只有硬编码的值?

问题描述

以下查询使用索引删除条目:

 const deleteGameQuery = ` 
                update users 
                set games = games - 1
                where username = $1
            `

如果我将索引作为参数传递,则不会删除任何内容:

const gameIndex = rowsCopy[0].games.findIndex(obj => obj.game == gameID).toString();


            const deleteGameQuery = ` 
                update users 
                set games = games - $1
                where username = $2
            `
    
          const { rows } = await query(deleteGameQuery, [gameIndex, username]);

          ctx.body = rows;

gameIndex 参数只是一个字符串,就像我键入它一样。那么为什么它似乎没有读取值呢?这是不允许的吗?

列games是一个jsonb数据类型,数据如下:

[
    {
        "game": "cyberpunk-2077",
        "status": "Backlog",
        "platform": "Any"
    },
    {
        "game": "new-pokemon-snap",
        "status": "Backlog",
        "platform": "Any"
    }
]

标签: postgresqlparametersnode-postgres

解决方案


问题是您传递的是文本而不是整数。您需要传递一个整数。我不确定您的数据库接口如何传递整数,请尝试删除toString()并确保gameIndexNumber

const gameIndex = rowsCopy[0].games.findIndex(obj => obj.game == gameID).


array - integer并且array - text意味着两个不同的东西。

array - 1从数组中删除第二个元素。

select '[1,2,3]'::jsonb - 1;

 [1, 3]

array - '1'搜索条目'1'并将其删除。

select '["1","2","3"]'::jsonb - '1';

 ["2", "3"]

-- Here, nothing is removed because 1 != '1'.
select '[1,2,3]'::jsonb - '1';

 [1, 2, 3]

当你传入一个参数时,它会query根据它的类型进行翻译。如果您传递一个数字,它将被翻译为1. 如果您传递一个字符串,它将被翻译为'1'. (或者至少它应该是这样工作的,我对 Javascript 数据库库并不完全熟悉。)


附带说明一下,这种数据最好作为连接表处理。

create table games (
  id bigserial primary key,
  name text not null,
  status text not null,
  platform text not null
);

create table users (
  id bigserial primary key,
  username text not null
);

create table game_users (
  game_id bigint not null references games,
  user_id bigint not null references users,

  -- If a user can only have each game once.
  unique(game_id, user_id)
);

-- User 1 has games 1 and 2. User 2 has game 2.
insert into game_users (game_id, user_id) values (1, 1), (2, 1), (2,2);

-- User 1 no longer has game 1.
delete from game_users where game_id = 1 and user_id = 1;

您还将有一个平台表和一个 game_platforms 连接表。

连接表有点让人费解,但它们是 SQL 存储关系的方式。JSONB 非常有用,但它不能替代关系。


推荐阅读