【问题标题】:How to evaluate expression in select statement in Postgres如何在 Postgres 的 select 语句中计算表达式
【发布时间】:2016-04-30 16:49:15
【问题描述】:

Postgres 9.1+ 数据库包含客户和产品。 在customers表中,客户价格被描述为每个客户的priceexpression列中的sql表达式。

如何根据这些数据创建价目表? 我尝试了下面的代码,但由于 eval() 未定义而出错。

create table customer
( id int primary key,
  priceexpression text );
insert into customer values (1, 'price*0.95'),(2,'cost+12.0' );

create table product
( id char(20) primary key,
   price numeric(12,4),
   cost numeric(12,4) );
insert into product values ('PRODUCT1', 120, 80),('PRODUCT2', 310.5, 290);


select
  customer.id as customer,
  product.id as product,
  eval(priceexpression) as price
 from customer,product

这是 ASP.NET MVC4 应用程序。

【问题讨论】:

    标签: sql postgresql asp.net-mvc-4 eval plpgsql


    【解决方案1】:

    您可以编写一个 SQL 函数来为您执行此操作并使用例如postgres-utils 提供的那些:

    select 
      c.name as cust_name,
      p.name as prod_name,
      p.cost as prod_cost,
    
      eval(  
        'select '||c.price_expression||' from product where id=:pid',
        '{"{cost}",:pid}',  
        array[ p.cost, p.id ]  
      )      as cust_cost
    
    from product p,  customer c
    

    但当然它可能很慢、不安全,您可以使用物化视图更轻松地对其进行缓存等 - 请参阅那里的文档。

    【讨论】:

    • 谢谢。伟大的。我将其标记为答案并投了赞成票。
    • 我试过但出错了。我把它贴在stackoverflow.com/questions/36939625/…
    • 我已针对您的问题更新了我的答案(我实际上并没有用您的示例亲自尝试过!)...您只需添加所有必要的参数和表格对于您的特定“dyna-sql”(product:cid)。 最好在您的数据中使用:cost而不是{cost},因为它更方便、更易于理解并且不与数组语法冲突。
    • 啊……不能再编辑最后一条评论了:-/……当然必须是:pid(而不是:cid
    • 您可以删除评论并重新输入。在运行时将列添加到客户和产品表中,并且还在运行时创建表达式。如何在不使用硬编码参数的情况下将所有列自动传递给 eval? plpgsql有行类型,也许这个可以用
    【解决方案2】:

    您不能在 PostgreSQL 中使用纯 SQL 来做到这一点。

    您需要将动态 SQL 与 PL/PgSQL 的 EXECUTE 语句一起使用。请参阅 PL/PgSQL 以及 Stack Overflow 上的许多示例。

    遍历结果集并为每一行循环EXECUTE 'SELECT '||the_expression INTO resultvar;

    请注意,如果未经证实可以运行原始 SQL 的任何人都可能修改价格列,则这是一个巨大的安全漏洞。你真的不应该这样做。

    【讨论】:

    • 根据接受的答案,它可能是可行的。我在stackoverflow.com/questions/36939625/… 中发布了相关问题
    • 嗯,是的。您正在使用 PL/PgSQ 和 EXECUTE。正如我上面建议的那样。
    猜你喜欢
    • 2013-04-25
    • 2016-12-19
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    相关资源
    最近更新 更多