我们知道可以动态地找出当前正在执行的过程或包的名称,如here和here所述。这通常适用于从数据库中的其他存储过程(已编译)执行的语句。
问题:
我们一直在尝试通过在表上放置触发器并从触发器内调用UPDATE
来记录特定列(称为STATE
)上的所有who_called_me
活动。这样做的目的显然是根据应用程序设计,列STATE
可以根据某些业务条件由多段代码(驻留在数据库中)进行更新。除此之外,该列也可以由应用程序更新,该应用程序是基于hibernate的应用程序,并且在通过hibernate查询进行更新时,who_called_me
函数不返回任何内容。根据特定条件,应用程序中还有多个部分也可以UPDATE
列STATE
。
如果存储过程(驻留在数据库中)发出who_called_me
语句并且UPDATE
成功捕获相应的,则who_called_me
策略适用于我们存储过程的所有者,名称,行号等。但是如果UPDATE
发生在休眠状态,则该函数不会捕获任何细节。
有没有办法通过触发器捕获哪一行hibernate查询UPDATE
?或者还有其他方法吗?
注意:触发器代码类似于this问题上发布的答案。
答案 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调试级别日志是目前唯一的方法。