gpt4 book ai didi

java - PLS-00103 : Encountered the symbol "end-of-file" in FlyWay

转载 作者:行者123 更新时间:2023-11-30 02:20:26 27 4
gpt4 key购买 nike

我们有一个数据库迁移脚本,通过 FlyWay 运行,FlyWay 是 Java 应用程序的一部分。问题是,一些客户拥有旧版本的应用程序,其中显示了一些表格和数据,而其他客户将安装此产品作为新解决方案。这些脚本必须每次运行(解决问题和历史问题)。

事实上,我们在 SQL 中通过简单的检查来处理这个问题,如果表存在,然后执行脚本的其余部分。它对于其他数据库(Postgres、MySQL、MS SQL)工作得很好,但对于 Oracle 却不行。经过几天的尝试和谷歌搜索后,我开始把头发从头上扯下来。第一个问题是执行 DDL 语句(已经知道我不能这样做),现在是这个。

我们训练的目的是:

  1. 如果当前用户存在主表,则运行脚本(这就是我们的方式确定所有其他表是否也存在)
  2. 对于每个表,我们需要创建一个备份表并复制其中的所有行(这就是我们执行 TRUNCATE 和 INSERT INTO 的原因,如果失败,我们执行 CREATE TABLE AS) - 这是所提供的代码应该执行的操作,IF table_count > 0 THEN 和 END IF 内的代码块;每个呈现的表格都会重复 (11x)
  3. 然后我们运行清理脚本,该脚本会检查错误数据并清理它们(我们必须存储原始值,以防出现问题)变坏)。
  4. 清理后的数据将复制到新表中(在之前的脚本中准备)。

总共有 10 个脚本,但这个脚本总是失败。

这是代码:

DECLARE 
table_count NUMBER;
curr_user VARCHAR2(100);
BEGIN
SELECT
sys_context('USERENV','SESSION_USER') INTO curr_user
FROM dual;

SELECT count(*)
INTO table_count
FROM all_objects
WHERE object_type IN ('TABLE', 'VIEW')
AND object_name = 'main_table'
AND owner = curr_user;

IF table_count > 0 THEN
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup
SELECT *
FROM some_table';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup AS SELECT * FROM some_table';
END IF;
END;

BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup2';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup2
SELECT *
FROM some_table2';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup2 AS SELECT * FROM some_table2';
END IF;
END;
.
.
.

END IF;

EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;

错误如下:

ORA-06550: line 30, column 8:

PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

第 30 行是 END; END IF 之后;在脚本的第一个分区中。

最佳答案

您的 FlyWay 版本似乎不喜欢嵌套 PL/SQL block 。我会尝试添加匿名 block 标签:

DECLARE 
table_count NUMBER;
curr_user VARCHAR2(100);
BEGIN
SELECT
sys_context('USERENV','SESSION_USER') INTO curr_user
FROM dual;

SELECT count(*)
INTO table_count
FROM all_objects
WHERE object_type IN ('TABLE', 'VIEW')
AND object_name = UPPER('main_table') --here I added UPPER
AND owner = curr_user;

IF table_count > 0 THEN
<<name1>>
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup
SELECT *
FROM some_table';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup AS SELECT * FROM some_table';
END IF;
END name1;

<<name2>>
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup2';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup2
SELECT *
FROM some_table2';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup2 AS SELECT * FROM some_table2';
END IF;
END name2;


END IF;

EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;
/
<小时/>

或者,您可以通过更改方法来避免嵌套 PL/SQL block 。

您可以轻松地检查表是否存在,然后执行操作,而不是首先尝试执行某些操作并处理异常。这样就根本不需要嵌套 PL/SQL block 。

第二种选择是使用动态 SQL:

DECLARE 
table_count NUMBER;
curr_user VARCHAR2(100);
BEGIN
SELECT
sys_context('USERENV','SESSION_USER') INTO curr_user
FROM dual;

SELECT count(*)
INTO table_count
FROM all_objects
WHERE object_type IN ('TABLE', 'VIEW')
AND object_name = UPPER('main_table')
AND owner = curr_user;

IF table_count > 0 THEN

EXECUTE IMMEDIATE q'{
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup
SELECT *
FROM some_table';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup AS SELECT * FROM some_table';
END IF;
END;}';

EXECUTE IMMEDIATE q'{
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE some_table_backup2';
EXECUTE IMMEDIATE 'INSERT INTO some_table_backup2
SELECT *
FROM some_table2';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942
THEN
RAISE;
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE some_table_backup2 AS SELECT * FROM some_table2';
END IF;
END;}';

END IF;

EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;

请注意 q'{}' 文本文字的用法,它允许处理 ' 而无需重复它们。

使用 FlyWay 4.2.0(从命令行调用),两个示例都可以正常工作。

关于java - PLS-00103 : Encountered the symbol "end-of-file" in FlyWay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47018419/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com