【问题标题】:how to convert string as sql syntax如何将字符串转换为sql语法
【发布时间】:2020-08-19 20:09:54
【问题描述】:

我正在尝试做的一个例子,

SELECT  count(*) as "count" 
FROM (
   SELECT overlay('db_xx.company_summary' placing 'US' from 4)
) as s

这将返回计数为 1,我希望它计算 db_us.company_summary 1*10^6 中的所有行

我希望这会产生与此类似的查询;

SELECT  count(*) as "count" 
FROM (db_us.company_summary')

我尝试了覆盖功能,类似于上面的查询。我不确定是否可以在 SQL 中执行此操作。

通常在python中你会做这样的事情;

"hello {}".format("world")

所以我希望输入的字符串充当 SQL 语法命令。

【问题讨论】:

  • 我删除了不一致的数据库标签。请仅使用您真正使用的数据库进行标记。
  • 通常您的 RDBMS 可能支持动态 SQL,您可以使用它从字符串执行查询(因此您可以使用您想要的任何替换来构建查询字符串并将其传递给执行)
  • 我明白这一点,但我就是不知道怎么做。我是否在问一个使用简单 SQL 函数无法解决的问题?我不确定。
  • select overlay('db_xx.company_summary' ..) 返回具有单个字符串值的单行。你为什么期望它返回任何其他东西? dbfiddle.uk/…
  • 我只是在画我想做的事。显然它不会翻译。

标签: postgresql


【解决方案1】:

普通 SQL 不允许参数化标识符(或 任何东西,但值)。您需要动态 SQL。例子:

类似这样的:

最小的测试设置(应该在问题中):

CREATE TABLE country_code (iso2 text PRIMARY KEY);
INSERT INTO country_code VALUES ('US'), ('GB'), ('AT');
CREATE SCHEMA db_us;
CREATE SCHEMA db_gb;
CREATE SCHEMA db_at;
CREATE TABLE db_us.company_summary (foo int);
CREATE TABLE db_gb.company_summary (foo int);
CREATE TABLE db_at.company_summary (foo int);
INSERT INTO db_us.company_summary VALUES (1), (2);
INSERT INTO db_gb.company_summary VALUES (1), (2), (3);
INSERT INTO db_at.company_summary VALUES (1), (2), (3), (4);

带有动态 SQL 的 PL/pgSQL 函数:

CREATE OR REPLACE FUNCTION f_counts()
  RETURNS SETOF bigint
  LANGUAGE plpgsql AS
$func$
DECLARE
   _lower_iso2 text;
   _ct bigint;
BEGIN
   FOR _lower_iso2 IN
      SELECT lower(iso2) FROM country_code
   LOOP
      RETURN QUERY EXECUTE
      format ('SELECT count(*) AS count FROM %I.company_summary'
             , overlay('db_xx' PLACING _lower_iso2 FROM 4)
             );
   END LOOP;
END
$func$;

呼叫:

SELECT * FROM f_counts();

结果:

f_counts
---------
2
3
4

db小提琴here

请注意 Postgres 标识符区分大小写。见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    相关资源
    最近更新 更多