2017-10-15 190 views
0

你能幫我傳遞輸入值(在執行時:我的意思是一次輸入單個變量的多個值)。如何一次讀取多個值作爲PLSQL中單個變量的輸入?

這裏是我的代碼,我一次只給一個輸入一個硬編碼輸入或一個輸入。

declare 
    type TEmpRec is record (
    EmployeeID EMPLOYEES.EMPLOYEE_ID%TYPE, 
    LastName EMPLOYEES.LAST_NAME%TYPE 
); 
    type TEmpList is table of TEmpRec; 
    vEmpList TEmpList; 
    --------- 
    function EmpRec(pEmployeeID EMPLOYEES.EMPLOYEE_ID%TYPE, 
        pLastName EMPLOYEES.LAST_NAME%TYPE default null) return TEmpRec is 
    -- Effective "Record constructor" 
    vResult TEmpRec; 
    begin 
    vResult.EmployeeID := pEmployeeID; 
    vResult.LastName := pLastName; 
    return vResult; 
    end; 
    --------- 
    procedure SearchRecs(pEmpList in out nocopy TEmpList) is -- Nocopy is a hint to pass by reference (pointer, so small) rather than value (actual contents, so big) 
    vIndex PLS_integer; 
    begin 
    if pEmpList is not null then 
     vIndex := pEmpList.First; 
     while vIndex is not null -- The "while" approach can be used on sparse collections (where items have been deleted) 
     loop 
     begin 
      select LAST_NAME 
      into pEmpList(vIndex).LastName 
      from EMPLOYEES 
      where EMPLOYEE_ID = pEmpList(vIndex).EmployeeID; 
     exception 
      when NO_DATA_FOUND then 
      pEmpList(vIndex).LastName := 'F'||pEmpList(vIndex).EmployeeID; 
     end; 
     vIndex := pEmpList.Next(vIndex); 
     end loop; 
    end if; 
    end; 
    --------- 
    procedure OutputRecs(pEmpList TEmpList) is 
    vIndex PLS_integer; 
    begin 
    if pEmpList is not null then 
     vIndex := pEmpList.First; 
     while vIndex is not null 
     loop 
     DBMS_OUTPUT.PUT_LINE ('pEmpList(' || vIndex ||') = '|| pEmpList(vIndex).EmployeeID||', '|| pEmpList(vIndex).LastName); 
     vIndex := pEmpList.Next(vIndex); 
     end loop; 
    end if; 
    end; 
begin 
    vEmpList := TEmpList(EmpRec(100), 
         EmpRec(34), 
         EmpRec(104), 
         EmpRec(110)); 
    SearchRecs(vEmpList); 
    OutputRecs(vEmpList); 
end; 
/

上面的程序在時間上取值爲1。 但是,我試着如下,但無法成功。

我試圖從控制檯一次輸入輸入(100,34,104,100),而不是對輸入(或)在輸入時進行硬編碼。

片段在DECLARE部分:

declare 
    type TEmpRec is record (
    EmployeeID EMPLOYEES.EMPLOYEE_ID%TYPE, 
    LastName EMPLOYEES.LAST_NAME%TYPE 
); 
    type TEmpList is table of TEmpRec; 
    v_input TEmpList := TEmpList(&v_input); -- to read multiple input at once 
    vEmpList TEmpList; 

在最後BEGIN部分:

BEGIN 
FOR j IN v_input.FIRST .. v_input.LAST LOOP 
    vEmpList := TEmpList(EmpRec(v_input(j).EmployeeID)); --to assign input values to vEmptList 

    SearchRecs(vEmpList); 
    OutputRecs(vEmpList); 
end loop; 
end; 
/

錯誤DECLARE部分: PLS-00306:錯誤數量或類型的參與調用'TEMPLIST' 最後一個錯誤ction: PLS-00320:這個表達式的類型的聲明不完整或畸形

作爲一個例子:在時間,我能夠讀取相同的變量多個輸入值,但我無法通過這是一個輸入,但無法弄清楚如何使這個作爲輸入我的主程序。

DECLARE 
TYPE t IS TABLE OF VARCHAR2(100); 
ORDERS t := t(&ORDERS); 
BEGIN 
FOR j IN ORDERS.FIRST .. ORDERS.LAST LOOP 
dbms_output.put_line(ORDERS(j)); 
END LOOP; 
END; 
/

輸出: PL/SQL過程已成功完成。 訂單輸入值:321153678

謝謝。

+0

'TEmpRec'是一個普通的PL/SQL記錄類型,所以它沒有構造函數。如果你想要一個構造函數,你需要創建一個對象類型。如果您想要更詳細的答案,[mcve](https://stackoverflow.com/help/mcve)會使問題更清楚。 –

回答

0

由於您有一個record變量的集合,您需要分別通過employee_ids和員工last_names。你打算如何通過一個鏡頭通過他們? 下面是一個示例腳本,它用3個收集元素的2個輸入實現了您想要的內容。

首先,創建一個集合TYPE和一個PIPELINED function將逗號分隔值轉換爲Collections - f_convert2

CREATE TYPE test_type AS TABLE OF VARCHAR2(100); 


CREATE OR REPLACE FUNCTION f_convert2(p_list IN VARCHAR2) 
    RETURN test_type 
PIPELINED 
AS 
    l_string  LONG := p_list || ','; 
    l_comma_index PLS_INTEGER; 
    l_index  PLS_INTEGER := 1; 
BEGIN 
    LOOP 
    l_comma_index := INSTR(l_string, ',', l_index); 
    EXIT WHEN l_comma_index = 0; 
    PIPE ROW (SUBSTR(l_string, l_index, l_comma_index - l_index)); 
    l_index := l_comma_index + 1; 
    END LOOP; 
    RETURN; 
END f_convert2; 
/

然後在您的匿名塊中分別爲employee_ids和last_name傳遞值。

SET SERVEROUTPUT ON 
DECLARE 
    TYPE temprec IS RECORD (employeeid employees.employee_id%TYPE, 
    lastname  employees.last_name%TYPE); 
    TYPE templist IS 
     TABLE OF temprec; 
    vemplist  templist; 
    v_no_of_rec NUMBER := 10; 

    v_empl_ids VARCHAR2(100) := '&empl_ids'; 
    v_empl_lnames VARCHAR2(100) := '&empl_lnames'; 
BEGIN 
SELECT employee_id,last_name 
    BULK COLLECT 
INTO 
    vemplist 
FROM 
    (
     SELECT 
      ROWNUM rn, 
      column_value employee_id 
     FROM 
      TABLE (f_convert2(v_empl_ids)) 
    ) a 
    JOIN (
     SELECT 
      ROWNUM rn, 
      column_value last_name 
     FROM 
      TABLE (f_convert2(v_empl_lnames)) 
    ) b ON a.rn = b.rn; 

     FOR i in 1..vemplist.COUNT LOOP 
     DBMS_OUTPUT.PUT_LINE(vemplist(i).employeeid || ' ' ||vemplist(i).lastname); 
     END LOOP; 
END; 
/

而不是簡單的JOIN以上,如果你使用OUTER JOINFULLLEFT),你可以處理,而無需編寫邏輯來檢查每個值遺漏值。

+0

謝謝Kaushik。我會試試這個。實際上,我不僅讀訪問我的數據庫,我只能寫匿名塊,我的輸入只是員工ID(一次有多個值) – Veeresh

+0

在這種情況下,您可以使用declare定義TYPE和函數。 –

+0

當我嘗試上面的代碼,我遇到以下錯誤。 PLS-00231:函數'F_CONVERT2'不能在SQL中使用 – Veeresh

相關問題