2011-08-05 59 views
1

我正在編寫的存儲過程(在Oracle數據庫上)的一部分將返回一個整數值數組到一個C#應用程序。我從來沒有這樣做過,我無法在網上找到有關如何在存儲過程中執行此操作的信息。如何在存儲過程中循環訪問數組,返回數組?

在C#端,我連接到數據庫並創建了存儲過程命令。我正在使用:

cmd.Parameters.Add("returnID", OracleDbType.Array, ParameterDirection.Output); 

要抓取數組。

內的存儲過程,我有:

CREATE OR REPLACE PROCEDURE ODM(/* not relevant*/, returnIDs OUT ARRAY) 
IS 
BEGIN 
... 
END ODM; 

哪裏returnIDs是我要輸出的陣列,全整數。

我需要能夠遍歷表,ORDERS,並獲取兩個值之間的所有整數主鍵,並將它們添加到returnID。

我希望這裏的東西類似於插入到數組中,其中主鍵在最小值和最大值之間,但我不確定。

能夠聲明這些值的語法是什麼,循環遍歷表並添加到我的輸出數組中?

編輯:解決方案:Bulk Collect可以爲此工作,但只要將最小值和最大值返回到我的程序,然後在那裏做一個單獨的選擇就容易多了。

回答

5

我不確定你需要循環。根據ARRAY類型的定義,你可能只需要

SELECT primary_key 
    BULK COLLECT INTO returnIDs 
    FROM orders 
WHERE primary_key BETWEEN low_value AND high_value 
+0

謝謝。以前沒有聽說過批量收集。我會嘗試的。 – zomgcopters

+0

剛剛添加它。它看起來像會起作用,只需要開始測試它。謝謝! – zomgcopters

-1

我的db專業知識主要在sql server和firebird,我不是一個熟練的oracle人。然而,我只是好奇,難道你不能只選擇這些值並將它們作爲一個簡單的數據表或數據集返回給C#應用程序,那麼您可以將它們保存在數據表中,或者將它們轉換爲C#應用程序中的數組或集合你喜歡?

+0

只是添加到我的答案。基本上我說的是爲什麼不把值返回到前端,然後在前端處理陣列管理?這會很容易解決問題嗎? – Matt

+0

這應該是一個評論,因爲它顯然不是一個答案 – APC

+0

我管理一系列在特定日期完成的「訂單」(將日期輸入到過程中),並希望列出我剛剛管理的所有訂單。 – zomgcopters

3

所以,你需要知道的是:

  1. 我們可以使用Oracle的bulk collect語法
  2. 我們可以插入到一個數組使用the ROW_NUMBER() aggregate function爲每一行分配一個唯一的編號。

把它們放在一起變成一個像這樣的PL/SQL函數:

SQL> create or replace type numbers_nt as table of number 
    2/

Type created. 

SQL> create or replace function get_range_of_numbers 
    2 (p_start in pls_integer 
    3  , p_end in pls_integer) 
    4  return numbers_nt 
    5 is 
    6 rv numbers_nt ; 
    7 begin 
    8  select empno 
    9  bulk collect into rv 
10  from 
11   (select empno 
12     , row_number() over (order by empno asc) rn 
13   from emp) 
14  where rn between p_start and p_end; 
15  return rv; 
16 end; 
17/

Function created. 

SQL> 

讓我們的搖滾!

SQL> select * 
     2 from table(get_range_of_numbers(5, 8)) 
     3/

    COLUMN_VALUE 
    ------------ 
      7654 
      7698 
      7782 
      7788 

    SQL> 

嗯,我想我誤解你的問題。您可能想要根據鍵值而不是行位置來選擇記錄。在這種情況下,功能應該只是

create or replace function get_range_of_numbers 
    (p_start in pls_integer 
    , p_end in pls_integer) 
    return numbers_nt 
is 
    rv numbers_nt ; 
begin 
    select empno 
    bulk collect into rv 
    where emp between p_start and p_end; 
    return rv; 
end; 
/
+0

我也在這個線程中誤導了你的意見。不知道我在想什麼。這效果更好。 – zomgcopters