我在Oracle中创建了以下存储过程:
create or replace
PROCEDURE APPUSERCT
(
PROJNAME IN VARCHAR2
, WHEREDATE IN VARCHAR2 ,
cnt OUT long
) AS
BEGIN
select count(Distinct UPPER(field1)) into cnt from bs_log where application_name=PROJNAME and field1 is not null and log_type='info' || WHEREDATE;
END APPUSERCT;
在我的php页面中,WHEREDATE设置为:
$ whereDate =“和(TO_DATE(created_on,'mm / dd / yyyy HH24:MI:SS')> = TO_DATE('”。$ startDate。“','mm / dd / yyyy')和TO_DATE (created_on,'mm / dd / yyyy HH24:MI:SS')< = TO_DATE('“。$ endDate。”','mm / dd / yyyy'))“;
然后我绑定参数和值并调用SP:
$sql = 'BEGIN APPUSERCT(:projName,:whereDate,:cnt); END;';
$result = oci_parse($dbconn, $sql);
oci_bind_by_name($result,':cnt',$totalRowCount,32);
oci_bind_by_name($result,':projName',$projName,32);
oci_bind_by_name($result,':whereDate',$whereDate,200);
oci_execute($result);
如果用户在php页面上没有输入日期范围,则SP中的WHEREDATE为空,并且SQL运行时没有任何范围或任何附加语法在Store Procedure(SP)中附加到它的末尾。
当用户在php页面上输入日期范围时,WHEREDATE参数变为:
and (TO_DATE(created_on,'mm/dd/yyyy HH24:MI:SS')>=TO_DATE('05/01/2015','mm/dd/yyyy') AND TO_DATE(created_on,'mm/dd/yyyy HH24:MI:SS')<=TO_DATE('05/07/2015','mm/dd/yyyy'))
并将其附加到SP中SQL的末尾。但每当发生这种情况时,我的php页面总是从执行的SQL返回0个计数。没有错误,只有0计数。
如果我尝试直接在Oracle中运行SQL,那就是:
select count(Distinct UPPER(field1)) as cnt from bs_log where application_name='Myweather' and field1 is not null and log_type='info' and (TO_DATE(created_on,'mm/dd/yyyy HH24:MI:SS')>= TO_DATE('05/01/2015','mm/dd/yyyy') AND TO_DATE(created_on,'mm/dd/yyyy HH24:MI:SS')<= TO_DATE('05/07/2015','mm/dd/yyyy'))
我得到了结果。我得到了倒数。但是当我通过程序调用它时,我得到0.有人能看出原因吗?
谢谢!
答案 0 :(得分:1)
好吧,出现了几个问题。
首先,我建议您将cnt
参数的声明从LONG
更改为NUMBER
。 LONG
不是Oracle中的数字类型;相反,它是一种不推荐使用的LOB。如果您真的想要使用BLOB
或CLOB
,请选择适当的LOB。
其次,您不能传入包含WHERE子句的一部分的字符串(WHEREDATE
参数),并将其连接到SQL语句的末尾。在这种情况下,您将WHEREDATE中的文本连接到字符串文字info
,我怀疑这不是您的想法。您应该以类似于以下的方式使用动态SQL:
create or replace PROCEDURE APPUSERCT(PROJNAME IN VARCHAR2,
WHEREDATE IN VARCHAR2,
cnt OUT NUMBER)
AS
strSql_text VARCHAR2(32767) := 'select count(Distinct UPPER(field1)) ' ||
' from bs_log where application_name=''' || PROJNAME ||
''' and field1 is not null and ' ||
' log_type=''info'' ' || WHEREDATE;
csr SYS_REFCURSOR;
BEGIN
OPEN csr FOR strSql_text;
FETCH csr INTO cnt;
CLOSE csr;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('APPUSERCT - exception : ' || SQLCODE || ' (' ||
SQLERRM || ')');
RAISE;
END APPUSERCT;
因此,您将SQL语句构建为文本字符串,包括添加到WHERE子句,然后使用OPEN语句打开该语句的游标。然后获取光标,将结果放入cnt
,然后关闭光标,最后退出例程。我已经包含了一个默认的EXCEPTION处理程序 - 在任何例程中总是一个好主意。