【发布时间】:2019-12-09 00:38:09
【问题描述】:
如何克服这个错误?
Java version: 1.8.0_131, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_131\jre
[DEBUG] com.oracle:ojdbc8:jar:12.2.0.1.0:provided
[INFO] Flyway Community Edition 5.2.4 by Boxfuse
[INFO] Database: jdbc:oracle:thin:@bdlg3400.na.pg.com:1525:ioptd101 (Oracle 12.2)
[DEBUG] Driver : Oracle JDBC driver 12.2.0.1.0
[ERROR] Migration R__SOME_VIEW_VW.sql failed
[ERROR] --------------------------------------
[ERROR] SQL State : 42000
[ERROR] Error Code : 933
[ERROR] Message : ORA-00933: (non-english description)
[ERROR] Location : sql\Views\R__SOME_VIEW_VW.sql (...\sql\Views\R__SOME_VIEW_VW.sql)
[ERROR] Line : 7
[ERROR] Statement : CREATE OR REPLACE VIEW some_view_vw as
[ERROR] WITH
[ERROR] abc AS
[ERROR] (
[ERROR] SELECT
[ERROR] iglp.p_skid,
[ERROR] LISTAGG(g.g_code, ',') WITHIN GROUP (ORDER BY g.g_code) AS lokd_gate_lst
[ERROR] FROM ig_l_prod iglp
[ERROR] JOIN ig_prc ig ON ig.ig_skid = iglp.ig_skid
[ERROR] JOIN g g ON g.g_skid = ig.g_skid
[ERROR] WHERE iglp.lock_ind = 'Y'
[ERROR] GROUP BY
[ERROR] iglp.p_skid
[ERROR] )
[ERROR] SELECT
[ERROR] pr.p_skid AS scr_prod_skid,
[ERROR] lg.lokd_gate_lst,
[ERROR] pr.*
[ERROR] FROM p pr
[ERROR] LEFT JOIN lokd_gate lg ON lg.p_skid = pr.p_skid
[ERROR] where exists(select 1 from PP_PRC pipo WHERE pipo.PI_P_SKID = pr.P_SKID);
[ERROR]
[ERROR] -> [Help 1]
当我将 WITH 子句作为子查询移动到 FROM 子句时,脚本成功。但是这样重构可能会导致其他视图效率低下。
【问题讨论】:
-
在视图中使用 CTE 是有效的。您确定您的整体陈述中没有其他错误/遗漏吗?如果您通过 SQL*Plus 或其他客户端运行相同的脚本,它会起作用吗?仅从错误消息中的这 4 行很难诊断。发布完整视图可能不可取,但您可以创建一个minimal reproducible example 来演示该问题吗? (也不确定为什么您认为它作为子查询的效率会降低。)
-
@AlexPoole 我们在项目中有很多视图,其中许多使用了多个 CTE。
-
我的猜测是,Flyway 解析该 SQL 脚本不正确,并且只将其中的一部分发送到服务器。你能告诉 Flyway “按原样”使用 SQL 脚本吗?我不知道 Flyway,但例如Liquibase 对这类事情有一个“splitStatements”属性,以防止工具不期望的 SQL 语法出现任何问题
-
我会怀疑日志中语句末尾显示的分号。那是一个语句分隔符(并由客户端解释),而不是语句的一部分。它会在 JDBC 和动态 SQL 调用等中导致此类错误。删除该分号是否可以解决问题? (作为脚本处理的一部分,Flyway 可能会很好,当然;我也不使用它......)
-
@AlexPoole,您有使用 CTE 的脚本(创建视图)示例吗?