【问题标题】:Dynamic queries with format() using the same argument many times多次使用相同参数的 format() 动态查询
【发布时间】:2017-01-14 15:03:01
【问题描述】:

我有一个程序将表名的后缀作为输入。然后,使用执行格式(),我传递这个参数来执行动态查询。问题是这个参数在整个过程中都是相同的——我不想像这样传递它 x 次:

execute format('SELECT table_%s.field1, table_%s.field2,table_%s.field3
FROM table_%s', inTableSuffix, inTableSuffix, inTableSuffix, inTableSuffix, ...) 

我想要类似于以下的格式:

execute format('SELECT table_%s.field1, table_%s.field2,table_%s.field3
FROM table_%s', inTableSuffix) 

我知道我可以使用表名的别名来解决这个问题,但是还有其他选择吗?

【问题讨论】:

  • 那么你有答案了吗?

标签: sql database postgresql plpgsql dynamic-sql


【解决方案1】:

您可以重复这样处理位置参数:


execute format('SELECT table_%1$s.field1
   , table_%1$s.field2,table_%1$s.field3
FROM table_%1$s;', inTableSuffix); 

注意:在这种特殊情况下,您可以通过使用别名来避免重复自己:


execute format('SELECT tx.field1
   , tx.field2, tx.field3
FROM table_%s tx;', inTableSuffix); 

【讨论】:

  • 另外,如果没有join的话,每列都不需要使用表名,但是即使有join,也可以使用表的别名,所以不需要连接多个乘以完整的表名。
【解决方案2】:

@wildplasser already provided the syntax如何在format()中重复引用同一个参数。不过,该代码仍然很危险。您需要转义根据用户输入构建的标识符:

EXECUTE format('SELECT field1, field2, field3 FROM %I', 'table_' || inTableSuffix);

对于给定的示例,无论如何您只需要一次参数。在 plpgsql 中使用EXECUTE 执行的动态查询的范围仅限于查询本身。函数的其他变量或参数在EXECUTE可见。因此,不需要在 FROM 子句中使用单个表对动态查询中的列进行表限定。

但更重要的是,%I is used in format() 用于标识符以避免语法错误、错误的小写或更糟糕的 SQL 注入!它用双引号(仅限!)否则为非法标识符,just like quote_ident() would

详情:

【讨论】:

  • @wildplasser:你似乎想念我已经这样做了。不需要(更昂贵的)变量,您可以将连接的表达式作为参数传递。另外:它是quote_ident(),而不是quote_identifier()
  • 糟糕,我没看到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
相关资源
最近更新 更多