首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用plpgsql函数时语法错误

调用plpgsql函数时语法错误
EN

Stack Overflow用户
提问于 2016-03-22 16:56:20
回答 2查看 853关注 0票数 0

我正在做一个项目,其中包括计算产业集群成本结构中来自区域内运输成本的百分比。我将为每个行业集群提供一个表,其中包含详细的成本细目(naics、want、inregion_amt)、包含所有运输naics的查找表transpo_industries和最终包含每个行业集群名称(c_name)、总成本(tot_cost)和区域内运输成本(inregion_transpo)的汇总表cluster_costs。表中已经填充了所有行业名称,这些名称与相应的产业集群的表名相匹配。

由于我需要运行至少15个产业集群,并且可能希望用较小的数据子集重新运行这段代码,所以我正在尝试创建一个函数。下面的代码创建了没有错误的函数,但是当我试图调用它时,我会得到一个语法错误(“错误:语法错误在或接近”集群成本“SQL state: 42601")

有人能帮我指出我哪里错了吗?

代码语言:javascript
运行
复制
create or replace function clustercosts(tblname text) RETURNS void
AS $$
BEGIN
EXECUTE 'update cluster_costs set tot_cost= (select sum(amount) from '||tblname||'), inregion_transpo = (select sum(inregion_amt) from '||tblname||', transpo_industries where '||tblname||'.naics=transpo_industries.naics) where c_name='||tblname||;
END;
$$ Language plpgsql;

使用format()的版本给出了同样的错误:

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION udate_clustercosts(tblname text)
  RETURNS void AS
$BODY$
BEGIN
EXECUTE format(
'update cluster_costs'
'set tot_cost= (select sum(amount)from %I),'
'inregion_transpo = (select sum(inregion_amt) from %I, transpo_industries where %I.naics=transpo_industries.naics)'
'where c_name=%I',tblname);
END;
$BODY$
  LANGUAGE plpgsql;
EN

回答 2

Stack Overflow用户

发布于 2016-03-24 04:41:56

你的问题从设计阶段开始。有了正确的DB设计,首先您就不需要动态SQL了。

每个产业集群我要一张桌子..。

不要。这应该是一个单独的表(如cluster_details),其中包含一个FK列(如cluster_id),引用表中列出的产业集群的PK (如industry_cluster)。

使用UPDATE实现计算聚合也是值得怀疑的。使用VIEW (或函数)来获取当前和。您的基本查询将类似于:

代码语言:javascript
运行
复制
SELECT ic.*
     , sum(cd.amount) AS sum_amount
     , (SELECT sum(inregion_amt)
        FROM   transpo_industries
        WHERE  naics = cd.naics) AS sum_inregion_amt
FROM   industry_cluster ic
LEFT   JOIN cluster_details cd USING (cluster_id)
WHERE  ic.name = 'Cluster 1';

至于所问的问题:由于错误是由函数调用触发的,并且错误消息清楚地引用了函数的名称,所以问题在于调用,这在问题中是缺失的。

在您的函数定义中还有其他问题,正如注释中所指出的--这些问题都与您提供的错误消息无关。

票数 1
EN

Stack Overflow用户

发布于 2016-03-22 20:15:35

你被这样的事实咬了,你想在引号中使用单引号。您可以使用如文档所解释的那样,美元引号字符串常量。避免这种情况。

出现此问题是因为您希望在SQL语句中使用单引号,因为您希望将tblname的值作为字符串常量传递。

在这里,我使用$a$在函数体中引用,用$$引用

代码语言:javascript
运行
复制
create or replace function clustercosts(tblname text) RETURNS void
AS $$
BEGIN
EXECUTE $a$ update cluster_costs set tot_cost= (select sum(amount) from $a$ || tblname || $a$), inregion_transpo = (select sum(inregion_amt) from $a$ || tblname || $a$, transpo_industries where $a$ || tblname || $a$.naics=transpo_industries.naics) where cluster_costs.c_name='$a$ || tblname || $a$'$a$;
END;
$$ language plpgsql;

在美元符号之间插入几乎任何标识符都是有效的,并且是函数嵌套引号的常见模式,与您的情况完全一样。

示例

我创建了您描述的表格:

代码语言:javascript
运行
复制
create table tblname (naics int, amount int, inregion_amt int);
create table transpo_industries (naics int);
create table cluster_costs (c_name text, tot_cost int, inregion_transpo int);

testdb=> SELECT clustercosts('tblname');
 clustercosts 
--------------

(1 row)

没有错误,SQL执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36160601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档