2015-05-18 40 views
0

我創建了以下存儲過程在Oracle中:執行SQL存儲過程傳遞變量

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')AND 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頁面上沒有輸入的日期範圍,那麼WHEREDATE是空白SP和SQL在存儲過程(SP)中運行時沒有任何範圍或附加任何附加語法。

當用戶進入PHP頁面上的時間範圍,則WHEREDATE PARAM變爲:

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

什麼數據類型是'created_on'?我猜這是一個日期,你有不同的NLS設置,你的隱式轉換不會以正確的值結束。如果是日期,那麼你不應該爲它調用'to_date'。請澄清類型,並添加樣本值。 –

回答

1

好吧,出現了一些問題。

首先,我建議您將cnt參數的聲明從LONG更改爲NUMBERLONG不是Oracle中的數字類型;相反,這是一種LOB,其使用已被棄用。如果您確實想要返回LOB,請使用BLOBCLOB(以適用者爲準)。

其次,不能傳入包含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處理程序 - 在任何程序中總是一個好主意。

分享和享受。