2011-07-25 51 views
2

我使用Firebird 2.5 64bit版本。我有两张表Master(A)和Detail(B),我为B设置了级联更新和删除,因此如果我删除了Master中的一条记录,任何相关记录的详细信息也将被删除。Firebird存储过程中的“select..into”

我设置了一个删除触发器表B中执行,并传递参数给存储过程后

该存储过程具有以下SQL:

select STATUS from A 
    where A.PK_id = :PK_id 
    INTO :var_status; 

的问题是,我总是得到NULL为变量var_status虽然我检查它在SQL编辑器中,我得到1这是正确的值,我也检查(使用IBexpert调试器)传递的参数:PK_id,它也是正确的!

为什么我得到存储在这个变量中的错误值。

+0

你可以发布更多的代码,显示如何声明和使用var_status和PK_id? – Re0sless

+0

在SP中声明的var_status id为smallint,PK_ID是表A的主键字段 – Welliam

回答

3

可能的问题是您正在使用AFTER DELETE并且该记录不存在了。下面是操作的顺序:

  • 记录会从一个
  • 删除第B
  • B中的AFTER DELETE触发器被称为删除从A级联删除操作。
  • 从触发器内部,您尝试访问不是来自B的数据,而是来自A的数据。它不再存在。

请记住,触发器在事务内部运行。因此,当您运行相同的SELECT时,您可以访问该值,因为您处于另一个事务中,并且原始事务尚未提交。

实际上这并不那么微不足道。这里有几个选项,以解决您的问题:

  • 检查您的业务规则是可以改变的,这样你不能在B中的触发运行的代码的一部分,但在A,其中的地位将可。毕竟,您需要做的是因为A而不是B。
  • 最终,您可以删除cascade delete并处理B中AFTER DELETE触发器中的B的删除操作。这样,所有内容都将位于同一个块中的代码。
+0

你是天才!在我检查重播之前的几分钟,我刚才发现了这一点(对于糟糕的描述,抱歉) - 现在因为我不想写两个触发器做同样的事情,因为用户必须能够从B中删除一条记录 - 是否有办法修改事务,以便我可以读取未提交的数据(从A删除的记录)? - 或者我应该创建额外的表来传递参数? – Welliam

+0

尽管可能,但您不应该阅读未编写的数据。永远。你会解决一个问题,并创建10个问题。另外,创建仅用于参数传递的表格并不好。你有没有考虑过创建一个存储过程?它可以从两个触发器中调用,并且可以正确传递参数。 –

+0

你是对的,但从B删除记录我会从Delphi代码中调用SP,我希望从DB中这样做 - 只是为了知识,我怎样才能读取触发器中的未定义数据? – Welliam