当我试图将值列表粘贴到条件中时,查询抛出了一个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语句中可以将其直接粘贴到表达式中,这对于较大的列表要好得多。
解决方案:
以上是我使用的代码。为了简洁起见,它稍微简化了一点,但它确实有效。
In List只要手动填充列表,就可以通过本机Query Manager选项工作
D.CATEGORY_CD='005-00'OR只要您将其包装在案例陈述中即可工作
D.CATEGORY_CD IN('015-00','015-06','015-10','615-07')只要将其包装在案例陈述中即可工作
Peoplesoft讨厌智能报价如果您直接从Word复制引号,则以上任何操作都不起作用,但除非您在编辑模式中保存、离开并返回到同一查询,否则您将看不到它
格式化很重要正如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
如果没有,你在那个盒子里放什么?
之前:
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。
希望对你有所帮助。