首页 > 解决方案 > Firebird SQL 过程可以知道调用它的父过程/触发器吗?

问题描述

我有一个 SQL 过程,如果它是从一个特定过程调用的,它应该返回一些不同的结果。SQL 过程是否有可能检测到它是从一个特定的其他 SQL 过程调用的?

也许监控 mon$... 表数据可以给出答案?

适用于 Firebird 2.1 的问题

例如,有 mon$call_stack 表,但对于 Firebird 2.1,大多数情况下 mon$... 表是空的,它们会为更高版本的 Firebird 填满。

标签: firebirdfirebird2.1

解决方案


隐藏的数据依赖关系是个坏主意。程序员将“纯函数”视为一件好事是有原因的。也许不是在所有情况下,也不是不惜一切代价,但是当其他因素不受影响时,最好是这样。

https://en.wikipedia.org/wiki/Pure_function

所以,马克是正确的,如果有什么东西会影响你的过程逻辑——那么最好通过成为一个显式的函数参数来显式地记录它。除非您的明确目标正是创建一个隐藏的后门。

然而,这意味着该过程的所有“客户端”,以及可以调用它的所有位置,也应该更改,并且应该在开发期间和客户端部署站点的升级期间协同完成。这可能很复杂。

所以我宁愿建议创建一个新程序并将所有实际逻辑移入其中。

https://en.wikipedia.org/wiki/Adapter_pattern

假设你有一些

create procedure old_proc(param1 type1, param2 type2, param3 type3) as 
begin
   ....some real work and logic here....
end;

把它变成类似的东西

create procedure new_proc(param1 type1, param2 type2, param3 type3, 
            new_param smallint not null = 0) as 
begin
   ....some real work and logic here....
   ....using new parameter for behavior fine-tuning...
end;

create procedure old_proc(param1 type1, param2 type2, param3 type3) as 
begin
  execute procedure new_proc(param1, param2, param3)
end;

...然后您明确地进行“一个特定程序”调用new_proc(...., 1)。然后逐渐地,一个接一个地,您将所有程序从调用移动old_proc到调用,最终当所有依赖项都移动到新 API 时new_proc,您将退休。old_proc


还有一个传递“隐藏后门参数”的选项——即上下文变量,在 Firebird 2.0 中引入

https://www.firebirdsql.org/rlsnotesh/rlsnotes20.html#dml-dsql-context

然后你的被调用者会这样检查

 .....normal execution
 if ( rdb$get_context('USER_TRANSACTION','my_caller') is not null) THEN BEGIN
      ....new behavior...
 end;

但是,您必须在调用之前进行“一个特定的过程”以正确设置此变量(这很乏味但并不难)并在调用后正确删除它(并且即使在任何情况下也应该正确设置框架以正确发生错误/异常,这也很乏味且不容易)。


推荐阅读