2011-07-25 52 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