我的存储过程如下:
CREATE OR REPLACE PROCEDURE Proc_SearchRequests
(
RequestedBy LONG,
FromDate DATE DEFAULT NULL,
ToDate DATE DEFAULT NULL,
RequestedByDesignation VARCHAR2 DEFAULT NULL,
TypeId INT,
CurrentStatusId INT DEFAULT NULL,
AmountFrom LONG DEFAULT NULL,
AmountTo LONG DEFAULT NULL,
cur_ExcelOutput OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cur_ExcelOutput FOR
SELECT cd.*,
emp.FIRSTNAME || ' ' || emp.LASTNAME AS ADDEDBYNAME
FROM
DETAILS cd
LEFT JOIN EMPLOYEES emp ON cd.ADDEDBY = emp.EMPLOYEEID
WHERE
cd.TYPEID=TypeId;
END;
我正在通过执行程序:
BEGIN
PROC_SEARCHREQUESTS (110, to_date ('2001-01-01', 'YYYY-MM-DD'), to_date ('9999-12-31 23:59:59', 'YYYY-MM-DD HH24:MI:SS'), null, 2, 0, 0, 0, :cur_exceloutput$REFCURSOR);
END;
但无论我作为TypeId传递的是什么,我都会得到完整的数据而不是过滤后的数据。 如果我写" cd.TYPEID = 2"我得到了正确的结果,但在varible中传递价值并没有帮助。
可能出现什么问题?我错过任何演员或其他什么东西吗?
答案 0 :(得分:7)
你有名字冲突。该变量与列具有相同的名称。 更改变量(参数)
TypeId INT,
进入
p_TypeId INT,
答案 1 :(得分:4)
在编写存储过程时,总是希望使用某种命名约定来区分局部变量,过程参数和数据库列。由于首先使用表中列的名称解析标识符,然后使用局部变量或参数的名称,WHERE
子句的两边
WHERE cd.TYPEID=TypeId;
解析为TypeID
表的Details
列。此查询不会查看参数TypeID
中的值。
如果您采用标准命名约定(即使用p_
添加前缀参数和使用l_
添加局部变量),则无需担心引入范围解析错误。
这样的事情应该有用(虽然您使用的数据类型非常不寻常 - 例如,LONG
已被弃用了很长时间,因此您应该使用VARCHAR2
那里(或CLOB
,如果你真的需要超过32k,这似乎不太可能给名字))。
CREATE OR REPLACE PROCEDURE Proc_SearchRequests
(
p_RequestedBy LONG,
p_FromDate DATE DEFAULT NULL,
p_ToDate DATE DEFAULT NULL,
p_RequestedByDesignation VARCHAR2 DEFAULT NULL,
p_TypeId INT,
p_CurrentStatusId INT DEFAULT NULL,
p_AmountFrom LONG DEFAULT NULL,
p_AmountTo LONG DEFAULT NULL,
p_cur_ExcelOutput OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_cur_ExcelOutput FOR
SELECT cd.*,
emp.FIRSTNAME || ' ' || emp.LASTNAME AS ADDEDBYNAME
FROM
DETAILS cd
LEFT JOIN EMPLOYEES emp ON cd.ADDEDBY = emp.EMPLOYEEID
WHERE
cd.TYPEID=p_TypeId;
END;