“who_called_me”等同于Hibernate

时间:2014-02-11 00:44:19

标签: oracle hibernate stored-procedures triggers

我们知道可以动态地找出当前正在执行的过程或包的名称,如herehere所述。这通常适用于从数据库中的其他存储过程(已编译)执行的语句。

问题:

我们一直在尝试通过在表上放置触发器并从触发器内调用UPDATE来记录特定列(称为STATE)上的所有who_called_me活动。这样做的目的显然是根据应用程序设计,列STATE可以根据某些业务条件由多段代码(驻留在数据库中)进行更新。除此之外,该列也可以由应用程序更新,该应用程序是基于hibernate的应用程序,并且在通过hibernate查询进行更新时,who_called_me函数不返回任何内容。根据特定条件,应用程序中还有多个部分也可以UPDATESTATE

如果存储过程(驻留在数据库中)发出who_called_me语句并且UPDATE成功捕获相应的,则who_called_me策略适用于我们存储过程的所有者,名称,行号等。但是如果UPDATE发生在休眠状态,则该函数不会捕获任何细节。

有没有办法通过触发器捕获哪一行hibernate查询UPDATE?或者还有其他方法吗?

注意:触发器代码类似于this问题上发布的答案。

2 个答案:

答案 0 :(得分:1)

您可以使用ora_sql_text函数跟踪查询,例如这是我用于此的功能:

-- getting sql code, which is calling the current event, as clob
function getEventSQLtext
  return clob
  is
    sqllob      clob;
    sql_text    ora_name_list_t;
    dummy       integer;
begin
  dummy := ora_sql_txt(sql_text);

  dbms_lob.createtemporary(sqllob,false);

  for i in 1..sql_text.count loop
    dbms_lob.writeappend(sqllob,length(sql_text(i)),sql_text(i));
  end loop;

  return sqllob;
  if dummy is null then null; end if; -- removing warning of non-used variable :)
end;

这将是一个由hibernate生成的查询,这是您可以获得的唯一信息,因为这应该是hibernate可以用DB做的唯一事情。

答案 1 :(得分:1)

事实证明,who_called_me方法对存储过程调用更有效,其中堆栈跟踪可以准确指出哪一行调用了DML。在hibernate的情况下,代码可能不会调用存储过程,但可能会有单独的DML,这些DML会根据某些条件被调用。与@simon给出的其他答案相反,ora_sql_txt函数可能只在系统事件触发器中起作用,或者我可能错了,但无论哪种方式它都无法捕获Hibernate发出的SQL语句(测试它是不起作用并重新调整NULL值。

所以在一天结束时,为了找到SQL Hibernate正在使用的内容,DB Trace文件和Hibernate调试级别日志是目前唯一的方法。