Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ 功能建议 ] 建议支持解析运行Oracle下PLSQL执行块功能 #327

Closed
ericruan-cn opened this issue Jul 16, 2019 · 11 comments
Closed
Labels
area/oracle enhancement New feature or request

Comments

@ericruan-cn
Copy link
Collaborator

ericruan-cn commented Jul 16, 2019

目前遇到的问题/使用障碍

(1) 无法创建和替换 函数、过程、包
(2) 无法执行PLSQL执行块

以上两点在SQL解析时就不支持,具体SQL解析如下:
image

希望如何解决/实现它

(1) 定义PLSQL执行块的 开始与结束的声明,根据该声明来识别出PLSQL执行块,例如:
/* PLSQL BEGIN */

/* PLSQL END */

(2) 识别出的PLSQL执行块,再根据符号(/)来详细分割更小的可执行块。每一个执行块是一个可执行语句。

举例

/* PLSQL BEGIN */

declare
begin
end
/

declare
begin
end
/

/* PLSQL END */

@LeoQuote
Copy link
Collaborator

感谢你的反馈, 目前 oracle 的语法解析是用的 sqlparse

def execute_check(self, db_name=None, sql=''):
"""上线单执行前的检查, 返回Review set"""
config = SysConfig()
check_result = ReviewSet(full_sql=sql)
# 禁用/高危语句检查
line = 1
critical_ddl_regex = config.get('critical_ddl_regex', '')
p = re.compile(critical_ddl_regex)
check_result.syntax_type = 2 # TODO 工单类型 0、其他 1、DDL,2、DML
for statement in sqlparse.split(sql):
statement = sqlparse.format(statement, strip_comments=True)

可以看到是简单的直接split , 在执行的时候也是这样简单的split , 所以会造成执行失败.

如果要支持 PLSQL , 可以仿照 sql server 使用正则表达式分割语句, 然后所有其他语句都作为一整块运行.

def execute_check(self, db_name=None, sql=''):
"""上线单执行前的检查, 返回Review set"""
check_result = ReviewSet(full_sql=sql)
# 切分语句,追加到检测结果中,默认全部检测通过
split_reg = re.compile('^GO$', re.I | re.M)
sql = re.split(split_reg, sql, 0)
sql = filter(None, sql)
split_sql = [f"""use [{db_name}]"""]
for i in sql:
split_sql = split_sql + [i]
rowid = 1
for statement in split_sql:
check_result.rows.append(ReviewResult(

如果有能力的话可以直接改代码提pr , 只要流程没大问题, 单元测试全过就会接受.

但是说实话, 你提供的这种程度复杂度( 有两层嵌套 )的语句, 正则表达匹配会比较累, 实现起来难度较大, 还请量力而行.
@yzypals 你这边用oracle 比较多, 你觉得怎么样?

@LeoQuote LeoQuote added area/oracle enhancement New feature or request labels Jul 16, 2019
@ericruan-cn
Copy link
Collaborator Author

@LeoQuote 了解,我提的方式只是一个举例,确实复杂些。
如有简洁方法,肯定走简洁方法。可以约定,plsql程序块工单内容必须完全独立,不能和DDL & DML语句混合使用。

@yzypals
Copy link
Collaborator

yzypals commented Jul 16, 2019

这个平台的 定义, sql 查询 和上线 ,上面说的2个功能 感觉已经高于 这个定义了。
目前我们 没碰到过 这些情况,稍后我去问问 dba ,看看 上面2个需求 和这个平台的匹配度。

@ericruan-cn
Copy link
Collaborator Author

@yzypals 确实,我这已经不仅仅作为SQL上线管理使用,在线数据运维也打算纳入到本平台。
目前平台有一整套的SQL审核、执行,工单流程处理,权限控制等待,完全契合这个需求。

@ericruan-cn
Copy link
Collaborator Author

各位,本问题暂时解决不了,根源是 cx_Oracle扩展包不支持执行plsql块,底层的cursor.execute() 实际上还是以分号(;)为分隔来执行语句。

截图如下:
工单内容:
image

语句识别:
image

执行结果:
image

@LeoQuote
Copy link
Collaborator

这个不是cx_oracle做的,你看一下execute方法的逻辑是有切分的,你可以把那一段代码改了

@yzypals
Copy link
Collaborator

yzypals commented Aug 2, 2019

这个功能缺的是oracle sql 解析 这一块 , 现在用的sqlparse ,不确定能不能很好的支持解析begin 这种句法, 后面会考虑做,应该我们公司要求支持分开分表, 就需要更好的去解析语法了,顺便就把begin 这部分做了。 就是 时间跨度上会比较久。最近事情多 , 没太多精力弄这个。

@hhyo
Copy link
Owner

hhyo commented Mar 28, 2020

#688
这个是不是也在PR里面搞定了

@ericruan-cn
Copy link
Collaborator Author

ericruan-cn commented Mar 28, 2020 via email

@hhyo
Copy link
Owner

hhyo commented Jul 4, 2020

已支持

@hhyo hhyo closed this as completed Jul 4, 2020
@solon-liu
Copy link

image

其他工具是可以正常运行的PLSQL程序块,这里提交为什么还是会报错呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/oracle enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants