SQLCL - 引用文件中存在 SQL 错误时出现意外 Java 异常

Posted

技术标签:

【中文标题】SQLCL - 引用文件中存在 SQL 错误时出现意外 Java 异常【英文标题】:SQLCL - Unexpected Java Exception when SQL errors exist in referenced files 【发布时间】:2019-01-16 18:48:55 【问题描述】:

当在命令行脚本和单独的 sql 文件中遇到 sql 错误时,我使用 SQLCL 遇到了不同的行为。

原始脚本,命令行 - 预期的 sql 错误

set errorlogging on
show errorlogging
TRUNCATE TABLE SPERRORLOG;
create table t1 (field1 number(10));
create table t1 (field1 number(10));
select /*csv*/ timestamp, message from sperrorlog;

当直接从 SQLCL 命令提示符执行创建表语句时,上述脚本会按预期执行。正如预期的那样,第二个 table create 语句报告了一个错误,表明 table 已经存在。

命令行的结果与预期一致:

SQL> set errorlogging on
SQL> show errorlogging
errorlogging is ON TABLE SPERRORLOG
SQL> TRUNCATE TABLE SPERRORLOG;

Table SPERRORLOG truncated.

SQL> create table t1 (field1 number(10));

Table T1 created.

SQL> create table t1 (field1 number(10));

Error starting at line : 1 in command -
create table t1 (field1 number(10))
Error report -
ORA-00955: name is already used by an existing object

SQL> select /*csv*/ timestamp, message from sperrorlog;
"TIMESTAMP","MESSAGE"
16-JAN-19 12.56.36.000000000 PM,"ORA-00955: name is already used by an existing object
"

更新脚本,外部文件 - java 异常:

但是,如果修改脚本以将“create table”语句移动到单独的 sql 文件中,则第二次执行不会报告 ORA-00955,而是会引发 Java 运行时异常

set errorlogging on
show errorlogging
TRUNCATE TABLE SPERRORLOG;
@create_t1.sql;
@create_t1.sql;
select /*csv*/ timestamp, message from sperrorlog;

create_t1.sql 的内容:

create table t1 (field1 number(10));

导致 java 运行时异常:

SQL> set errorlogging on
SQL> show errorlogging
errorlogging is ON TABLE SPERRORLOG
SQL> TRUNCATE TABLE SPERRORLOG;

Table SPERRORLOG truncated.

SQL> @create_t1.sql

Table T1 created.

SQL> @create_t1.sql
Jan 16, 2019 1:12:40 PM oracle.dbtools.raptor.newscriptrunner.ScriptExecutor run
SEVERE: sun.nio.fs.WindowsPathParser.normalize(Unknown Source)
java.nio.file.InvalidPathException: Illegal char <:> at index 4: file:/C:/repos/SKSandbox/sql/create_t1.sql
        at sun.nio.fs.WindowsPathParser.normalize(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPath.parse(Unknown Source)
        at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
        at java.nio.file.Paths.get(Unknown Source)
        at oracle.dbtools.raptor.newscriptrunner.ScriptRunnerContext.errorLog(ScriptRunnerContext.java:2360)
        at oracle.dbtools.raptor.newscriptrunner.SQL.handleSQLException(SQL.java:245)
        at oracle.dbtools.raptor.newscriptrunner.SQL.run(SQL.java:217)
        at oracle.dbtools.raptor.newscriptrunner.ScriptRunner.runSQL(ScriptRunner.java:404)
        at oracle.dbtools.raptor.newscriptrunner.ScriptRunner.run(ScriptRunner.java:230)
        at oracle.dbtools.raptor.newscriptrunner.ScriptExecutor.run(ScriptExecutor.java:341)
        at oracle.dbtools.raptor.newscriptrunner.ScriptExecutor.run(ScriptExecutor.java:224)
        at oracle.dbtools.raptor.newscriptrunner.SQLPLUS.runExecuteFile(SQLPLUS.java:3900)
        at oracle.dbtools.raptor.newscriptrunner.SQLPLUS.run(SQLPLUS.java:209)
        at oracle.dbtools.raptor.newscriptrunner.ScriptRunner.runSQLPLUS(ScriptRunner.java:420)
        at oracle.dbtools.raptor.newscriptrunner.ScriptRunner.run(ScriptRunner.java:257)
        at oracle.dbtools.raptor.newscriptrunner.ScriptExecutor.run(ScriptExecutor.java:341)
        at oracle.dbtools.raptor.newscriptrunner.ScriptExecutor.run(ScriptExecutor.java:224)
        at oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli.process(SqlCli.java:404)
        at oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli.processLine(SqlCli.java:415)
        at oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli.startSQLPlus(SqlCli.java:1247)
        at oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli.main(SqlCli.java:491)

SQL> select /*csv*/ timestamp, message from sperrorlog;
"TIMESTAMP","MESSAGE"
no rows selected
SQL>

更新 2,ext 文件,注销 - 没有 java 异常

如果ERRORLOGGING设置为OFF,则不报java异常,按预期返回SQL错误。

set errorlogging off
show errorlogging
TRUNCATE TABLE SPERRORLOG;
@create_t1.sql
@create_t1.sql
select /*csv*/ timestamp, message from sperrorlog;

结果包含没有java异常但缺少必要的SPERRORLOG记录的sql错误:

SQL> set errorlogging off
SQL> show errorlogging
errorlogging is OFF
SQL> TRUNCATE TABLE SPERRORLOG;

Table SPERRORLOG truncated.

SQL> @create_t1.sql

Table T1 created.

SQL> @create_t1.sql

Error starting at line : 1 File @ C:\repos\SKSandbox\sql\create_t1.sql
In command -
create table t1 (field number(10))
Error report -
ORA-00955: name is already used by an existing object

SQL> select /*csv*/ timestamp, message from sperrorlog;
"TIMESTAMP","MESSAGE"
no rows selected
SQL>

谁有关于如何使用 sql 文件的建议,这将导致适当的错误被记录到 SPERRORLOG 而没有 java 异常?

【问题讨论】:

【参考方案1】:

看起来确实是一个错误 - 您应该将这些报告给 My Oracle Support 或在 forums 上打开一个线程。

【讨论】:

我在论坛上发帖但没有 My Oracle Support 帐户。如果它是一个错误,我们希望解决方案与您的响应一样快。 :) @Shawn 显然我们在访问脚本文件时遇到了问题,DEV 肯定知道您的问题,敬请期待 谢谢。它似乎与当前工作目录有关。我发现如果我简单地添加一个“cd”。执行之前的命令所有文件都已找到并按预期运行

以上是关于SQLCL - 引用文件中存在 SQL 错误时出现意外 Java 异常的主要内容,如果未能解决你的问题,请参考以下文章

修复或避免在 SSDT 引用 Azure 托管实例中的主数据库时出现 SQL71501 和 SQL71561 构建错误?

执行 oracle 更改查询时出现错误:ORA-01756:引用的字符串未正确终止

尝试在 PHP 文件中调用方法时出现 ActionScript 错误

引用 .dll 文件时出现错误消息

为啥在 dbt 中运行模型时出现“关系 <y> 的列 <x> 不存在”错误,但在 SQL 客户端中运行时却没有?

链接 cxx 可执行文件时出现 Cmake 错误未定义引用