Mysql 我怎样才能通过考试;数组";将值添加到我的存储过程中?

Mysql 我怎样才能通过考试;数组";将值添加到我的存储过程中?,mysql,database,arrays,postgresql,stored-procedures,Mysql,Database,Arrays,Postgresql,Stored Procedures,我希望能够将值的“数组”传递给存储过程,而不是串行调用“addvalue”过程 有人能建议一种方法吗?我是不是遗漏了什么 编辑:我将使用PostgreSQL/MySQL,我还没有决定。您没有指出,但如果您指的是SQL server 和MS支持。如果您计划使用MySQL 5.1,则不可能传入数组。 请参阅MySQL 5.1 如果您计划使用PostgreSQL,那么您可以查看我不知道如何将实际数组传递到这些引擎中(我使用sqlserver),但这里有一个想法,可以通过此函数传递分隔字符串并在存储过程

我希望能够将值的“数组”传递给存储过程,而不是串行调用“addvalue”过程

有人能建议一种方法吗?我是不是遗漏了什么


编辑:我将使用PostgreSQL/MySQL,我还没有决定。

您没有指出,但如果您指的是SQL server


和MS支持。

如果您计划使用MySQL 5.1,则不可能传入数组。
请参阅MySQL 5.1

如果您计划使用PostgreSQL,那么您可以查看

我不知道如何将实际数组传递到这些引擎中(我使用sqlserver),但这里有一个想法,可以通过此函数传递分隔字符串并在存储过程中对其进行解析

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,您可以执行以下操作:

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;
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 
$$
然后,可以向存储过程传递一个带分隔符的字符串

比如说,param1是一个输入参数,包含
'1 | 2 | 3 | 4 | 5'

声明:

SELECT CAST(fnExplode(string_to_array(param1, '|')) AS INTEGER);
生成一个可以合并或插入的结果集

同样,对于MySQL,您可以执行以下操作:

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;
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_数组('1 | 2 | 3 | 4 | 5')
就可以生成与上述PostgreSQL查询相同的结果集。

正如Chris所指出的,在PostgreSQL中,这没有问题-任何基类型(如int、text)都有自己的数组子类型,您还可以创建自定义类型,包括复合类型。例如:

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)

顺便说一句,下面是如何将数组添加到函数(存储过程)调用中:

CallableStatement proc=null;
List faultcd_array=Arrays.asList(100312345678);
//conn-您的连接管理器
conn=DriverManager.getConnection(此处为连接字符串);
proc=conn.prepareCall(“{?=callprocedurename(?)}”);
proc.registerOutParameter(1,type.OTHER);
//这将设置阵列
整数[]dataFaults=faultcd_数组.toArray(新整数[faultcd_数组.size());
java.sql.Array sqlFaultsArray=conn.createArrayOf(“int4”,dataFaults);
进程setArray(2,sqlFaultsArray);
//:
//添加代码以检索游标,使用数据。
//:

多亏了MySQL中的JSON支持,您现在可以将数组传递给MySQL存储过程。创建一个JSON_数组,并将其作为JSON参数传递给存储过程。 然后在这个过程中,使用MySQL的WHILE循环和MySQL的JSON“路径”,访问JSON_数组中的每个元素,并按照您的意愿进行操作。
这里的一个示例

从SQL Server 2008开始,您实际上可以使用表变量作为存储过程参数。这个问题是在PostgreSQL或MySql环境中特别提出的,而不是在MSSQL环境中