Wil*_*ill 18 sql oracle parsing
对于我当前的项目,我需要一个解析Oracle SQL语句的SQL解析器.目前我一直在使用jsqlparser,它适用于简单查询.但是当特定函数发生时(例如cast()或(+)),解析器失败.
任何人都可以建议一个完全符合Oracle SQL的解析器吗?
最好的,威尔
在处理同样的问题后,我设法让SQL解析器工作:
我的代码看起来像这样:
import oracle.jdeveloper.db.DatabaseConnections;
import oracle.javatools.db.sql.SQLQueryBuilder;
import oracle.javatools.db.Database;
...
// load the database connections
// this is specific to Oracle SQL developer
DatabaseConnections connections = DatabaseConnections.getPrivateInstance(
(new File("src/test/resources/connection.xml")).toURI().toURL(),
"somePassword");
// get the one we are interested in
Database database = connections.getDatabase("the-name-of-a-sqldeveloper-connection");
SQLQueryBuilder queryBuilder = SQLQueryBuilderFactory.createBuilder(
database, new Schema("OPTIONAL_SCHEMA"), "select * from some_table");
Run Code Online (Sandbox Code Playgroud)
实现这一目标的挑战是:
<?xml version = '1.0' encoding = 'UTF-8'?>
<References xmlns="http://xmlns.oracle.com/adf/jndi">
<Reference name="the-name-of-a-sqldeveloper-connection" className="oracle.jdeveloper.db.adapter.DatabaseProvider" xmlns="">
<Factory className="oracle.jdevimpl.db.adapter.DatabaseProviderFactory1212"/>
<RefAddresses>
<StringRefAddr addrType="password">
<Contents>HSx10FtlsPc=</Contents>
</StringRefAddr>
<StringRefAddr addrType="oraDriverType">
<Contents>thin</Contents>
</StringRefAddr>
...
Run Code Online (Sandbox Code Playgroud)
要获得这样的文件,您需要深入了解存储Oracle SQL Developer设置的文件夹,然后将该内容复制粘贴到您自己的文件中.
现在,假设你设法在这里做到这一点是问题和我最终解决方案失望的点:
我张贴了这个答案的原因是为了推动社会各界关注的事实,其具有的Oracle SQL语法分析程序是完全可行的,并可能有一天Oracle会考虑露出解析器竞争优势(我相信有网友在那里,会愉快地支付获得许可证的一些费用).
请问,为什么不用oracle解析器呢?
create global temporary table plans as select * from table(dbms_xplan.display_cursor());
--/
declare
c number;
i varchar2(30);
l number;
stmt varchar2(4000);
begin
delete from plans;
stmt:= 'select z.* from z,skew1 where z.z = skew1.fillblocks';
l:= length(stmt);
c:=dbms_sql.open_cursor();
dbms_sql.parse (c, stmt,dbms_sql.native);
select distinct sql_id into i from v$open_cursor where sid in (select sid from v$mystat) and substr(sql_text,1,l) = substr(stmt,1,l);
insert into plans select * from table(dbms_xplan.display_cursor(i));
dbms_output.put_Line ('sql_id:'||i);
end;
/
select * from plans;
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------
SQL_ID 97qc3ynmw1pa4, child number 0
-------------------------------------
select z.* from z,skew1 where z.z = skew1.fillblocks
Plan hash value: 942457544
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 85 (100)| |
|* 1 | HASH JOIN | | 1 | 410 | 85 (2)| 00:00:02 |
| 2 | TABLE ACCESS FULL| Z | 1 | 9 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| SKEW1 | 6000 | 2349K| 82 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("Z"."Z"=INTERNAL_FUNCTION("SKEW1"."FILLBLOCKS"))
Run Code Online (Sandbox Code Playgroud)
您确实需要一个 oracle 数据库连接。如果输出是您想要的,这是获得您想要的最简单方法,而无需为轮子重新发明其他颜色。在本例中,我将 sql 限制为 4000 个字符,但您可以将 varchar2 的 pl/sql 数组提供给 dbms_sql.parse 函数,这样做可以让您解析难以想象的大小的 sql。
您考虑过通用 SQL 解析器吗?我自己没有任何经验,但浏览他们的网站它有潜力。就我个人而言,我已经在 Eclipse Data Tools Platform 中的解析器上推出了自己的构建版本(抱歉我无法分享,它是专有的),但现在我必须评估我上面链接的解析器,因为它声称对 Oracle SQL 的覆盖范围比我的解析器确实如此。