ORA-00907在查询中使用分析函数时出错(PS/Query,Peopletools 8.51.12)



当我试图将值列表粘贴到条件中时,查询抛出了一个ORA-00907错误。

背景我不是开发人员,我只是一个经过足够研究的最终用户,我可以在Peoplesoft中使用PS/Query编写查询,为我公司的实施。我使用Peoplesoft的FSCM模块(财务和供应链管理),目前版本为FSCM8.90.08.024,使用我认为Oracle 11g作为基础数据库。

我大部分是自学成才的,我们的技术专家都很忙数据库/应用程序的东西,或者他们不熟悉我的部分的具体数据需求。

我应该指出,我无法直接将SQL语句写入查询数据库。我必须使用一个名为"PS/Query"的内置程序(也称为查询管理器),带有为您编写SQL的GUI并将其保存为查询,您可以运行该查询到数据库以提取数据这与我的问题有关,只是因为:

1. I cannot create or alter views/tables
2. I cannot perform any type of SQL Statement except "SELECT"
3. I can embed PL/SQL, MetaSQL and plain SQL into Expressions
4. At this point, Query Manager is the only option I have.

PS/Query是我迄今为止唯一使用SQL的经验,除了Oracle的文档和类似的网站。根据我的研究受到"实际"SQL程序员的极大限制。对它的限制要求你以一种违背事实的方式做事SQL编码的最佳实践。

查询请求:我有一个请求我编写的查询,根据定义的特定系统提取支出(凭证和采购订单)类别代码。我想做的是提取优惠券ID,将按供应商和类别代码列出的商品金额,并显示结果。或者换句话说,对于供应商/类别,将具有供应商/类别组合。

使用SUM(字段名)OVER(PARTITION BY字段名,字段名)语法。

所以最终结果应该看起来像。。。

Code     Vendor    Amount
123-45   Acme     $5000.00
123-45   Apple    $4200.00
123-46   Acme     $750.00

话虽如此,以下是查询管理器显示的SQL,以获得我上面显示的结果集:

SELECT DISTINCT D.CATEGORY_CD, D.TN_DESCR1000, C.VENDOR_ID, E.NAME1, SUM ( A.MERCH_AMT_VCHR) OVER (PARTITION BY  D.CATEGORY_CD,  C.VENDOR_ID),E.SETID,E.VENDOR_ID 
  FROM PS_PO_LINE_MATCHED A, PS_PO_LINE B, PS_PO_HDR C, PS_ITM_CAT_TBL D, PS_VENDOR E, PS_PYMNT_VCHR_XREF F 
  WHERE A.BUSINESS_UNIT = B.BUSINESS_UNIT 
     AND A.PO_ID = B.PO_ID 
     AND A.LINE_NBR = B.LINE_NBR 
     AND B.BUSINESS_UNIT = C.BUSINESS_UNIT 
     AND B.PO_ID = C.PO_ID 
     AND D.CATEGORY_ID = B.CATEGORY_ID 
     AND D.EFFDT = 
        (SELECT MAX(D_ED.EFFDT) FROM PS_ITM_CAT_TBL D_ED 
        WHERE D.SETID = D_ED.SETID 
          AND D.CATEGORY_TYPE = D_ED.CATEGORY_TYPE 
          AND D.CATEGORY_CD = D_ED.CATEGORY_CD 
          AND D.CATEGORY_ID = D_ED.CATEGORY_ID 
          AND D_ED.EFFDT <= SYSDATE) 
     AND ( F.SCHEDULED_PAY_DT >= TO_DATE('2010-07-01','YYYY-MM-DD') 
     AND F.SCHEDULED_PAY_DT <= TO_DATE('2011-06-30','YYYY-MM-DD')) 
     AND D.CATEGORY_CD LIKE :1 
     AND E.VENDOR_ID = C.VENDOR_ID 
     AND A.BUSINESS_UNIT = F.BUSINESS_UNIT 
     AND A.VOUCHER_ID = F.VOUCHER_ID 
  ORDER BY 1

基本问题:这很好,但只能提示一个类别代码。类别代码是5位数字,一个3位数字"Class"后面跟着一个破折号,然后是一个2位数的子类。我有一个列表我需要获得375个类别代码的查询结果。

我在这个版本上设置了一个提示,允许输入通配符(所以123-%%),但这仍然是大约一百次单独的跑步查询Query Manager允许在中使用"In List"表达式类型条件,但它要求您在列表

我正在尝试将其设置为可以粘贴代码列表到表达式中,并使用正确的引号/逗号评估一下,给我一个所有NIGP代码的组合列表指定。查询管理器创建的"提示"字段不允许粘贴列表(据我所知)。

尝试的解决方案:我在http://peoplesoft.ittoolbox.com/groups/technical-functional/peoplesoft-other-l/create-an-expression-in-psoft-90-query-to-paste-a-list-of-emplids-2808427我试过那里给出的一些答案,但都不起作用。这个页面让我尝试了这个修改后的SQL(很明显,代码列表被截断了一点,以便在这里显示):

