我有一个用户定义的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'\', \''这样的事情?

推荐答案

使用format(),就像已经指示的Richard一样.这不仅可读性更好,而且还修复了原始版本中明显的SQL注入问题.

更重要的是,根本不要把values连在一起.将它们作为值与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?

可以肯定的是,使用模式限定的表名--不能像上面的代码那样作为单个标识符传递.架构和表名称必须分别用引号引起来.请参见:

一定要理解并使用dollar-quoting:

Postgresql相关问答推荐

Postgs SQL用于比较两个表之间的数据并填充到目标中

为什么32632投影中的几何图形并不完美?

使用postgres在go测试容器中使用tern迁移

使用doobie,如何将Scala case类映射到带有类型tstzmultirange的PostgreSQL列?

为什么不能超过 10 个并发连接到 Postgres RDS 数据库

查找列中的数据是否满足sql中的数据类型条件

我可以在 Ruby on Rails 上编写 PostgreSQL 函数吗?

Heroku Rails 4 无法连接到服务器:connection refused

当脚本工作时,Postgres now() 时间戳不会改变

使用 ON CONFLICT 从 INSERT 返回行,无需更新

Nodemon - 安装期间clean exit - waiting for changes before restart

无法向 postgresql 数据库授予用户权限(对于 rails 应用程序)

需要将整个 postgreSQL 数据库加载到 RAM 中

如何在构建时链接 docker 容器?

如何在 PostgreSQL 触发器函数中获取表名?

Rails 4查询由单个属性唯一

PostgreSQL:使用 psql 命令行实用程序时 Windows 上的编码问题

如何为查询执行设置语句超时

PostGIS - 将多面体转换为单面体

如何使用 sql 或 phpPgAdmin 更改 PostgreSQL 数据库的数据库编码?