提问人:Capacytron 提问时间:11/8/2023 最后编辑:Erwin BrandstetterCapacytron 更新时间:11/9/2023 访问量:53
使动态 INSERT inside 函数更具可读性
Make dynamic INSERT inside function more readable
问:
我有一个用户定义的Postgres函数,该函数执行动态。代码是不可读的,并且由于字符串转义而很难修改它。有没有办法让它看起来更好?INSERT
这是我的代码,为简洁起见省略了一些部分:
BEGIN
-- some code
-- escape nightmare for teammates goes here
EXECUTE 'INSERT INTO ' || _table || E'(col1, col2, col3) VALUES (\'' || _col1 ||
E'\', \'' || _col2 || E'\''|| E', \'' || _col3::text ||E'\') ON CONFLICT DO NOTHING RETURNING code' INTO _code;
-- more code
END
有没有办法简化这样的事情?E'\', \''
答:
0赞
gbjbaanb
11/8/2023
#1
我所做的是添加注释 - 特别是生成的查询是什么样子的。你不能改变代码的工作方式,也不应该经常这样做,当有人知道最终结果时,你会更容易理解代码是如何构建它的。
评论
0赞
Capacytron
11/8/2023
感谢您的建议,它被一堆单元测试所覆盖。很清楚它的作用,但由于转义样板,很难修改它。
1赞
Richard Huxton
11/8/2023
#2
使用格式
format('INSERT INTO %I (col1,col2,col3) VALUES (%L,%L,%L)', _table, _col1, _col2, _col3);
评论
0赞
Capacytron
11/8/2023
我在使用格式和 %L 时遇到转义字符串的问题,我已经更新了问题。
2赞
Erwin Brandstetter
11/8/2023
#3
使用 format(),
就像 Richard 已经指示的那样。这不仅更具可读性,而且还修复了原始版本中明显的 SQL 注入问题。
更重要的是,根本不连接值。使用子句将它们作为值传递:USING
EXECUTE format(
'INSERT INTO %I (col1,col2,col3) VALUES ($1,$2,$3)
ON CONFLICT DO NOTHING
RETURNING code', _table)
INTO _code
USING _col1, _col2, _col3::text; -- do you need to cast?
可以肯定的是,请使用架构限定的表名 - 它不能像上面的代码那样作为单个标识符传递。架构和表名必须分开引用。看:
请务必理解并使用美元报价:
评论