将同一变量传递到 SQL 语句的多个部分时出错
Error with passing in the same variable into multiple parts of SQL statement
所以我有一个 Node.js 查询,它应该传入这三个值,并为具有特定 ID 的用户按特定数量更新特定列:
await client.query(sqlStatement, [columnName, changeBy, id])
'sqlStatement' 看起来像:
'UPDATE tableName SET () = () + () WHERE id = ()'
如您所见,它应该传递值,使 SQL 语句看起来像:
'UPDATE tableName SET columnName = columnName + changeBy WHERE id = id'
我也试过如下编写 sqlStatement(只将 columnName 传入查询两次,但这也会导致错误:
'UPDATE tableName SET () = () + () WHERE id = ()'
返回的错误是错误:“$1”处或附近的语法错误。
不确定如何解决此问题 - 非常感谢任何帮助。
发生这种情况的原因是 node-postgres
doesn't support query parameters for identifiers 和 SET
之后的列名称是一个标识符。此外,即使这可行,除非 node-postgres
以某种方式用整个 ()
(带括号)代替你的价值,你会得到
ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
.
如果您希望保留 node-postgres
,它的 documentation recommends to use pg-format in such cases, to build a dynamic SQL statement. If you consider alternatives, you can look into Knex.js 将为您构建查询,如下所示:
knex('tableName')
.update({
columnName: knex.raw('?? + ?',['columnName',changeBy])
})
.where('id', id)
同时,作为一种解决方法,您应该能够将 sqlStatement
设置为您自己的动态 SQL 查询:
do language plpgsql $$ begin execute format('UPDATE test SET %I = %I + %s WHERE id = %s','','',,); end$$;
然后尝试一下。请注意,我删除了更新列周围的括号以避免多列更新错误。应该发生的是 node-postgres
将以上计算为
do language plpgsql $$ begin execute format('UPDATE test SET %I = %I + %s WHERE id = %s','col','col',51,72); end$$;
并将其传递给 PostgreSQL,后者应将其执行为
UPDATE test SET "col" = "col" + 51 WHERE id = 72;
来自doc:
%I
用于 I 标识符,如果需要,PostgreSQL 将自动引用。
%L
用于字符串 Literals
%s
用于 simple string 替换,在某种意义上它不会被引用,所以它可用于数字文字
所以我有一个 Node.js 查询,它应该传入这三个值,并为具有特定 ID 的用户按特定数量更新特定列:
await client.query(sqlStatement, [columnName, changeBy, id])
'sqlStatement' 看起来像:
'UPDATE tableName SET () = () + () WHERE id = ()'
如您所见,它应该传递值,使 SQL 语句看起来像:
'UPDATE tableName SET columnName = columnName + changeBy WHERE id = id'
我也试过如下编写 sqlStatement(只将 columnName 传入查询两次,但这也会导致错误:
'UPDATE tableName SET () = () + () WHERE id = ()'
返回的错误是错误:“$1”处或附近的语法错误。
不确定如何解决此问题 - 非常感谢任何帮助。
发生这种情况的原因是 node-postgres
doesn't support query parameters for identifiers 和 SET
之后的列名称是一个标识符。此外,即使这可行,除非 node-postgres
以某种方式用整个 ()
(带括号)代替你的价值,你会得到
ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
.
如果您希望保留 node-postgres
,它的 documentation recommends to use pg-format in such cases, to build a dynamic SQL statement. If you consider alternatives, you can look into Knex.js 将为您构建查询,如下所示:
knex('tableName')
.update({
columnName: knex.raw('?? + ?',['columnName',changeBy])
})
.where('id', id)
同时,作为一种解决方法,您应该能够将 sqlStatement
设置为您自己的动态 SQL 查询:
do language plpgsql $$ begin execute format('UPDATE test SET %I = %I + %s WHERE id = %s','','',,); end$$;
然后尝试一下。请注意,我删除了更新列周围的括号以避免多列更新错误。应该发生的是 node-postgres
将以上计算为
do language plpgsql $$ begin execute format('UPDATE test SET %I = %I + %s WHERE id = %s','col','col',51,72); end$$;
并将其传递给 PostgreSQL,后者应将其执行为
UPDATE test SET "col" = "col" + 51 WHERE id = 72;
来自doc:
%I
用于 I 标识符,如果需要,PostgreSQL 将自动引用。%L
用于字符串 Literals%s
用于 simple string 替换,在某种意义上它不会被引用,所以它可用于数字文字