我希望能夠將一個「數組」值傳遞給我的存儲過程,而不是串行調用「添加數值」過程。如何將值的「數組」傳遞給我的存儲過程?
任何人都可以提出一個辦法做到這一點?我在這裏錯過了什麼嗎?
編輯:我將使用PostgreSQL/MySQL的,我還沒有決定。
我希望能夠將一個「數組」值傳遞給我的存儲過程,而不是串行調用「添加數值」過程。如何將值的「數組」傳遞給我的存儲過程?
任何人都可以提出一個辦法做到這一點?我在這裏錯過了什麼嗎?
編輯:我將使用PostgreSQL/MySQL的,我還沒有決定。
正如克里斯指出,在PostgreSQL裏是沒有問題的 - 任何基本類型(如int,文本)有它自己的陣列亞型,您還可以創建自定義類型,包括複合的。例如:
CREATE TYPE test as (
n int4,
m int4
);
現在您可以輕鬆創建測試的數組:
select ARRAY[
row(1,2)::test,
row(3,4)::test,
row(5,6)::test
];
您可以編寫將成倍N * M代表在陣列中的每個項目的功能,並返回乘積之和:
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;
並運行它:
# SELECT test_test(
ARRAY[
row(1, 2)::test,
row(3,4)::test,
row(5,6)::test
]
);
test_test
-----------
44
(1 row)
你沒有標明,但如果你指的是SQL服務器,here's one way。
和MS支持ref。
我不知道通過一個實際的陣列到這些引擎(我用sqlserver的工作),但這裏是爲合格的想法一個分隔符的字符串,並用這個函數在你的sproc中解析它。
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
這個問題在PostgreSQL或MySql環境中特別提出,而不是MSSQL – 2017-10-30 07:19:24
對於PostgreSQL,你可以做這樣的事情:
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;
然後,您可以分隔字符串傳遞給您的存儲過程。
說,參數1是含有'1|2|3|4|5'
該語句的輸入PARAM:
SELECT CAST(fnExplode(string_to_array(param1, '|')) AS INTEGER);
導致的結果集可被連接或插入。
同樣,對於MySQL,你可以做這樣的事情:
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
$$
然後只需撥打spTest_Array('1|2|3|4|5')
應產生相同的結果設定爲上述PostgreSQL的查詢。
順便說一句,這裏是你如何將陣列添加到功能(存儲進程內)電話:
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.
//:
由於JSON支持在MySQL中,你現在居然有一個數組傳遞給你的MySQL存儲過程的能力。創建一個JSON_ARRAY,並將其作爲JSON參數傳遞給您的存儲過程。 然後在過程中,使用MySQL的WHILE循環和MySQL的JSON「路徑」,訪問JSON_ARRAY中的每個元素並按照你的意願進行操作。 這裏的一個例子https://gist.githubusercontent.com/jonathanvx/513066eea8cb5919b648b2453db47890/raw/22f33fdf64a2f292688edbc67392ba2ccf8da47c/json.sql
從SQL Server 2008開始,實際上可以使用表變量作爲存儲過程參數。 – Thorarin 2009-08-18 19:18:39