这是我的使用情况:输入是表示一串 Oracle PL/SQL statement 的arbitray的复杂性。我们可以假设它是一个单一的发言(不一脚本)。现在,几个 位的这种输入串必须要被改写.

E.g。表名需要加,总的功能选择名单,不使用别名列应该分配一个默认的一种:

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
...

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

因为总的职能可能是嵌套和子选择的一b_tch,我不敢使用普通的表达。嗯,其实我没有并实现80%的成功,但我需要剩余的20%。

正确的做法,我相信,是使用法和分析程序.我摆弄弄c++ANTLR2(虽然我不知道很多关于法和分析的帮助等).我没有看到一个简单的方法来获得SQL位:

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

可能有人可能提供一些指针,关于如何"分析专业人员"就会追求这一问题?编辑:我使用 Oracle9i.

有帮助吗?

解决方案

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

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&amp;#3693276

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

编辑1:

可悲的是,我并不完全理解OP的需求,但我希望这可以提供帮助(这是另一种询问列的'名称'的方法,例如查询 select count(*),max(虚拟)来自双):

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 = .. ..'

其他提示

如果来源的SQL statement串的其他编码,你可以简单地坚持认为,该部需要改变简单,标明由特殊的逃跑公约,例如,写$表替代表的姓名、或$TABLEPREFIX其中之一是需要的。然后找的地方,需要修补,可以完成与一个子串的搜索和更换。

如果你真的有任意SQL串的和无法获得他们很好标记,你需要以某种方式parse SQL串为你已经观察到。XML解决方案肯定是一种可能的方式。

另一个办法是使用一个 程序的转换系统.这样的一个工具,可以分析一串为一个语言例,建立Ast,进行分析,并转变关于Ast,然后吐出一个经修订的串。

DMS软件的再设计工具包 是这样的系统。它有PLSQL前结束的分析器。它可以使用模式的指导转变为完成重写你似乎需要的。对你的例子涉及选择项目:

domain PLSQL.
rule use_explicit_column(e: expression):select_item -> select_item
   "\e" -> "\e \column\(\e\)".

阅读规则,则需要了解的东西里面的引用标记表示的抽象树木在某些计算机语言我们想要操纵。什么是"域PLSQL"的短语所说,"使用PLSQL分析器"来处理援引串的内容,这是它如何知道。(DMS有很多的语言特点的分析程序选择)。条款 "表达"和"select_item"是语法结构从语言的兴趣,例如,PLSQL在这种情况。看到的铁路图在你PLSQL参考手册》。反斜线表示逃/meta的信息,而不是目标语言的语法。

什么规则说的是,把这些元素分析 select_items 是只由一个 表达 \子, ,通过将其转换成一个 select_item 由的同样的表达 \子 和相应的栏( \列(\e) )据推测的基础上的位置,在选择项目列表,具体表。你必须要实现一个 功能,可以确定相应的名称从位置的选择项目。在这个例子中,我已选择将列定义功能接受的表达的兴趣作为参数;表达实际上是通过作为匹配树,因而列函数能够确定它在哪里的 select_items 清单由行走上抽象语法树。

这一规则的处理只是在选择项目。你会添加更多的规则来处理其他各种情况下,你的兴趣。

什么样的转换系统不会为你是:

  • 分析的语言的片段感兴趣
  • 建立一个AST
  • 让你们的模式相匹配为地方利益(通过这样做AST模式匹配) 但是,使用的表面语法的目标语言
  • 替换匹配的模式,通过其他模式
  • 计算aritrary的替代品(如Ast)
  • 再生来源的文本的修改Ast.

在编写该规则并不总是微不足道,这是什么是必要的,如果你的问题 指出作为提出。

XML建议的解决方案是另一种方式建立这样的Ast.它没有很好的模式匹配的性质尽管你可能能够得到很多出XSLT。我不知道的是如果XML具有分析树在完成的详细信息;DMS析程序不提供这种设计,因为它是必要的,如果你想要做任意的分析并变革。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top