2009-01-01 19 views

Odpowiedz

9

Jak zauważył Chris, w PostgreSQL nie ma problemu - każdy typ bazy (np. Int, text) ma własną podtyp macierzy, a także można tworzyć typy niestandardowe, w tym złożone.Na przykład:

CREATE TYPE test as (
    n int4, 
    m int4 
); 

Teraz można łatwo utworzyć tablicę testu:

select ARRAY[ 
    row(1,2)::test, 
    row(3,4)::test, 
    row(5,6)::test 
]; 

można napisać funkcję, która będzie pomnożyć n * m dla każdego elementu w tablicy i zwraca sumę iloczynów:

CREATE OR REPLACE FUNCTION test_test(IN work_array test[]) RETURNS INT4 as $$ 
DECLARE 
    i  INT4; 
    result INT4 := 0; 
BEGIN 
    FOR i IN SELECT generate_subscripts(work_array, 1) LOOP 
     result := result + work_array[i].n * work_array[i].m; 
    END LOOP; 
    RETURN result; 
END; 
$$ language plpgsql; 

i uruchom go:

# SELECT test_test(
    ARRAY[ 
     row(1, 2)::test, 
     row(3,4)::test, 
     row(5,6)::test 
    ] 
); 
test_test 
----------- 
     44 
(1 row) 
2

Nie wskazałeś, ale jeśli masz na myśli serwer SQL, here's one way.

I wsparcie MS ref.

+0

Począwszy od SQL Server 2008, można w rzeczywistości używać zmiennych tabeli jako parametrów procedury przechowywanej. – Thorarin

4

Jeśli planujesz używać MySQL 5.1, nie można przekazać tablicy.
Zobacz MySQL 5.1 faq
Jeśli planujesz używać PostgreSQL, możliwe jest patrzeć here

2

nie wiem o przejściu rzeczywistej tablicy do tych silników (pracuję z sqlserver), ale tutaj jest pomysł na marginesie rozdzielany ciąg i analizowanie go w sproc z tą funkcją.

CREATE FUNCTION [dbo].[Split] 
(
    @ItemList NVARCHAR(4000), 
    @delimiter CHAR(1) 
) 
RETURNS @IDTable TABLE (Item VARCHAR(50)) 
AS  

BEGIN  
    DECLARE @tempItemList NVARCHAR(4000) 
    SET @tempItemList = @ItemList 

    DECLARE @i INT  
    DECLARE @Item NVARCHAR(4000) 

    SET @tempItemList = REPLACE (@tempItemList, ' ', '') 
    SET @i = CHARINDEX(@delimiter, @tempItemList) 

    WHILE (LEN(@tempItemList) > 0) 
    BEGIN 
     IF @i = 0 
      SET @Item = @tempItemList 
     ELSE 
      SET @Item = LEFT(@tempItemList, @i - 1) 
     INSERT INTO @IDTable(Item) VALUES(@Item) 
     IF @i = 0 
      SET @tempItemList = '' 
     ELSE 
      SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i) 
     SET @i = CHARINDEX(@delimiter, @tempItemList) 
    END 
    RETURN 
END 
+0

To pytanie było szczególnie zadawane w środowisku PostgreSQL lub MySql, a nie w MSSQL –

1

dla PostgreSQL, można zrobić coś takiego:

CREATE OR REPLACE FUNCTION fnExplode(in_array anyarray) RETURNS SETOF ANYELEMENT AS 
$$ 
    SELECT ($1)[s] FROM generate_series(1,array_upper($1, 1)) AS s; 
$$ 
LANGUAGE SQL IMMUTABLE; 

Następnie można przekazać ciąg rozdzielany do procedury przechowywanej.

Say, param1 był param wejściowy zawierający '1|2|3|4|5'

stwierdzenie:

SELECT CAST(fnExplode(string_to_array(param1, '|')) AS INTEGER); 

daje w wyniku zbiór wyników, które mogą być połączone lub wstawione.

Podobnie, MySQL, można zrobić coś takiego:

DELIMITER $$ 
CREATE PROCEDURE `spTest_Array` 
(
    v_id_arr TEXT 
) 
BEGIN 
    DECLARE v_cur_position INT; 
    DECLARE v_remainder TEXT; 
    DECLARE v_cur_string VARCHAR(255); 
    CREATE TEMPORARY TABLE tmp_test 
    ( 
     id INT 
    ) ENGINE=MEMORY; 

    SET v_remainder = v_id_arr; 
    SET v_cur_position = 1; 

    WHILE CHAR_LENGTH(v_remainder) > 0 AND v_cur_position > 0 DO 
     SET v_cur_position = INSTR(v_remainder, '|'); 
     IF v_cur_position = 0 THEN 
      SET v_cur_string = v_remainder; 
     ELSE 
      SET v_cur_string = LEFT(v_remainder, v_cur_position - 1); 
     END IF; 

     IF TRIM(v_cur_string) != '' THEN 
      INSERT INTO tmp_test 
       (id) 
      VALUES 
       (v_cur_string);     
     END IF; 

     SET v_remainder = SUBSTRING(v_remainder, v_cur_position + 1); 
    END WHILE; 

    SELECT 
     id 
    FROM 
    tmp_test; 

    DROP TEMPORARY TABLE tmp_test; 
END 
$$ 

Następnie wystarczy zadzwonić spTest_Array('1|2|3|4|5') powinna produkować ten sam zestaw wyników jak wyżej zapytania PostgreSQL.

0

Incidently, oto jak można dodać tablicę do funkcji (przechowywany-proc) połączenia:

CallableStatement proc = null; 
List<Integer> faultcd_array = Arrays.asList(1003, 1234, 5678); 
//conn - your connection manager 
conn = DriverManager.getConnection(connection string here); 
proc = conn.prepareCall("{ ? = call procedureName(?) }"); 
proc.registerOutParameter(1, Types.OTHER); 
//This sets-up the array 
Integer[] dataFaults = faultcd_array.toArray(new Integer[faultcd_array.size()]); 
java.sql.Array sqlFaultsArray = conn.createArrayOf("int4", dataFaults); 
proc.setArray(2, sqlFaultsArray); 
//: 
//add code to retrieve cursor, use the data. 
//: 
0

Dzięki wsparciu JSON w MySQL teraz rzeczywiście mają możliwość przekazać tablicę do MySQL przechowywane procedury . Utwórz JSON_ARRAY i po prostu przekazuj go jako argument JSON do swojej procedury składowanej. Następnie w procedurze, używając pętli WHASE MySQL i ścieżki "JSON" MySQL, uzyskaj dostęp do każdego z elementów w JSON_ARRAY i rób to, co chcesz. Przykład tutaj: https://gist.githubusercontent.com/jonathanvx/513066eea8cb5919b648b2453db47890/raw/22f33fdf64a2f292688edbc67392ba2ccf8da47c/json.sql