1

当我尝试将值列表粘贴到条件中时,查询会引发 ORA-00907 错误。

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

我主要是自学成才,我们的技术专家忙于数据库/应用程序的东西,或者他们不熟悉我部门的特定数据需求。

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

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 (Fieldname) OVER (PARTITION BY fieldname, fieldname) 语法。

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

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 位数字的“类别”,后跟一个短划线,然后是一个 2 位数字的“子类别”。我有一个包含 375 个类别代码的列表,我需要获取此查询结果。

我已经在这个版本上设置了一个提示,允许输入通配符(所以 123-%%),但这仍然是大约一百次单独运行的查询。查询管理器允许在条件中使用“列表中”表达式类型,但它需要您手动输入列表中的每个条目。

我正在尝试将其设置为可以将代码列表的纯文本副本粘贴到表达式中的位置,并带有适当的引号/逗号,并让它评估它以给我一个指定的所有 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 查询管理器使用 OVER、PARTITION BY 进行分组分析 SUM。当我尝试将列表粘贴到条件中时,它会引发 ORA-00907 错误。

任何帮助将不胜感激。谢谢!

4

4 回答 4

2

好的,在对此进行更多调整之后,我发现了我认为的根本问题。

在这种情况下,错误是双重的。部分原因是我的错(我没有检查 Peoplesoft 是否修改了我从 Word 中提取的引号),部分原因是查询管理器解释某些类型的函数的方式(你必须在 Case When 语句中包装一些东西让它正确评估)。

首先,“我的错”部分:

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

它具有可能很方便的“用智能引号替换直引号”功能。Peoplesoft 在呈现“智能报价”时会发疯,并将它们显示为倒置的问号(可能是一个技术术语,我不知道)。

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

我的错误在于没有保存不同的版本,离开应用程序并返回。当您保存查询,离开页面,转到 Peoplesoft 中的其他位置,然后返回打开查询管理器时,它实际上向您显示它正在执行字符转换。除非你这样做,否则你看不到它。即使查询管理器正在这样做。所以它抛出了一个查询管理器无法识别的字符,但没有向我显示它无法识别的字符。

我最近买了一台新的工作电脑,我现在禁用了智能报价自动替换以供将来使用。

二、“查询管理器:部分:

在我开始工作的版本中,我利用将“IN”函数包装在 Case 语句中。我发现很多 SQL 函数在使用“普通”时(因为我只是通过从 Oracle 的定义页面复制粘贴并填写适当的变量来定义它们)往往会给 PS/Query(查询管理器)带来胃痛. 但是,如果将它们包装在 CASE...WHEN...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 语句中可让您将其直接粘贴到 Expression 中,这对于较大的列表要好得多。

解决方案:

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

  1. 只要您手动填充列表,在列表中就可以通过本机查询管理器选项工作

  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')等

感谢所有为此提供帮助的人!我不认为我以前在任何问题上都这么努力过,但我想这是学习过程的一部分。由于发布的所有答案都是有效且正确的(或至少是较大的“正确”的一部分),我将把它们全部标记出来。

于 2012-08-14T18:14:45.300 回答
1

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

部分对我来说看起来很可疑

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

'015-00,'' '

后跟(非字符串)

015-06,

以下''可能是解析器偶然发现的东西,因为它毫无意义。

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

于 2012-01-10T21:05:42.463 回答
0

您发布的链接之后,我看到了 2 种方法来完成您想要完成的工作。我还注意到您尝试了第三种方法。

  • 方法一

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

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

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

问题)以下内容是否与您在“表达式”框中放置的文本完全匹配?

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

如果不是,你在那个盒子里放什么?

于 2012-04-09T19:20:37.587 回答
0

我认为 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 中包含 VENDOR_ID 或 NAME1 BY 子句。

希望对您有所帮助。

于 2012-01-12T02:11:58.033 回答