我想構建一個存儲過程來封裝一些複雜的邏輯。以下是基本代碼,有點匿名:爲什麼這個存儲過程返回一個空集?
SET TERM^;
RECREATE PROCEDURE GET_DATA (
USERID INTEGER,
W INTEGER,
X INTEGER,
Y INTEGER)
RETURNS (
ID INTEGER,
NAME VARCHAR(64) CHARACTER SET UTF8)
AS
BEGIN
select first 1
QP.ID,
QO.NAME
from QP
join QO
on QO.ID = QP.QO_ID
where
(QO.W = :w) and (QO.X = :x) and (QO.Y = :y)
and ((QP.PREREQUISITE in (
select VALUE
from LOOKUP_TABLE1
where USER_ID = :userid))
or (QP.PREREQUISITE is null))
and (QO.Q_ID not in (
select VALUE
from LOOKUP_TABLE2
where USER_ID = :userid))
order by QP.SEQUENCE desc
into :ID, :NAME;
suspend;
END^
SET TERM ;^
它預計會返回1或0的結果。這在邏輯上是正確的;如果我採取SELECT
查詢,手動替換參數,並在Firebird Maestro中運行它,它會給出預期的結果。但是如果我說select ID, NAME from GET_DATA(1, 1, 2, 3)
,使用相同的參數,我得到一個空的結果集。
因此,在存儲過程級別出現問題。任何人都知道它是什麼以及我如何解決它?
是'LOOKUP_TABLE2.VALUE'可爲空場?因爲' NOT IN()'如果''的結果集包含NULL,則永遠不會成立。 (如果這是問題,那麼修正是將'和VALUE不爲空'添加到子查詢中。) –
ruakh
2012-03-26 18:01:11
@ruakh:不,兩個查找表都有NOT NULL約束。就像我說的那樣,查詢在邏輯上是正確的;當我將它作爲存儲過程運行時,它不會運行任何結果。 – 2012-03-26 18:02:35
@Mason會很好,如果你發佈DDL statemenst這些表和一些示例數據,所以我們可以重新創建它 - SP似乎是好的 – JustMe 2012-03-27 06:45:41