首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中修改PL/SQL语句字符串

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

Stack Overflow用户
提问于 2009-10-23 17:13:29
回答 1查看 1.2K关注 0票数 2

这就是我的用例:输入是一个字符串,表示仲裁复杂性的Oracle /SQL语句。我们可能假设它是一个语句(而不是脚本)。现在,这个输入字符串的几个位必须重写

例如,表名需要前缀,不使用列别名的选择列表中的聚合函数应该被指定为默认的函数:

代码语言:javascript
复制
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
...

变成了

代码语言:javascript
复制
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
...

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

由于聚合函数可能是嵌套的,而subSELECT是一个b_tch,所以我不敢使用正则表达式。嗯,事实上我做到了,并且取得了80%的成功,但我确实需要剩下的20%。

我认为正确的方法是使用语法和解析器。我摆弄着c++ ANTLR2 (尽管在这样的帮助下,我对语法和解析不太了解)。我看不出获得SQL位的一种简单方法:

代码语言:javascript
复制
list<string> *ssel = theAST.getSubSelectList(); // fantasy land

有人能提供一些关于“解析专业人士”将如何解决这个问题的建议吗?编辑:我正在使用Oracle9i

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-10-23 17:24:44

也许您可以使用它,它将select语句更改为xml块:

代码语言:javascript
复制
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>

见此处:

现在,您只需要解析这个xml块。

Edit1:

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

代码语言:javascript
复制
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;
/

(有关更多信息,请参见这里:sql.html)

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1614794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档