[英]PLS-00103: Encountered the symbol “end-of-file” in FlyWay
We have a database migration scripts, which are run trough FlyWay, which is part of Java app. 我们有一个数据库迁移脚本,该脚本通过FlyWay运行,它是Java应用程序的一部分。 The problem is that some customers have the older version of app, where some table and data are presented, while others will be installing this product as new solution. 问题在于某些客户使用的应用程序版本较旧,其中显示了一些表和数据,而另一些客户将安装此产品作为新解决方案。 These scripts must run everytime (solution problem and historical problem). 这些脚本必须每次都运行(解决问题和历史问题)。
In fact, we handle this in SQL with simple check, if table exist and then execute the rest of script. 实际上,我们通过简单的检查在SQL中进行处理(如果表存在),然后执行其余脚本。 It works quite fine for other databases (Postgres, MySQL, MS SQL) but not for Oracle. 对于其他数据库(Postgres,MySQL,MS SQL),它工作得很好,但对于Oracle,则不能。 And after few days of trying and googling I am starting to rip my hair off of my head. 经过几天的尝试和谷歌搜索,我开始把头发从头上扯下来。 First problem was executing DDL statements (already learned I can't do that) and now this. 第一个问题是执行DDL语句(已经知道我做不到),而现在是这样。
What are we traing to achieve: 我们要实现的目标是:
There is 10 scripts in total, but this one is constantly failing. 总共有10个脚本,但是这个脚本一直在失败。
Here is the code: 这是代码:
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;
The error is following: 错误如下:
ORA-06550: line 30, column 8: ORA-06550:第30行,第8列:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: PLS-00103:预期以下情况之一时遇到符号“文件结束”:
Line 30 is END; 第30行是END; after END IF; 在END IF之后; in first partition of script. 在脚本的第一个分区中。
It looks like that your version of FlyWay does not like nested PL/SQL Blocks. 看来您的FlyWay版本不喜欢嵌套的PL / SQL块。 I would try to add anonymous block labels: 我会尝试添加匿名块标签:
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;
/
Alternatively you could avoid nested PL/SQL block by changing approach. 另外,您可以通过更改方法来避免嵌套的PL / SQL块。
Instead of trying to do something first and handle exception, you could easily check if table exist or not and then do the action. 您可以轻松地检查表是否存在,然后执行操作,而不是先尝试做一些事情并处理异常。 That way there is no need for nested PL/SQL blocks at all. 这样,根本就不需要嵌套的PL / SQL块。
Second alternative is to use dynamic SQL: 第二种选择是使用动态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;
Please note the usage of q'{}'
text literal that allow to handle '
without duplicating them. 请注意q'{}'
文本文字的用法,该文本常量可以处理'
而无需复制它们。
With FlyWay 4.2.0(called from command-line) both samples work as it should. 使用FlyWay 4.2.0(从命令行调用)时,两个示例都可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.