SELECT DISTINCT D.CATEGORY_CD, D.TN_DESCR1000, C.VENDOR_ID, E.NAME1, SUM (  A.MERCH_AMT_VCHR) OVER (PARTITION BY  D.CATEGORY_CD,  C.VENDOR_ID),E.SETID,E.VENDOR_ID 
  FROM PS_PO_LINE_MATCHED A, PS_PO_LINE B, PS_PO_HDR C, PS_ITM_CAT_TBL D, PS_VENDOR E,  PS_PYMNT_VCHR_XREF F 
  WHERE A.BUSINESS_UNIT = B.BUSINESS_UNIT 
     AND A.PO_ID = B.PO_ID 
     AND A.LINE_NBR = B.LINE_NBR 
     AND B.BUSINESS_UNIT = C.BUSINESS_UNIT 
     AND B.PO_ID = C.PO_ID 
     AND D.CATEGORY_ID = B.CATEGORY_ID 
     AND D.EFFDT = 
        (SELECT MAX(D_ED.EFFDT) FROM PS_ITM_CAT_TBL D_ED 
        WHERE D.SETID = D_ED.SETID 
          AND D.CATEGORY_TYPE = D_ED.CATEGORY_TYPE 
          AND D.CATEGORY_CD = D_ED.CATEGORY_CD 
          AND D.CATEGORY_ID = D_ED.CATEGORY_ID 
          AND D_ED.EFFDT <= SYSDATE) 
     AND ( F.SCHEDULED_PAY_DT >= TO_DATE('2010-07-01','YYYY-MM-DD') 
     AND F.SCHEDULED_PAY_DT <= TO_DATE('2011-06-30','YYYY-MM-DD')) 
     AND D.CATEGORY_CD = '005-00' OR  D.CATEGORY_CD IN ('015-00,'' '015-06,'' '015-10,'' '615-07'') 
     AND E.VENDOR_ID = C.VENDOR_ID 
     AND A.BUSINESS_UNIT = F.BUSINESS_UNIT 
     AND A.VOUCHER_ID = F.VOUCHER_ID 
  ORDER BY 1

上面的SQL就是导致ORA-00907错误的原因。以前有人遇到过这个问题吗?巨大的文字墙,我知道。我很抱歉。这是我在这里的第一篇帖子,我尽量不遗漏任何相关内容。

我已经解决了引发这个问题的直接问题,但这个请求只是冰山一角,在某个时候,我需要找到一种方法,能够使用查询管理器将明文列表粘贴为标准,最好是以一种与分析分组配合良好的方式。

TL;DR版本:

使用Peoplesoft Query Manager使用OVER、PARTITION BY进行分组的分析求和。当我试图将列表粘贴到条件中时,它会抛出ORA-00907错误

如有任何帮助,我们将不胜感激。谢谢

好吧,经过一点调整,我发现了我认为的根本问题。

在这种情况下,错误有两个方面。部分原因是我的错(我没有检查Peoplesoft是否篡改了我从Word中提取的引号),部分原因是Query Manager解释某些函数的方式(你必须将一些东西包装在Case When语句中才能使其正确评估)。

首先,"我的错"部分:

每次我在测试NIGP代码列表中粘贴时,我都是从保存在Microsoft Word中的文件中粘贴的。

它有一个可能很方便的"用智能引号替换直引号"功能。Peoplesoft在展示"聪明的报价"时会发疯,并将其显示为倒置的问号(可能有一个技术术语,我不知道)。

因此,当我测试建议时(例如按照@Rene Nyffenegger和@WayneH的建议修复引号/逗号顺序),我会从我的基本测试查询开始,添加表达式并测试它,将其保存为一个单独的查询。如果它们不起作用,我会回到基本查询。这样,我就可以迭代更改并将潜在的测试保存为不同的版本。

我的错误是没有保存不同的版本,离开应用程序并返回。当你保存查询,离开页面,转到Peoplesoft的其他地方,然后返回打开查询管理器时,它实际上会向你显示它正在进行字符转换。除非你那样做,否则你看不到它。尽管Query Manager正在这么做。所以它抛出了一个Query Manager无法识别的字符,但没有向我显示它无法识别的角色。

我最近买了一台新的工作电脑,现在我已经禁用了Smart Quotes自动更换功能,以备将来使用。

第二,"查询管理器:部分:

在我开始工作的这个版本中,我使用了将"IN"函数包装在Case语句中的方法。我发现,很多SQL函数在"纯"使用时(我通过从Oracle的定义页面复制粘贴并填充适当的变量来定义它们)往往会让PS/Query(查询管理器)感到心痛。但如果你把它们包在箱子里。。。何时。。。END语句,该语句评估函数的结果,然后构建一个标准,根据该结果的某些值进行选择,函数将工作并正确显示结果。

