2016-12-05 113 views
0

我試圖將$ PRODUCT_NUM數組傳遞給pl-sql塊,然後爲數組中的兩個產品編號的每一個執行存儲函數,並將結果集發送回php。我對pl-sql並不熟悉,並希望得到一些關於如何實現這一點的指導?我的意圖是構建一個基於REST的Web svc,在清理完成後調用下面的PHP代碼。不知道我是否想爲下面的sql塊創建一個存儲過程,因爲我預計每分鐘下面的代碼會有1000個命中。如何將數組傳遞給plsql塊並將結果集返回給php?

<?php 
$conn = oci_connect("username","password","localdb"); 

$CONFIG_NAME='DirectType'; 
$BUS_SEG_CODE=''; 
$PRODUCT_NUM=array('130342','270179'); 
$MEMBER_NAME='87307-3'; 
$EFFECTIVE_DATE=strtotime('2016-12-01'); 
$MODEL_DATE=time(); 
$CURRENCY='USD'; 
$REALM_NUM=1024; 
$RESOLVED_PRICE=111; 
$RESOLVED_CURRENCY='USD'; 

if ($conn) { 
    echo "Connection Successful"."\n"; 
    echo "System time is ".time(); 

    $sql_proc = " 
    DECLARE 
     v_MEMBER_ID NUMBER; 
     v_PRODUCT_ID NUMBER; 
     PRODUCTNUMBER NUMBER; 
     BASEPRICE NUMBER; 
     RESOLVEDPRICE NUMBER; 
     UPCHARGEAMOUNT NUMBER; 
     CURRENCY VARCHAR2; 
     PRICINGDOCNAME VARCHAR2(100); 
     TIER_INDEX NUMBER; 
     DOC_ID VARCAHR2(100); 
    BEGIN 
      SELECT cat_map_id INTO v_PRODUCT_ID 
      FROM CAT_MAP WHERE product_num IN :PRODUCT_NUM_ARR and catalog_type = 'INT'; 

      SELECT member_id INTO v_MEMBER_ID 
      FROM MEMBER_TABLE WHERE member_name = :MEMBER_NAME; 

      v_PMLI_PK := PACKAGE.function(:CONFIG_NAME,:BUS_SEG_CODE,v_MEMBER_ID,v_PRODUCT_ID,TO_TIMESTAMP(TO_DATE(:EFFECTIVE_DATE,'YYYY-MM-DD')),TO_TIMESTAMP(TO_DATE(:MODEL_DATE,'YYYY-MM-DD')), 
                  :CURRENCY_CODE,:REALM_NUM,:RESOLVED_PRICE,:RESOLVED_CURRENCY); 

     SELECT 
      PMLI.PRODUCT_NUM INTO PRODUCTNUMBER, 
      PMLI.BASE_PRICE INTO BASEPRICE, 
      PMLI.PRICE INTO RESOLVEDPRICE, 
      PMLI.UP_CHARGE INTO UPCHARGEAMOUNT, 
      PMLI.PRICE_CURR INTO CURRENCY, 
      NULL, 
      DOC.STRUCT_DOC_NAME INTO PRICINGDOCNAME, 
      PMLI.TIER_INDEX INTO TIER_INDEX, 
      NULL, 
      PMLI.DOC_ID INTO DOC_ID, 
      NULL 
      FROM P_MASTER PMLI 
      INNER JOIN DOC_TABLE DOC 
      ON (PMLI.STRUCT_DOC_ID = DOC.STRUCT_DOC_ID) 
      WHERE PMLI.PMLI_ID = v_PMLI_PK; 

    END; 


    $stmt = oci_parse($conn,$sql_proc); 
    // Bind the input parameter 

oci_bind_by_name($stmt,':CONFIG_NAME',$CONFIG_NAME); 
oci_bind_by_name($stmt,':BUS_SEG_CODE',$BUS_SEG_CODE); 
oci_bind_by_name($stmt,':EFFECTIVE_DATE',$EFFECTIVE_DATE); 
oci_bind_by_name($stmt,':MODEL_DATE',$MODEL_DATE); 
oci_bind_by_name($stmt,':CURRENCY_CODE',$CURRENCY); 
oci_bind_by_name($stmt,':REALM_NUM',$REALM_NUM); 
oci_bind_by_name($stmt,':RESOLVED_PRICE',$RESOLVED_PRICE); 
oci_bind_by_name($stmt,':RESOLVED_CURRENCY',$RESOLVED_CURRENCY); 

// Parse the statement. Note there is no final semi-colon in the SQL statement 
$result=oci_execute($stmt); 

if (!$result){ 
    $e = oci_error($stmt); // For oci_execute errors pass the statement handle 
    print htmlentities($e['message']); 
    print "\n<pre>\n"; 
    print htmlentities($e['sqltext']); 
    printf("\n%".($e['offset']+1)."s", "^"); 
    print "\n</pre>\n"; 

} 
else { 
    echo "Execute STMT returns True or False : ".$result; 
    echo "Resolved Price is : ".$RESOLVED_PRICE. "\n"; 
} 
echo "</pre>"; 
oci_free_statement($stmt); 
oci_close($conn); 
} 
else { 
$e = oci_error(); 
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR); 
} 
    ?> 
+0

請看看[mcve]構建更簡潔的示例 – Aleksej

回答

0

我的建議是,你創建你的SQL塊作爲數據庫中的存儲過程。

https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_6009.htm

讓你的程序接受一個參數,一個集合(表型要準確)。 在數據庫中創建一個表類型:

CREATE TYPE myRec AS OBJECT (NUMBER(10)); 
    CREATE TYPE myTab AS TABLE OF myRec; 

你的程序必須接受型MYTAB的PARAM:

PROCEDURE p_myProc(param1 myTab) IS... 
在PHP代碼

然後,只需調用這個過程:

$sql_proc = "p_myproc(yourPHPArrayVariable)"; 

請注意,你必須確保數據類型是同步的..我的意思是不要傳遞字符,如果你的數據庫中的基礎記錄是數字,如我的例子。

+0

我正在構建一個基於REST的Web Svc,使用PHP執行現有的Oracle存儲功能。所以我不確定我是否希望在數據庫中建立一個存儲過程,因爲我預計每分鐘會有大約1000次點擊。 –

+0

我正在追求你的建議。我放棄了通過OCI接口執行sql並從數組中獲取結果。這是多麼錯誤纏身。什麼對我來說是綁定從oracle存儲函數返回的變量。我會堅持! –

+0

很酷。如果這有一些負面影響,請做評論。 –

相關問題