gpt4 book ai didi

c++ - 在 C++ 中修改 PL/SQL 语句字符串

转载 作者:搜寻专家 更新时间:2023-10-31 02:00:45 25 4
gpt4 key购买 nike

这是我的用例:输入是表示任意复杂度的 Oracle PL/SQL 语句 的字符串。我们可以假设它是一条语句(不是脚本)。现在,必须重写此输入字符串的几个

例如表名需要加前缀,选择列表中不使用列别名的聚合函数应该分配一个默认值:

SELECT SUM(ABS(x.value)), 
TO_CHAR(y.ID,'111,111'),
y.some_col
FROM
tableX x,
(SELECT DISTINCT ID
FROM tableZ z
WHERE ID > 10) y
WHERE
...

成为

SELECT SUM(ABS(x.value)) COL1, 
TO_CHAR(y.ID,'111,111') COL2,
y.some_col
FROM
pref.tableX x,
(SELECT DISTINCT ID, some_col
FROM pref.tableZ z
WHERE ID > 10) y
WHERE
...

(免责声明:只是为了说明问题,声明没有意义)

因为聚合函数可能是嵌套的,subSELECTs是一个b_tch,我不敢用正则表达式。好吧,实际上我做到了,并且取得了 80% 的成功,但我确实需要剩下的 20%。

我认为正确的方法是使用语法和解析器。我摆弄了 c++ ANTLR2(尽管我不太了解语法和借助于此进行解析)。我没有看到获取 SQL 位的简单方法:

list<string> *ssel = theAST.getSubSelectList(); // fantasy land

任何人都可以提供一些关于“解析专家”将如何解决这个问题的建议吗?编辑:我正在使用 Oracle 9i

最佳答案

也许你可以使用它,它将一个 select 语句更改为一个 xml block :

declare
cl clob;
begin
dbms_lob.createtemporary (
cl,
true
);
sys.utl_xml.parsequery (
user,
'select e.deptno from emp e where deptno = 10',
cl
);
dbms_output.put_line (cl);
dbms_lob.freetemporary (cl);
end;
/

<QUERY>
<SELECT>
<SELECT_LIST>
<SELECT_LIST_ITEM>
<COLUMN_REF>
<SCHEMA>MICHAEL</SCHEMA>
<TABLE>EMP</TABLE>
<TABLE_ALIAS>E</TABLE_ALIAS>
<COLUMN_ALIAS>DEPTNO</COLUMN_ALIAS>
<COLUMN>DEPTNO</COLUMN>
</COLUMN_REF>
....
....
....
</QUERY>

参见此处:http://forums.oracle.com/forums/thread.jspa?messageID=3693276&#3693276

现在您“只”需要解析这个 xml block 。

编辑1:

遗憾的是,我并不完全理解 OP 的需求,但我希望这能有所帮助(这是另一种询问列的“名称”的方式,例如查询 select count(*),max( dual 中的虚拟):

set serveroutput on

DECLARE
c NUMBER;
d NUMBER;
col_cnt PLS_INTEGER;
f BOOLEAN;
rec_tab dbms_sql.desc_tab;
col_num NUMBER;

PROCEDURE print_rec(rec in dbms_sql.desc_rec) IS
BEGIN
dbms_output.new_line;
dbms_output.put_line('col_type = ' || rec.col_type);
dbms_output.put_line('col_maxlen = ' || rec.col_max_len);
dbms_output.put_line('col_name = ' || rec.col_name);
dbms_output.put_line('col_name_len = ' || rec.col_name_len);
dbms_output.put_line('col_schema_name= ' || rec.col_schema_name);
dbms_output.put_line('col_schema_name_len= ' || rec.col_schema_name_len);
dbms_output.put_line('col_precision = ' || rec.col_precision);
dbms_output.put_line('col_scale = ' || rec.col_scale);
dbms_output.put('col_null_ok = ');

IF (rec.col_null_ok) THEN
dbms_output.put_line('True');
ELSE
dbms_output.put_line('False');
END IF;
END;

BEGIN
c := dbms_sql.open_cursor;
dbms_sql.parse(c,'select count(*),max(dummy) from dual ',dbms_sql.NATIVE);
dbms_sql.describe_columns(c, col_cnt, rec_tab);

for i in rec_tab.first..rec_tab.last loop
print_rec(rec_tab(i));
end loop;

dbms_sql.close_cursor(c);
END;
/

(查看此处了解更多信息:http://www.psoug.org/reference/dbms_sql.html)

OP 还希望能够在查询中更改表的架构名称。我认为最简单的实现方法是从 user_tables 查询表名并在 sql 语句中搜索这些表名并为其添加前缀,或者执行 'alter session set current_schema = .. ..'

关于c++ - 在 C++ 中修改 PL/SQL 语句字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1614794/

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