因此,作为一个例子,设置这个表达式(就像@qyb2zm302中的例子一样)。我使用的代码与原来的示例不同,但它们的工作原理相同(它们都是五位数的字符型代码,由三位数、一个短划线和两位数组成)

Case when  E.CATEGORY_CD  IN
                  ('375-15', '375-30', '375-54', '375-60', '380-30','938-63') 
    then 'true' 
    else 'false' 
    end 

然后设置一个标准:

    AND 
        Case when  E.CATEGORY_CD  IN
                  ('375-15', '375-30', '375-54', '375-60', '380-30','938-63') 
                   then 'true' 
                   else 'false' 
        end 
   = 'true'

它将运行到完成,并返回任何具有该类别代码的行。

如果你不想这样做,你可以像@qyb2zm302的方法2那样做。在查询管理器中,唯一的缺点是您必须将它们输入到"列表"中的各个行中,如果您一次只能复制粘贴25个。

将其封装在Case语句中可以将其直接粘贴到表达式中,这对于较大的列表要好得多。

解决方案:

以上是我使用的代码。为了简洁起见,它稍微简化了一点,但它确实有效。

  1. In List只要手动填充列表,就可以通过本机Query Manager选项工作

  2. D.CATEGORY_CD='005-00'OR只要您将其包装在案例陈述中即可工作

  3. D.CATEGORY_CD IN('015-00','015-06','015-10','615-07')只要将其包装在案例陈述中即可工作

  4. Peoplesoft讨厌智能报价如果您直接从Word复制引号,则以上任何操作都不起作用,但除非您在编辑模式中保存、离开并返回到同一查询,否则您将看不到它

  5. 格式化很重要正如Rene和Wayne所指出的,以上所有内容都需要正确的逗号/引号格式。含义:('xxx-xx','xxx-01','xxx-02')等

感谢所有在这方面提供帮助的人!我想我以前在任何问题上都没有这么努力过,但我想这是学习过程的一部分。由于发布的所有答案都是有效和正确的(或者至少是较大的"正确"的一部分),我将标记所有答案。

 D.CATEGORY_CD IN ('015-00,'' '015-06,'' '015-10,'' '615-07'') 

觉得零件有点可疑

由于字符串中的''"评估"为单个',因此第一个字符串是

'015-00,'' '

然后是(非字符串)

015-06,

下面的''可能是解析器偶然发现的东西,因为它非常没有意义。

编辑使用D.CATEGORY_CD IN ('015-00', '015-06', '015-10', '615-07')进行尝试。

在您发布的链接之后,我看到了两种方法来完成您想要完成的任务。我还注意到你尝试了第三种方法。

  • 方法1

    • 条件>添加条件
    • 表达式类型:字符
    • 长度:255
    • 表达式文本:D.CATEGORY_CD IN('015-00','015-06','015-10','615-07')AND 1
    • 条件类型:等于
    • 常数:1
  • 方法2

    • 条件>添加条件
    • 字段:D.CATEGORY_CD
    • 条件类型:在列表中
    • 值:015-00','015-06','015-10','615-07
  • 方法3(您的方法)

    • 条件>添加条件
    • 字段:D.CATEGORY_CD
    • 条件类型:等于
    • 定义表达式:"015-00"或D.CATEGORY_CD IN('015-00','015-06','015-10','615-07')

问题)下面的内容与你放在"表达式"框中的文本完全匹配吗?

('015-00','015-06','015-10','615-07')中的"015-00"或D.CATEGORY_CD

如果没有,你在那个盒子里放什么?

p>我认为D.CATEGORY_CD标准给你带来了问题,我把双引号改成了单引号,然后我觉得它仍然很奇怪。然后我注意到逗号在你的引号里,而不是在它们之间,试着让一个标准行看起来像这样:

之前:

OR  D.CATEGORY_CD IN ('015-00,'' '015-06,'' '015-10,'' '615-07'')

之后:

OR  D.CATEGORY_CD IN ('015-00', '015-06', '015-10', '615-07')

此外,"IN"是一个隐含的"OR",我不确定你是否在两个D.CATEGORY_CD周围有括号,我只需要将一个额外的代码放入IN标准中,并删除"D.CATEGORY_CD="行:

之前:

AND D.CATEGORY_CD = '005-00' OR  D.CATEGORY_CD IN ('015-00', '015-06', '015-10', '615-07') 

之后:

AND D.CATEGORY_CD IN ('015-00', '015-06', '015-10', '615-07', '005-00')

当然,您已经按CATEGORY_CD排序了,您可以删除此条件并在一次运行中提取所有类别(也就是说,除非excel的行太多),然后您可能还想在ORDER by子句中包括VENDOR_ID或NAME1。

希望对你有所帮助。

相关内容

  • 没有找到相关文章

最新更新