使用 SQL 从 AS400 中提取数据的问题
Posted
技术标签:
【中文标题】使用 SQL 从 AS400 中提取数据的问题【英文标题】:Problem with extracting data from AS400 using SQL 【发布时间】:2020-05-26 08:36:31 【问题描述】:我正在编写一个 SQL 请求,以使用不同的关系从 AS400 导出数据。 我想这样写以减少时间并提高 ETL 的性能(我的 ETL 中至少有 2900 万行可以使用它)。
SQL:
SELECT A.x1, A.x2, A.x3, A.x4, A.x5,
(SELECT B.y1, B.y2, B.y3, C.w1 as w
FROM TEST1 AS B inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5))
where (B.y6 = 2)),
E.q1
FROM TEST3 AS A
LEFT OUTER JOIN TEST1 AS B ON (A.x6 = B.y7)
LEFT OUTER JOIN TEST4 AS E ON ((A.x6 = E.q2) AND (A.x7 = E.q3))
这个错误我真的需要帮助
我遇到了这个异常:
TITRE:Microsoft Visual Studio HRESULT 异常:0xC0202009 Erreur sur Traitement [来源 [2]]:代码错误 SSIS DTS_E_OLEDBERROR。 Une erreur OLE DB 最重要的产品。错误代码:0x80004005。 取消注册 OLE DB est disponible。来源:« IBMDA400 命令» Hresult:0x80004005 描述:« SQL0412 : Sous-requête non admise, car plus d'une colne résultat 原因 。 . . . . : La sous-requête d'un prédicat doit avoir uniquement une colne résultat concurrent lorsque l'autre opérande du prédicat est une expression simple。 En effet, la sous-requête peut extraire zéro, une ou plusieurs valeurs constituant une liste mais apparaissant dans une seule colne résultat。阙阙。 . . : Modifiez le nombre d'éléments renvoyés par la sous-requête pour qu'il n'y ait qu'une seule colne résultat ou remplacez l'autre opérande du prédicat pour obtenir une liste d'expressions。 »。
【问题讨论】:
根据错误消息,您的子查询SELECT B.y1, B.y2, B.y3, C.w1 as w ...
有多个列。如果您真的想要所有这些列,您可以使子查询成为外部应用,然后将其列包含在您的主选择中。
问题仍然存在。
我很困惑。 SQL Server 是否在“ibm-midrange”计算机上运行?我认为你的标签是错误的。
是的,已检查。我找到了一个解决方案,但它不是最好的:(SELECT B.y1, FROM TEST1 AS B inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) where ( B.y6 = 2)), (SELECT B.y2 FROM TEST1 AS B 内连接 TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) 其中 (B.y6 = 2)), (SELECT B.y3 FROM TEST1 AS B 内连接 TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) where (B.y6 = 2)), (SELECT C.w1 as w FROM TEST1 AS B 内连接 TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) where (B.y6 = 2)),跨度>
您的子查询(如果有效)与任何外部表都不相关。这似乎是一个更大的问题。并且了解您需要使用 DB2 可以理解的语法,而不是 TSQL 语法。在我看来,您需要将子查询设为派生表并将其加入主查询。我建议您使用 DB2 工具开发您的查询以使查询正确。然后在您的 SSIS 逻辑中使用该查询。
【参考方案1】:
您的错误的原因是子查询返回的列不止一列。 AlwaysLearning 已经说过了。
但下一个问题将是您的子查询返回多行。
除非
SELECT B.y1, B.y2, B.y3, C.w1 as w
FROM TEST1 AS B inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5))
where (B.y6 = 2)
只返回一行。请注意,子查询没有与外部选择相关的条件。在子查询中使用别名 B 不会将其与外部选择相关联,因为它是在内部选择中重新定义的 FROM TEST1 AS B
。这使得别名对子查询来说是本地的,并在子查询的外部选择中隐藏了 B 的使用。如果这不是您想要的,即使是,您也应该始终遵循 SQL 中的简单规则,不要重复使用别名。
【讨论】:
【参考方案2】:您可以使用“表表达式”来连接额外数据,而不是“标量子查询”。
标量子查询仅限于一行(您的可能返回多行)和一列(您的显然试图返回多于一列)。
例如,你可以这样做:
SELECT A.x1, A.x2, A.x3, A.x4, A.x5,
f.y1, f.y2, f.y3, f.w,
E.q1
FROM TEST3 AS A
LEFT OUTER JOIN TEST1 AS B ON (A.x6 = B.y7)
LEFT OUTER JOIN TEST4 AS E ON ((A.x6 = E.q2) AND (A.x7 = E.q3))
left join (
SELECT B.y1, B.y2, B.y3, C.w1 as w
FROM TEST1 AS B -- you should avoid reusing the same alias B, but OK
inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5))
where (B.y6 = 2)
) f on 1 = 1 -- what's the join condition? I assume you want all rows to match
编辑以加快查询速度
您正在选择表 A
中的所有行;那一定很慢。然而,由于您的连接是等连接,它们可以从索引中受益匪浅;以下索引可以使您的查询更快:
create index ix1 on TEST1 (y7, x1, x2, x3, x4, x5);
create index ix2 on TEST1 (y6, y1, y2, y3);
create index ix3 on TEST4 (q2, q3, q1);
create index ix4 on TEST2 (w2, w3, w1);
【讨论】:
我已经尝试过这个解决方案并且效果很好。但主要问题是需要很长时间。我想减少这个查询提取数据的时间。这就是为什么我试图避免连接并将它写成子查询。 @houssemeddineayari 您正在从表A
中选择所有行;那一定很慢。我添加的索引可以大大加快您的查询速度,除非您选择的行太多。实际上,您的查询选择了多少行?以上是关于使用 SQL 从 AS400 中提取数据的问题的主要内容,如果未能解决你的问题,请参考以下文章