【问题标题】:postgresql function query execute using parameter for ANY clause - get error - query string argument of EXECUTE is null使用 ANY 子句的参数执行 postgresql 函数查询 - 获取错误 - EXECUTE 的查询字符串参数为空
【发布时间】:2020-09-26 14:00:47
【问题描述】:

PostgreSQL 11.4,由 Visual C++ build 1914 编译,64 位

在 Stackoverflow 中审阅了几十篇文章,没有真正的匹配。需要:传递一个逗号分隔的字符串(id 值),并将该列表与“ANY”postgresql 子句一起使用。

代码

return query execute 
  'select aa.id, aa.course_id, aa.comments, aa.curr_cont_t_id, aa.date_done, ' || 
    'aa.unit_id, aa.time_seq, aa.week_num, bb.module_id, bb.expected_hrs, ' || 
    'bb.title unit_title, cc.module_name, cc.tally_hours, cc.time_of_day, ' || 
    'bb.file_upload_expected, aa.app_files_id, xx.facility_id ' ||
  'from course_content aa ' || 
    'left outer join units bb on aa.unit_id = bb.id ' || 
    'left outer join module_categories cc on bb.module_id = cc.id ' || 
    'left outer join courses xx on aa.course_id = xx.id ' || 
  'where xx.facility_id = any(''{' || $1 || '}'') '
using p_facilities;

我检查了 p_facilities 以确保它不为空或为空。我什至专门将 p_facilities 设置为函数内部的一个值,如下所示:

p_facilities text = '3';

返回的错误是一致的:'EXECUTE 的查询字符串参数为空(SQL 状态 22004)'

【问题讨论】:

  • 你为什么要使用动态 SQL?只需return (select … where xx.facility_id = any(string_to_array(p_facilities, ',')));

标签: postgresql function parameter-passing


【解决方案1】:

问题是您没有在查询中的任何位置引用using 参数。相反,您将$1 直接连接到您的查询中,而这个$1 指的是您所在的pl/pgsql 函数的第一个参数(显然是NULL)。

要使用dynamically executed sql 中的参数并将它们传递给using,您需要将文本$1 硬编码到查询字符串中:

EXECUTE 'SELECT … WHERE xx.facility_id = any($1)' USING some_array;

要在查询中插入字符串,不需要任何using 子句,直接引用字符串即可:

EXECUTE 'SELECT … WHERE xx.facility_id = any(''{' || p_facilities || '}'')';

但是,请注意,您根本不需要(也不应该使用)动态 sql。您正在构建一个值,而不是 sql 结构。您可以直接在普通查询中引用它:

SELECT … WHERE xx.facility_id = any( ('{' || p_facilities || '}')::int[] );
-- or better
SELECT … WHERE xx.facility_id = any( string_to_array(p_facilities, ',')::int[] );

【讨论】:

  • 谢谢。在使用字符串时,我总是有点担心 SQL 注入,所以我走错了路。我看到 string_to_array() 应该防止任何 SQL 注入。在其他查询中,我有几个在查询中使用的参数(例如 this = $1 和 that = $2...)。但我认为你向我展示了如何将所有这些结合在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多