【问题标题】:How to retrieve parsed dynamic pl Sql如何检索解析的动态pl Sql
【发布时间】:2012-03-08 15:48:36
【问题描述】:

我有许多执行动态 sql 的 PL/SQL 函数和过程。

是否可以提取解析的语句和 dbms_output 作为调试帮助?

我真正想要的是查看解析后的 sql(带有替换参数的 sql 语句)。

例子:

我有一个这样的动态 SQL 语句

 SQ:='SELECT  :pComno as COMNO,null t$CPLS,t$CUNO,t$cpgs,t$stdt,t$tdat,t$qanp,t$disc,:cS Source FROM BAAN.TTDSLS031'||PCOMNO --1
    || ' WHERE' ||' TRIM(T$CUNO)=trim(:CUNO)' --2  
    ||    ' AND  TRIM(T$CPGS)=trim(:CPGS)' --3
    ||    ' AND  T$QANP      = priceWorx.fnDefaultQanp ' --4
    ||    ' AND  priceWorx.fdG2J(sysdate) between priceWorx.fdG2J(t$stdt) and priceWorx.fdG2J(t$tdat)' --5
    ||    ' AND  rownum=1 order by t$stdt';--6

    execute immediate SQ into R using 
        PCOMNO,'C' --1
        ,PCUNO-- 2
        ,PCPGS;-- 3

发送到服务器的语句是什么?

【问题讨论】:

  • 您要检索动态 sql 的 dbms_output.put_line,是吗?
  • 是的,这就是我想要的..
  • 你试过什么没用?

标签: oracle plsql


【解决方案1】:

您可以像这样显示与 SQL 语句关联的绑定变量:

select v$sql.sql_text
    ,v$sql_bind_capture.*
from v$sql_bind_capture
inner join v$sql on
    v$sql_bind_capture.hash_value = v$sql.hash_value
    and v$sql_bind_capture.child_address = v$sql.child_address
--Some unique string from your query
where lower(sql_text) like lower('%priceWorx.fdG2J(sysdate)%');

您可能希望查看整个查询,所有绑定变量都替换为它们的实际值。不幸的是,没有简单的方法可以准确地获得您正在寻找的东西,因为以下原因 问题。

  1. V$SQL_BIND_CAPTURE 不存储所有绑定变量信息。最大的限制是它只显示“当绑定变量用于 SQL 语句的 WHERE 或 HAVING 子句时”的数据。
  2. 将绑定捕获数据中的绑定变量名称与查询匹配非常困难。让它在 99% 的时间内正常工作很容易,但最后 1% 需要 SQL 和 PL/SQL 解析器,这基本上是不可能的。
  3. SQL 将从池中老化。例如,如果您收集相关表之一的统计信息,则可能会使使用该表的所有查询无效。您不能总是相信 V$SQL 会处理您的查询。

这意味着您可能会以丑陋的方式做这件事。您需要手动存储 SQL 和绑定变量数据,类似于 user1138658 所做的。

【讨论】:

    【解决方案2】:

    您可以使用dbms_output 包来执行此操作。可以enabledisable 进行调试,得到get_line 过程的行。

    我用execute immediate 进行了测试,插入到一个表格中,它可以工作。

    我最近回答了another question,并举了一个使用这个的例子。

    【讨论】:

    • 这个问题是在我回答后编辑的。在这种情况下获取 dbms_output 不是 OP 想要的...
    【解决方案3】:

    一种可能的解决方案是在您的架构中创建一个表temp(id varchar2,data clob);,然后将插入语句放在您想要找到已解析键的任何位置

    insert into temp values(seq.nextval,v_text);
    

    例如

    declare 
    v_text varchar2(2000);
    begin
    v_text:='select * from emp'; -- your dynamic statement
    
    insert into temp values(seq.nextval,v_text); --insert this script whenever you want to find the actual query 
    
    OPEN C_CUR FOR v_text;
    
    -----
    
    end;
    

    现在,如果您看到表 temp,您将获得该动态语句的数据。

    【讨论】:

      猜你喜欢
      • 2018-05-31
      • 2014-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2012-08-15
      相关资源
      最近更新 更多