热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用存储过程在LEFTOUTERJOIN中返回SETOF记录-UsingstoredprocedurereturningSETOFrecordinLEFTOUTERJOIN

Imtryingtocallastoredprocedurepassingparametersinaleftouterjoinlikethis:我正在尝试调用存储过程

I'm trying to call a stored procedure passing parameters in a left outer join like this:

我正在尝试调用存储过程在左外连接中传递参数,如下所示:

select i.name,sp.*
from items i
left join compute_prices(i.id,current_date) as sp(price numeric(15,2), 
          discount numeric(5,2), taxes numeric(5,2)) on 1=1
where i.type = 404;

compute_prices() returns a setof record.
This is the message postgres shows:

compute_prices()返回一组setof记录。这是postgres显示的消息:

ERROR: invalid reference to FROM-clause entry for table "i"

错误:对表“i”的FROM子句条目的无效引用

...left join compute_prices(i.id,current_date)...

...左连接compute_prices(i.id,current_date)...

HINT: There is an entry for table "i", but it cannot be referenced from this part of the query.

提示:表“i”有一个条目,但不能从查询的这一部分引用它。

This kind of query works in Firebird. Is there a way I could make it work by just using a query? I don't want to create another stored procedure that cycles through items and makes separate calls to compute_prices().

这种查询适用于Firebird。有没有办法可以通过使用查询使其工作?我不想创建另一个循环遍历项目的存储过程,并单独调用compute_prices()。

3 个解决方案

#1


5  

Generally, you can expand well known row types (a.k.a. record type, complex type, composite type) with the simple syntax @Daniel supplied:

通常,您可以使用提供的简单语法@Daniel扩展众所周知的行类型(a.k.a。记录类型,复杂类型,复合类型):

SELECT i.name, (compute_prices(i.id, current_date)).*
FROM   items i
WHERE  i.type = 404;

However, if your description is accurate ...

但是,如果您的描述准确无误......

The compute_prices sp returns a setof record.

compute_prices sp返回一组记录。

... we are dealing with anonymous records. Postgres does not know how to expand anonymous records and throws an EXCEPTION in despair:

......我们正在处理匿名记录。 Postgres不知道如何扩展匿名记录并在绝望中抛出一个EXCEPTION:

ERROR:  a column definition list is required for functions returning "record"

PostgreSQL 9.3

There is a solution for that in Postgres 9.3. LATERAL, as mentioned by @a_horse in the comments:

Postgres 9.3中有一个解决方案。正如@a_horse在评论中提到的那样:LATERAL:

SELECT i.name, sp.*
FROM   items i
LEFT   JOIN LATERAL compute_prices(i.id,current_date) AS sp (
                       price    numeric(15,2)
                      ,discount numeric(5,2)
                      ,taxes    numeric(5,2)
                      ) ON TRUE
WHERE i.type = 404;

Details in the manual.

手册中的详细信息。

PostgreSQL 9.2 and earlier

Things get hairy. Here's a workaround: write a wrapper function that converts your anonymous records into a well known type:

事情变得多毛了。这是一个解决方法:编写一个包装函数,将您的匿名记录转换为众所周知的类型:

CREATE OR REPLACE FUNCTION compute_prices_wrapper(int, date)
  RETURNS TABLE (
            price    numeric(15,2)
           ,discount numeric(5,2)
           ,taxes    numeric(5,2)
          ) AS
$func$
    SELECT * FROM compute_prices($1, $2)
    AS t(price    numeric(15,2)
        ,discount numeric(5,2)
        ,taxes    numeric(5,2));
$func$ LANGUAGE sql;

Then you can use the simple solution by @Daniel and just drop in the wrapper function:

然后你可以使用@Daniel的简单解决方案,只需输入包装函数:

SELECT i.name, (compute_prices_wrapper(i.id, current_date)).*
FROM   items i
WHERE  i.type = 404;

PostgreSQL 8.3 and earlier

PostgreSQL 8.3 has just reached EOL and is unsupported as of now (Feb. 2013).
So you'd better upgrade if at all possible. But if you can't:

PostgreSQL 8.3刚刚达到EOL,截至目前(2013年2月)尚未得到支持。因此,如果可能的话,你最好升级。但如果你不能:

CREATE OR REPLACE FUNCTION compute_prices_wrapper(int, date
           ,OUT price    numeric(15,2)
           ,OUT discount numeric(5,2)
           ,OUT taxes    numeric(5,2))
  RETURNS SETOF record AS
$func$
    SELECT * FROM compute_prices($1, $2)
    AS t(price    numeric(15,2)
        ,discount numeric(5,2)
        ,taxes    numeric(5,2));
$func$ LANGUAGE sql;

Works in later versions, too.

也适用于更高版本。

The proper solution would be to fix your function compute_prices() to return a well know type to begin with. Functions returning SETOF record are generally a PITA. I only poke those with a five-meter-pole.

正确的解决方案是修复函数​​compute_prices()以返回一个众所周知的类型。返回SETOF记录的函数通常是PITA。我只戳那些五米高的杆子。

#2


3  

Assuming the compute_prices function always return a record with 3 prices, you could make its return type to TABLE (price numeric(15,2), discount numeric(5,2),taxes numeric(5,2)), and then I believe what you want could be expressed as:

假设compute_prices函数总是返回一个有3个价格的记录,你可以将它的返回类型设为TABLE(价格数字(15,2),折扣数字(5,2),税数字(5,2)),然后我相信你想要什么可以表达为:

SELECT i.name, (compute_prices(i.id,current_date)).*
  FROM items i
WHERE i.type=404;

Note that its seems to me that LEFT JOIN ON 1=1 does not differ from an unconstrained normal JOIN (or CROSS JOIN), and I interpreted the question as actually unrelated to the left join.

请注意,在我看来,LEFT JOIN ON 1 = 1与无约束的正常JOIN(或CROSS JOIN)没有区别,我将该问题解释为与左连接实际上无关。

#3


1  

I believe Daniel's answer will work also but haven't tried it yet. I do know that I have an SP called list_failed_jobs2 in a schema called logging, and a dummy table called Dual (like in Oracle) and the following statement works for me:

我相信丹尼尔的回答也会奏效但尚未尝试过。我知道我在名为logging的模式中有一个名为list_failed_jobs2的SP,以及一个名为Dual的虚拟表(如在Oracle中),以下语句适用于我:

select * from Dual left join 
              (select * from logging.list_failed_jobs2()) q on 1=1;

Note, the SP call will not work without the parens, the correlation (q), or the ON clause. My SP returns a SETOF also.

注意,没有parens,相关(q)或ON子句,SP调用将不起作用。我的SP也返回SETOF。

Thus, I suspect something like this will work for you:

因此,我怀疑这样的事情对你有用:

select i.name,sp.*
from items i
left join (select * from compute_prices(i.id,current_date)) as sp on 1=1
where i.type = 404;

Hope that helps.

希望有所帮助。


推荐阅读
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 本博文基于《Amalgamationofproteinsequence,structureandtextualinformationforimprovingprote ... [详细]
  • QuestionThereareatotalofncoursesyouhavetotake,labeledfrom0ton-1.Somecoursesmayhaveprerequi ... [详细]
  • 用户视图(查看运行状态或其他参数)系统视图(配置设备的系统参数)system-viewEntersystemview,returnuservi ... [详细]
author-avatar
手机用户2502903815
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有