2013-07-06 92 views
2

編輯//問題解決 - 我已將我的代碼重新編寫成PL/SQL包和函數,因此現在可以簡單地使用標準選擇語句。我將在下面留下我的原始查詢,以及我發現對於處於類似位置的任何人都有用的幾個鏈接。無法讓dbms_output在PHP中工作(連接到Oracle數據庫)

鏈接

原始查詢

我一直試圖很長一段時間來讓我的PHP代碼成功處理我的PL/SQL dbms_output。我似乎無法得到它的工作。其餘的代碼工作,並在SQL開發人員,我得到正確的輸出。錯誤報告也起作用,就像我遺漏了任何代碼一樣,我得到報告的錯誤(例如,不緩存網絡)。這只是沒有給我最終的結果。這裏是我的代碼在PHP中的dbms_output部分。

// Fetch and display any dbms_output 
function DisplayDbmsOutput($con) 
{ 
    $r = GetDbmsOutput($con); 

if (!$r) 
    print "<p>Error getting dbms_output</p>\n"; 
else 
    foreach ($r as $line) 
     echo $line."<br>\n"; 
} 

// Returns an array of dbms_output lines, or false. 
function GetDbmsOutput($con) 
{ 
    $res = false; 
    $stid = doParse($con, "BEGIN DBMS_OUTPUT.GET_LINE(:LN, :ST); END;"); 
    if ($stid) { 
    if (doBind($stid, ":LN", $ln, 255) && 
     doBind($stid, ":ST", $st, "")) { 
     $res = array(); 
     while ($succ = doExecute($stid)) { 
     if ($st) 
      break; 
     $res[] = $ln; 
     } 
     if (!$succ) 
     $res = false; 
    } 
    @OCIFreeStatement($stid); 
    } 
    return ($res); 
} 

// Cache Network 
CacheNetwork($con, true); 

// turn serveroutput on 
SetServerOutput($con, true); 

// Create dbms_output 
$s = doParse($con, " 
DECLARE 
cost NUMBER; 
path_id NUMBER; 
res_numeric NUMBER; 
res_array SDO_NUMBER_ARRAY; 
Nav_Info Test_Turns.Navigation_Info%TYPE; 
Walk_Dist chadwick_link$.cost%TYPE; 
Starting_Node_ID chadwick_link$.Start_Node_ID%TYPE; 
Ending_Node_ID chadwick_link$.End_Node_ID%TYPE; 
start_node_id Number; 
goal_node_id Number; 
goal_node varchar(20); 
txtArray dbms_output.chararr; 
numLines integer := 4; 

BEGIN 
start_node_id := 34; 
goal_node_id := 19; 
goal_node := '%' || ' ' || (to_Char(goal_node_id)) || ',' || '%'; 

path_id := sdo_net_mem.network_manager.shortest_path('CHADWICK', start_node_id, goal_node_id); 
cost := SDO_NET_MEM.PATH.GET_COST('CHADWICK', path_id); 
res_array := SDO_NET_MEM.PATH.GET_LINK_IDS('CHADWICK', path_id); 
FOR indx IN res_array.FIRST..res_array.LAST 
LOOP 
    Select Start_Node_ID INTO Starting_Node_ID from chadwick_link$ where Link_ID = res_array(indx); 
    Select End_Node_ID INTO Ending_Node_ID from chadwick_link$ where Link_ID = res_array(indx); 
    Select Navigation_Info INTO Nav_Info from Test_Turns_Two where Starting_Node = Starting_Node_ID and Finishing_Node = Ending_Node_ID and possible_finish_nodes Like goal_node; 
    select cost INTO Walk_Dist from chadwick_link$ where link_id = res_array(indx); 
    DBMS_OUTPUT.PUT(Nav_Info || ' ' || Walk_Dist || ' meters'); 
END LOOP; 
DBMS_OUTPUT.PUT('You have arrived at your destination'); 
DBMS_OUTPUT.PUT(' '); 
END; 
"); 
if ($s) 
doExecute($s); 

// Display the output 
DisplayDbmsOutput($con); 

任何建議將是美好的!

+0

你是否追查過這段代碼以確定它出錯的地方?特別是,DisplayDbmsOutput有沒有被調用,它是否曾經進入應該調用'DBMS_OUTPUT.GET_LINE'的代碼? –

+0

當我運行它時,它返回「Error getting dbms_output」,所以我認爲它必須是getDmbsOutput中的一個問題,因爲如果(!$ r)[$ r = GetDbmasOutput]返回。我不確定它爲什麼會失敗。 – Xanphis

+0

在我看來,無論是'doParse'還是'doExecute'都沒有返回有效值,或者其中一個'doBind'調用失敗。這些例程是你寫的東西嗎?如果是這樣,也許你可以添加一些代碼來打印更多關於哪裏出錯的東西。 –

回答

2

DBMS_OUTPUT寫入和讀取緩衝區。此軟件包最常見的用途是在客戶端(如SQL * Plus)中顯示文本,該文件內置支持通過其set serveroutput on命令自動顯示緩衝區。

但是,我們以編程方式使用軟件包。

  1. 我們需要初始化緩衝區:dbms_output.enable()
  2. 然後我們寫緩衝區:dbms_output.put_line()當我們想顯示什麼,我們已經寫了,我們需要從緩衝區檢索
  3. dbms_output.get_line() - 或dbms_output.get_lines()如果有很多
  4. 最後關閉緩衝區dbms_output.disable()

的文檔有進一步的我信息,和一些工作的例子。 Find out more.


我想真正的問題是爲什麼您使用DBMS_OUTPUT。在程序單元或體系結構層之間傳遞消息通常有更好的機制。

+0

謝謝你的回答。我的代碼中已經有4分,我已經將啓用和禁用從所示的腳本中除去了。它仍然不起作用...我已經通過了文檔,它並沒有真正幫助我。使用它的原因很簡單,因爲它是我知道如何從PL/SQL子程序(最短路徑)獲取輸出的唯一途徑。 – Xanphis