mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-05 22:03:36 +08:00
🐛 fix(oracle): 修复过程CASE分割导致执行截断
This commit is contained in:
@@ -175,6 +175,63 @@ describe('sqlStatementSelection', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps Oracle CREATE PROCEDURE cursor CASE expressions as one executable statement', () => {
|
||||
const sql = [
|
||||
'CREATE OR REPLACE PROCEDURE proc_accept_to_add(',
|
||||
' p_acceptno IN t_accept_h.acceptno%TYPE',
|
||||
') IS',
|
||||
' CURSOR cur_store_same(p_ind s_sys_ini.inipara%TYPE) IS',
|
||||
' SELECT si.compid, si.batid, si.wareid',
|
||||
' FROM t_store_i si',
|
||||
' ORDER BY CASE',
|
||||
" WHEN p_ind = '1' THEN",
|
||||
" to_char(si.invalidate - to_date('19700101', 'yyyymmdd'))",
|
||||
" WHEN p_ind = '2' THEN",
|
||||
" lpad(to_char(floor(si.wareqty)), 10, '0')",
|
||||
' ELSE',
|
||||
' to_char(si.batid)',
|
||||
' END,si.batid;',
|
||||
'BEGIN',
|
||||
' NULL;',
|
||||
'END;',
|
||||
'/',
|
||||
'SELECT 1 FROM dual;',
|
||||
].join('\n');
|
||||
|
||||
const ranges = findSqlStatementRanges(sql).map((range) => range.text);
|
||||
|
||||
expect(ranges).toEqual([
|
||||
[
|
||||
'CREATE OR REPLACE PROCEDURE proc_accept_to_add(',
|
||||
' p_acceptno IN t_accept_h.acceptno%TYPE',
|
||||
') IS',
|
||||
' CURSOR cur_store_same(p_ind s_sys_ini.inipara%TYPE) IS',
|
||||
' SELECT si.compid, si.batid, si.wareid',
|
||||
' FROM t_store_i si',
|
||||
' ORDER BY CASE',
|
||||
" WHEN p_ind = '1' THEN",
|
||||
" to_char(si.invalidate - to_date('19700101', 'yyyymmdd'))",
|
||||
" WHEN p_ind = '2' THEN",
|
||||
" lpad(to_char(floor(si.wareqty)), 10, '0')",
|
||||
' ELSE',
|
||||
' to_char(si.batid)',
|
||||
' END,si.batid;',
|
||||
'BEGIN',
|
||||
' NULL;',
|
||||
'END;',
|
||||
].join('\n'),
|
||||
'SELECT 1 FROM dual',
|
||||
]);
|
||||
expect(resolveExecutableSql(sql, sql.indexOf('ORDER BY CASE'))).toEqual({
|
||||
sql: ranges[0],
|
||||
source: 'statement',
|
||||
});
|
||||
expect(resolveExecutableSql(sql, sql.indexOf('NULL'))).toEqual({
|
||||
sql: ranges[0],
|
||||
source: 'statement',
|
||||
});
|
||||
});
|
||||
|
||||
it('skips SQL*Plus slash delimiter comments after named Oracle procedure endings', () => {
|
||||
const sql = [
|
||||
'-- 修改函数/存储过程:H2.cproc_tzhssr_order2sale_A1',
|
||||
|
||||
@@ -205,6 +205,8 @@ export const findSqlStatementRanges = (sql: string): SqlStatementRange[] => {
|
||||
let dollarTag: string | null = null;
|
||||
let plsqlDepth = 0;
|
||||
let plsqlDeclareBeginSkips = 0;
|
||||
let plsqlCaseDepth = 0;
|
||||
let skipNextPlsqlCaseEndToken = false;
|
||||
let justClosedPLSQLBlock = false;
|
||||
|
||||
const push = (end: number) => {
|
||||
@@ -309,6 +311,16 @@ export const findSqlStatementRanges = (sql: string): SqlStatementRange[] => {
|
||||
tokenEnd++;
|
||||
}
|
||||
const token = text.slice(index, tokenEnd).toLowerCase();
|
||||
if (token === 'case' && plsqlDepth > 0) {
|
||||
if (skipNextPlsqlCaseEndToken) {
|
||||
skipNextPlsqlCaseEndToken = false;
|
||||
} else {
|
||||
plsqlCaseDepth++;
|
||||
justClosedPLSQLBlock = false;
|
||||
}
|
||||
} else if (token !== 'case') {
|
||||
skipNextPlsqlCaseEndToken = false;
|
||||
}
|
||||
if (token === 'begin' && plsqlDeclareBeginSkips > 0) {
|
||||
plsqlDeclareBeginSkips--;
|
||||
justClosedPLSQLBlock = false;
|
||||
@@ -325,11 +337,20 @@ export const findSqlStatementRanges = (sql: string): SqlStatementRange[] => {
|
||||
plsqlDeclareBeginSkips++;
|
||||
}
|
||||
justClosedPLSQLBlock = false;
|
||||
} else if (token === 'end' && plsqlDepth > 0 && plsqlCaseDepth > 0) {
|
||||
plsqlCaseDepth--;
|
||||
if (nextSqlSignificantToken(text, tokenEnd) === 'case') {
|
||||
skipNextPlsqlCaseEndToken = true;
|
||||
}
|
||||
justClosedPLSQLBlock = false;
|
||||
} else if (token === 'end' && plsqlDepth > 0 && !isPlsqlControlEnd(text, tokenEnd)) {
|
||||
plsqlDepth--;
|
||||
if (plsqlDeclareBeginSkips > plsqlDepth) {
|
||||
plsqlDeclareBeginSkips = plsqlDepth;
|
||||
}
|
||||
if (plsqlCaseDepth > plsqlDepth) {
|
||||
plsqlCaseDepth = plsqlDepth;
|
||||
}
|
||||
justClosedPLSQLBlock = plsqlDepth === 0;
|
||||
}
|
||||
index = tokenEnd - 1;
|
||||
|
||||
Reference in New Issue
Block a user