2

我的存储过程是这样的:

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”,我会得到正确的结果,但在变量中传递值没有帮助。

有什么问题?..我错过了任何演员或其他东西吗?

4

2 回答 2

8

你有名字冲突。变量与列同名。改变变量(参数)

TypeId INT,

进入

p_TypeId INT,
于 2012-07-24T05:40:54.180 回答
4

在编写存储过程时,您总是希望有某种命名约定来区分局部变量、过程参数和数据库列。由于标识符首先使用表中列的名称解析,然后使用局部变量或参数的名称解析,因此WHERE子句的两侧

WHERE cd.TYPEID=TypeId;   

解析为表的TypeIDDetails。此查询永远不会查看参数中的值TypeID

如果您采用标准命名约定(即用 为参数添加前缀,用 为p_局部变量添加前缀l_),您就不必担心引入范围解析错误。

像这样的东西应该可以工作(尽管您使用的数据类型非常不寻常LONG-例如,已被弃用很长时间,因此您确实应该在VARCHAR2那里使用 a (或者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;
于 2012-07-24T05:48:18.210 回答