2016-05-17 106 views
1
 CREATE OR REPLACE PACKAGE BODY simpleState IS 

     PROCEDURE selectFromTable(tableName VARCHAR2, columnName VARCHAR2) IS 
     TYPE c1 IS TABLE OF VARCHAR2(30); 
     Notes c1; 
     BEGIN 
     EXECUTE IMMEDIATE 'Select ' || columnName || ' FROM ' || tableName BULK COLLECT INTO Notes; 
     FOR idx IN Notes.FIRST .. Notes.LAST LOOP 
      DBMS_OUTPUT.PUT_LINE(Notes(idx)); 
     END LOOP; 
     END selectFromTable; 


    $conn = oci_connect("student", "STUDENT", "localhost"); 

    if (!$conn) { 
     $m = oci_error(); 
     echo $m['message'], "\n"; 
     exit; 
    } 

else { 
    print "Connected to Oracle!"; 
} 


    if(isset($_POST["readSubmit"])){ 

     $table = $_POST['ReadTableName']; 
     $column = $_POST['ReadColumn']; 

     $stid = oci_parse($conn, 'begin simpleState.selectFromTable(:a,:b); end;'); 

     ocibindbyname($stid, 'a', $table); 
     ocibindbyname($stid, 'b', $column); 

     if (!$stid) { 
      $e = oci_error($conn); 
      trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR); 
     } 


      $r = oci_execute($stid); 
      echo "$r"; 
     oci_free_statement($stid); 
     oci_close($conn);  
     } 

     ?> 

我試圖在使用PHP的瀏覽器中的DBMS_OUPUT.PUT_LINE中顯示消息。但它不顯示任何東西。 PL/SQL代碼工作並顯示它必須在SQL Developer中顯示的內容。誰能幫我這個?在oracle中獲取來自oracle的dbms輸出消息

+1

你爲什麼要這麼做? DBMS_OUTPUT通常只用於adhoc消息 - 例如。用於測試目的 - 而不是將數據從一個系統傳遞到另一個系統的方法。如果我是你,我會調查ref遊標 - 這是將select語句中的數據傳回給調用代碼的首選解決方案。 – Boneist

+0

那麼,需要一個快速的解決方案來集成一個用戶界面的pl/sql過程(像html頁面一樣簡單) – student0495

+0

哦,我已經嘗試過ref遊標.... – student0495

回答

2

前幾天我有同樣的問題,但我很懶,我停止尋找解決方案,但是,我現在找到了解決方案。

而是一個過程,我創建了一個返回SYS_REFCURSOR的函數。

CREATE OR REPLACE FUNCTION selectFromTable(tableName VARCHAR2, columnName VARCHAR2) 
    RETURN SYS_REFCURSOR 
AS 
    my_cursor SYS_REFCURSOR; 
    s_query varchar2(500); 
BEGIN 

    s_query := 'SELECT ' || columnName || ' FROM ' || tableName; 

    OPEN my_cursor FOR s_query; 

    RETURN my_cursor; 
END selectFromTable; 
/

PHP代碼很簡單。

<?php 
    $conn = oci_connect('student', 'STUDENT', 'localhost/XE'); 
    if (!$conn) { 
     $e = oci_error(); 
     trigger_error(htmlentities($e('message'), ENT_QUOTES), E_USER_ERROR); 
    } 

    $tablename = 'STUDENTI'; 
    $columnname = 'NR_MATRICOL'; 

    $query = "begin 
       :cursor := selectFromTable(:tabl, :colm); 
      end;"; 

    $stid = oci_parse($conn, $query); 

    $p_cursor = oci_new_cursor($conn); 

    oci_bind_by_name($stid, ":tabl", $tablename); 
    oci_bind_by_name($stid, ":colm", $columnname); 

    oci_bind_by_name($stid, ":cursor", $p_cursor, -1, OCI_B_CURSOR); 

    oci_execute($stid); 
    oci_execute($p_cursor, OCI_DEFAULT); 

    while (($row = oci_fetch_array($p_cursor, OCI_ASSOC+OCI_RETURN_NULLS)) != false) { 
     echo $row['NR_MATRICOL'] . "<br />\n"; 
    } 
?> 

編輯: 如果需要打印更多的列,你可以簡單地添加列在這裏的名字:

$columnname = 'NR_MATRICOL, NUME, PRENUME'; 

,你需要添加回聲太:

echo $row['NR_MATRICOL'] . " - "; 
echo $row['NUME'] . " - "; 
echo $row['PRENUME'] . "<br >"; 

輸出應該如下所示:

111 - Popescu - Bogdan 
112 - Prelipcean - Radu 
123 - Bucur - Andreea 
131 - Santa - Claus 
+0

我已經用ref遊標嘗試過了,我也會嘗試你的解決方案。謝謝! – student0495

+0

工作完美!謝謝! – student0495

0

經過深入研究,我發現我實際上無法從dbms_output中獲取某些東西,所以我已經爲我的問題提供了一種解決方案。我已經在我的PL/SQL過程中添加了一個OUT參數,並將所有結果連接起來。我已經添加了chr(10)以在Oracle中有新行和模擬不同的行結果。

因此我已將PROCEDURE selectFromTable(tableName VARCHAR2, columnName VARCHAR2, p_out OUT VARCHAR2);和修改爲DBMS_OUTPUT.PUT_LINE(Notes(idx));轉換爲p_out := p_out || Notes(idx) || chr(10);。我還添加了anoter:c variabile到我的PHP函數,併爲它添加了ocibindbyname($stid, 'c', $outVal, 300);

+0

作爲對此解決方案的說明,chr(10)僅適用於SQL Developer ...在PHP中,它沒有顯示它作爲一個新的線不幸。 – student0495

+0

也許你需要'chr(13)|| chr(10)'而不是'chr(10)'? – Boneist

+0

在SQL Developer中,chr(10)就足夠了,我也試過用chr(13)|| chr(10),正如你所說的,但它在PHP中是一樣的(所有結果都顯示在一行中) – student0495