복잡한 논리를 캡슐화하기 위해 저장된 proc 파일을 빌드하려고합니다. 다음은 익명으로 처리 한 기본 코드입니다.왜이 저장 프로 시저가 빈 집합을 반환합니까?
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''null 허용 필드인가? 왜냐하면 ''의 결과 세트가 'NULL'을 포함하면 ' NOT IN ()'이 참일 수 있기 때문입니다. (그게 문제라면, 문제는 서브 쿼리에'VALUE is not null'을 추가하는 것입니다.) –
ruakh
@ruakh : 아니요, 두 룩업 테이블에는 NULL 제약 조건이 없습니다. 내가 말했듯이, 쿼리는 논리적으로 정확합니다. 저장 프로 시저로 실행할 때 어떤 결과도 실행되지 않습니다. –
@Mason이 테이블과 일부 샘플 데이터를 DDL 상태로 게시하여 다시 만들 수 있으면 좋을 것입니다 - SP는 괜찮은 것 같습니다 – JustMe