Como posso simular uma variável de array no MySQL?

93

Ele parece que o MySQL não tem variáveis de matriz. O que devo usar no lugar?


Parece haver duas alternativas sugeridas: Um escalar do tipo conjunto e tabelas temporárias . A pergunta a que vinculei sugere a primeira opção. Mas é uma boa prática usar isso em vez de variáveis ​​de array? Alternativamente, se eu for com conjuntos, a que equivaleria o idioma baseado em conjuntos foreach?

einpoklum
fonte

Respostas:

78

Bem, tenho usado tabelas temporárias em vez de variáveis ​​de matriz. Não é a melhor solução, mas funciona.

Observe que você não precisa definir formalmente seus campos, apenas crie-os usando um SELECT:

DROP TEMPORARY TABLE IF EXISTS my_temp_table;
CREATE TEMPORARY TABLE my_temp_table
    SELECT first_name FROM people WHERE last_name = 'Smith';

(Consulte também Criar tabela temporária a partir da instrução select sem usar Criar Tabela .)

einpoklum
fonte
1
Ohhh: o Eu não sabia que o SQL tinha isso !! As tabelas estão vivas apenas para o escopo de todas as consultas em execução. ARRUMADO!
iGbanam
2
@Yasky, desde que você não reutilize a conexão. Porque na verdade vai durar toda a sessão.
Pacerier
4
@John: Sim, bem, você pode reutilizá-lo, mas não na mesma consulta.
einpoklum
1
Se você estiver reutilizando conexões, geralmente deve DROP TEMPORARY TABLE IF EXISTS my_temp_table; antes de criá-lo.
Aurast de
46

Você pode fazer isso no MySQL usando WHILEloop:

SET @myArrayOfValue = '2,5,2,23,6,';

WHILE (LOCATE(',', @myArrayOfValue) > 0)
DO
    SET @value = ELT(1, @myArrayOfValue);
    SET @myArrayOfValue= SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);

    INSERT INTO `EXEMPLE` VALUES(@value, 'hello');
END WHILE;

EDITAR: Como alternativa, você pode fazer isso usando UNION ALL:

INSERT INTO `EXEMPLE`
(
 `value`, `message`
)
(
 SELECT 2 AS `value`, 'hello' AS `message`
 UNION ALL
 SELECT 5 AS `value`, 'hello' AS `message`
 UNION ALL
 SELECT 2 AS `value`, 'hello' AS `message`
 UNION ALL
 ...
);
Omesh
fonte
4
Os loops não são possíveis apenas em procedimentos armazenados?
einpoklum
2
sim certo, é possível dentro de stored procedures, functions e triggers.
Omesh
1
Portanto, não posso usar o código que você forneceu ... preciso de algo que seja aplicável de forma mais geral.
einpoklum
Você pode escrever um procedimento armazenado de amostra e CALLisso.
Omesh
1
Não acho que matrizes sejam necessárias. Você pode fazer isso facilmente usando tabelas temporárias ou UNION ALLsem usar o procedimento.
Omesh
28

Tente usar a função FIND_IN_SET () do MySql, por exemplo

SET @c = 'xxx,yyy,zzz';

SELECT * from countries 
WHERE FIND_IN_SET(countryname,@c);

Observação: você não precisa definir a variável em StoredProcedure se estiver passando parâmetros com valores CSV.

Himalaya Garg
fonte
Cuidado com os limites de comprimento, que podem ser bastante baixos: stackoverflow.com/q/2567000/1333493
Nemo
19

Hoje em dia, usar um array JSON seria uma resposta óbvia.

Uma vez que esta é uma questão antiga, mas ainda relevante, produzi um pequeno exemplo. As funções JSON estão disponíveis desde mySQL 5.7.x / MariaDB 10.2.3

Eu prefiro esta solução em vez de ELT () porque é realmente mais como um array e este 'array' pode ser reutilizado no código.

Mas tenha cuidado: ele (JSON) é certamente muito mais lento do que usar uma tabela temporária. É apenas mais prático. imo.

Aqui está como usar uma matriz JSON:

SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';

SELECT JSON_LENGTH(@myjson);
-- result: 19

SELECT JSON_VALUE(@myjson, '$[0]');
-- result: gmail.com

E aqui está um pequeno exemplo para mostrar como funciona em uma função / procedimento:

DELIMITER //
CREATE OR REPLACE FUNCTION example() RETURNS varchar(1000) DETERMINISTIC
BEGIN
  DECLARE _result varchar(1000) DEFAULT '';
  DECLARE _counter INT DEFAULT 0;
  DECLARE _value varchar(50);

  SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';

  WHILE _counter < JSON_LENGTH(@myjson) DO
    -- do whatever, e.g. add-up strings...
    SET _result = CONCAT(_result, _counter, '-', JSON_VALUE(@myjson, CONCAT('$[',_counter,']')), '#');

    SET _counter = _counter + 1;
  END WHILE;

  RETURN _result;
END //
DELIMITER ;

SELECT example();
SeparateReality
fonte
Você está dizendo que ELT é mais lento ou JSON é mais lento?
Kanagavelu Sugumar
2
@Kanagavelu Sugumar: No momento em que este artigo foi escrito, JSON é definitivamente mais lento. Editei a resposta para tornar isso mais claro.
SeparateReality de
16

Não sei sobre os arrays, mas existe uma maneira de armazenar listas separadas por vírgulas na coluna VARCHAR normal.

E quando você precisa encontrar algo nessa lista, você pode usar a função FIND_IN_SET () .

verme
fonte
Se eu quiser encontrar um subconjunto em um conjunto, há alguma maneira?
Akshay Vishnoi
Desculpa! Não tenho certeza se isso é possível.
wormhit
Você tem a melhor solução
Calvin
7
DELIMITER $$
CREATE DEFINER=`mysqldb`@`%` PROCEDURE `abc`()
BEGIN
  BEGIN 
    set @value :='11,2,3,1,'; 
    WHILE (LOCATE(',', @value) > 0) DO
      SET @V_DESIGNATION = SUBSTRING(@value,1, LOCATE(',',@value)-1); 
      SET @value = SUBSTRING(@value, LOCATE(',',@value) + 1); 
      select @V_DESIGNATION;
    END WHILE;
  END;
END$$
DELIMITER ;
Sagar Gangwal
fonte
2
Explique como este código deve ser usado e como ele responde à pergunta.
einpoklum
Como aqui você faz um procedimento simples que fornece um por um elemento daquela string particular que funciona como array no oracle.
Sagar Gangwal
Oráculo? Esta pergunta não é sobre a Oracle. Além disso, parece que você está definindo uma matriz dentro do procedimento.
einpoklum
Por favor, verifique o Syntex é apenas para mysql
Sagar Gangwal
Não perca a última vírgula!
Eagle_Eye
4

Eu sei que esta é uma resposta um pouco tardia, mas recentemente tive que resolver um problema semelhante e pensei que isso pode ser útil para outras pessoas.

fundo

Considere a tabela abaixo chamada 'mytable':

Mesa inicial

O problema era manter apenas os últimos 3 registros e excluir todos os registros mais antigos cujo systemid = 1 (pode haver muitos outros registros na tabela com outros valores de systemid)

Seria bom se você pudesse fazer isso simplesmente usando a instrução

DELETE FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)

No entanto, isso ainda não é suportado no MySQL e se você tentar fazer isso, receberá um erro como

...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'

Portanto, é necessária uma solução alternativa pela qual uma matriz de valores é passada para o seletor IN usando a variável. No entanto, como as variáveis ​​precisam ser valores únicos, eu precisaria simular uma matriz . O truque é criar o array como uma lista de valores separados por vírgulas (string) e atribuir isso à variável como segue

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);

O resultado armazenado em @myvar é

5,6,7

Em seguida, o seletor FIND_IN_SET é usado para selecionar a partir da matriz simulada

SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);

O resultado final combinado é o seguinte:

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
DELETE FROM mytable WHERE FIND_IN_SET(id,@myvar);

Estou ciente de que este é um caso muito específico. No entanto, pode ser modificado para se adequar a praticamente qualquer outro caso em que uma variável precise armazenar uma matriz de valores.

Eu espero que isso ajude.

Clinton
fonte
3

Talvez crie uma tabela de memória temporária com colunas (chave, valor) se quiser matrizes associativas. Ter uma tabela de memória é a coisa mais próxima de ter matrizes no mysql

Pavle Lekic
fonte
Umm, eu não quero matrizes associativas, apenas matrizes.
einpoklum
você pode usar uma tabela de memória temporária com apenas uma coluna e, em seguida, fazer um loop pelos valores usando cursores, que é a coisa mais próxima de usar arrays e loops for / while em uma linguagem de programação não declarativa
Pavle Lekic
A linguagem realmente tem esse recurso, ou seja, não há razão sintática para que você não possa selecionar um vetor em uma variável da mesma forma que seleciona um escalar nela.
einpoklum 02 de
3

Veja como eu fiz.

Primeiro, criei uma função que verifica se um Long / Integer / qualquer valor está em uma lista de valores separados por vírgulas:

CREATE DEFINER = 'root'@'localhost' FUNCTION `is_id_in_ids`(
        `strIDs` VARCHAR(255),
        `_id` BIGINT
    )
    RETURNS BIT(1)
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

  DECLARE strLen    INT DEFAULT 0;
  DECLARE subStrLen INT DEFAULT 0;
  DECLARE subs      VARCHAR(255);

  IF strIDs IS NULL THEN
    SET strIDs = '';
  END IF;

  do_this:
    LOOP
      SET strLen = LENGTH(strIDs);
      SET subs = SUBSTRING_INDEX(strIDs, ',', 1);

      if ( CAST(subs AS UNSIGNED) = _id ) THEN
        -- founded
        return(1);
      END IF;

      SET subStrLen = LENGTH(SUBSTRING_INDEX(strIDs, ',', 1));
      SET strIDs = MID(strIDs, subStrLen+2, strLen);

      IF strIDs = NULL or trim(strIds) = '' THEN
        LEAVE do_this;
      END IF;

  END LOOP do_this;

   -- not founded
  return(0);

END;

Portanto, agora você pode pesquisar um ID em uma lista separada por vírgulas de IDs, como esta:

select `is_id_in_ids`('1001,1002,1003',1002);

E você pode usar essa função dentro de uma cláusula WHERE, como esta:

SELECT * FROM table1 WHERE `is_id_in_ids`('1001,1002,1003',table1_id);

Esta foi a única maneira que encontrei de passar um parâmetro "array" para um PROCEDURE.

chuckedw
fonte
2

O objetivo dos arrays não é ser eficiente? Se você estiver apenas iterando por valores, acho que um cursor em uma tabela temporária (ou permanente) faz mais sentido do que buscar vírgulas, não? Também mais limpo. Procure "mysql DECLARE CURSOR".

Para acesso aleatório, uma tabela temporária com chave primária indexada numericamente. Infelizmente, o acesso mais rápido que você obterá é uma tabela hash, não um acesso aleatório verdadeiro.

Amaigus
fonte
Este é um comentário, não uma resposta. Não indiquei que é isso que quero fazer com a matriz.
einpoklum
2

Estou surpreso que nenhuma das respostas menciona ELT / FIELD.

ELT / FIELD funciona de forma muito semelhante a uma matriz, especialmente se você tiver dados estáticos.

FIND_IN_SET também funciona de forma semelhante, mas não tem uma função complementar embutida, mas é fácil de escrever.

mysql> select elt(2,'AA','BB','CC');
+-----------------------+
| elt(2,'AA','BB','CC') |
+-----------------------+
| BB                    |
+-----------------------+
1 row in set (0.00 sec)

mysql> select field('BB','AA','BB','CC');
+----------------------------+
| field('BB','AA','BB','CC') |
+----------------------------+
|                          2 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select find_in_set('BB','AA,BB,CC');
+------------------------------+
| find_in_set('BB','AA,BB,CC') |
+------------------------------+
|                            2 |
+------------------------------+
1 row in set (0.00 sec)

mysql>  SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1);
+-----------------------------------------------------------+
| SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1) |
+-----------------------------------------------------------+
| BB                                                        |
+-----------------------------------------------------------+
1 row in set (0.01 sec)
Jongab
fonte
1

Isso funciona bem para a lista de valores:

SET @myArrayOfValue = '2,5,2,23,6,';

WHILE (LOCATE(',', @myArrayOfValue) > 0)
DO
SET @value = ELT(1, @myArrayOfValue);
    SET @STR = SUBSTRING(@myArrayOfValue, 1, LOCATE(',',@myArrayOfValue)-1);
    SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',', @myArrayOfValue) + 1);

    INSERT INTO `Demo` VALUES(@STR, 'hello');
END WHILE;
user2664904
fonte
1

Ambas as versões usando conjuntos não funcionaram para mim (testado com MySQL 5.5). A função ELT () retorna todo o conjunto. Considerando que a instrução WHILE está disponível apenas no contexto PROCEDURE, eu a adicionei à minha solução:

DROP PROCEDURE IF EXISTS __main__;

DELIMITER $
CREATE PROCEDURE __main__()
BEGIN
    SET @myArrayOfValue = '2,5,2,23,6,';

    WHILE (LOCATE(',', @myArrayOfValue) > 0)
    DO
        SET @value = LEFT(@myArrayOfValue, LOCATE(',',@myArrayOfValue) - 1);    
        SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);
    END WHILE;
END;
$
DELIMITER ;

CALL __main__;

Para ser honesto, não acho que seja uma boa prática. Mesmo que seja realmente necessário, dificilmente é legível e é bastante lento.

jmmeier
fonte
1

Outra maneira de ver o mesmo problema. Espero útil

DELIMITER $$
CREATE PROCEDURE ARR(v_value VARCHAR(100))
BEGIN

DECLARE v_tam VARCHAR(100);
DECLARE v_pos VARCHAR(100);

CREATE TEMPORARY TABLE IF NOT EXISTS split (split VARCHAR(50));

SET v_tam = (SELECT (LENGTH(v_value) - LENGTH(REPLACE(v_value,',',''))));
SET v_pos = 1;

WHILE (v_tam >= v_pos)
DO
    INSERT INTO split 
    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(v_value,',',v_pos),',', -1);
    SET v_pos = v_pos + 1;
END WHILE;

SELECT * FROM split;

DROP TEMPORARY TABLE split;

END$$


CALL ARR('1006212,1006404,1003404,1006505,444,');
Walter Azevedo
fonte
Na verdade, não está claro o que você está dizendo aqui. Esta questão de 7 anos atrás tem várias respostas relevantes. Considere remover sua resposta ou explicar o que você está tentando nos dizer de maneira direta / geral, em vez de por meio de um exemplo.
einpoklum
0

Na versão MYSQL após 5.7.x, você pode usar o tipo JSON para armazenar uma matriz. Você pode obter o valor de um array por meio de uma chave via MYSQL.

nick maldito
fonte
8
Você pode dar um exemplo de como eu faria isso?
einpoklum
0

Inspirado pela função ELT (número do índice, string1, string2, string3, ...), acho que o exemplo a seguir funciona como um exemplo de array:

set @i := 1;
while @i <= 3
do
  insert into table(val) values (ELT(@i ,'val1','val2','val3'...));
set @i = @i + 1;
end while;

Espero que ajude.

Edward
fonte
0

Aqui está um exemplo de MySQL para loop por uma string delimitada por vírgulas.

DECLARE v_delimited_string_access_index INT;
DECLARE v_delimited_string_access_value VARCHAR(255);
DECLARE v_can_still_find_values_in_delimited_string BOOLEAN;

SET v_can_still_find_values_in_delimited_string = true;
SET v_delimited_string_access_index = 0;
WHILE (v_can_still_find_values_in_delimited_string) DO
  SET v_delimited_string_access_value = get_from_delimiter_split_string(in_array, ',', v_delimited_string_access_index); -- get value from string
  SET v_delimited_string_access_index = v_delimited_string_access_index + 1;
  IF (v_delimited_string_access_value = '') THEN
    SET v_can_still_find_values_in_delimited_string = false; -- no value at this index, stop looping
  ELSE
    -- DO WHAT YOU WANT WITH v_delimited_string_access_value HERE
  END IF;
END WHILE;

isso usa a get_from_delimiter_split_stringfunção definida aqui: https://stackoverflow.com/a/59666211/3068233

Ulad Kasach
fonte
strings delimitadas por vírgulas já foram sugeridas - anos atrás.
einpoklum de
@einpoklum sim - e aqui está outra maneira de interagir com eles
Ulad Kasach
0

Uma variável de array é realmente necessária?

Eu pergunto porque originalmente cheguei aqui querendo adicionar uma matriz como uma variável de tabela do MySQL. Eu era relativamente novo no design de banco de dados e estava tentando pensar em como faria isso em uma linguagem de programação típica.

Mas os bancos de dados são diferentes. Eu pensei eu quis um array como uma variável, mas verifica-se que não é apenas uma prática base de dados comum MySQL.

Prática padrão

A solução alternativa para matrizes é adicionar uma tabela adicional e, em seguida, referenciar sua tabela original com uma chave estrangeira.

Como exemplo, vamos imaginar um aplicativo que monitora todos os itens que cada pessoa em uma casa deseja comprar na loja.

Os comandos para criar a tabela que eu imaginei originalmente seriam parecidos com estes:

#doesn't work
CREATE TABLE Person(
  name VARCHAR(50) PRIMARY KEY
  buy_list ARRAY
);

Acho que imaginei buy_list como uma string de itens separados por vírgulas ou algo parecido.

Mas o MySQL não tem um campo do tipo array, então eu realmente precisava de algo assim:

CREATE TABLE Person(
  name VARCHAR(50) PRIMARY KEY
);
CREATE TABLE BuyList(
  person VARCHAR(50),
  item VARCHAR(50),
  PRIMARY KEY (person, item),
  CONSTRAINT fk_person FOREIGN KEY (person) REFERENCES Person(name)
);

Aqui definimos uma restrição chamada fk_person. Diz que o campo 'pessoa' em BuyList é uma chave estrangeira. Em outras palavras, é uma chave primária em outra tabela, especificamente o campo 'nome' na tabela Person, que é o que REFERENCES denota.

Também definimos a combinação de pessoa e item para ser a chave primária, mas tecnicamente isso não é necessário.

Finalmente, se você deseja obter todos os itens da lista de uma pessoa, pode executar esta consulta:

SELECT item FROM BuyList WHERE person='John';

Isso dá a você todos os itens da lista de John. Sem matrizes necessárias!

kraftydevil
fonte
Minha solução aceita é usar uma mesa temporária.
einpoklum
Claro. Em seguida, incluí esta resposta para qualquer pessoa como eu que chegou a esta página procurando uma maneira de criar um tipo de array - que inicialmente não entendeu por que os arrays não são um tipo no MySQL. Parece que é por design. O caso geral não foi representado aqui, então incluí o que aprendi para que outras pessoas entendessem que os arrays normalmente não são necessários. Não espero que você selecione minha resposta. Depende do caso de uso. Você aceitou a sua resposta para um caso de uso específico e estou fornecendo esta resposta para o caso de uso geral.
kraftydevil
0

Se tivermos uma mesa assim

mysql> select * from user_mail;
+------------+-------+
| email      | user | 
+------------+-------+-
| email1@gmail |     1 | 
| email2@gmail |     2 |
+------------+-------+--------+------------+

e a tabela array:

mysql> select * from user_mail_array;
+------------+-------+-------------+
| email      | user | preferences |
+------------+-------+-------------+
| email1@gmail |     1 |           1 |
| email1@gmail |     1 |           2 |
| email1@gmail |     1 |           3 |
| email1@gmail |     1 |           4 |
| email2@gmail |     2 |           5 |
| email2@gmail |     2 |           6 |

Podemos selecionar as linhas da segunda tabela como uma matriz com a função CONCAT:

mysql> SELECT t1.*, GROUP_CONCAT(t2.preferences) AS preferences
     FROM user_mail t1,user_mail_array t2
       where t1.email=t2.email and t1.user=t2.user
     GROUP BY t1.email,t1.user;

+------------+-------+--------+------------+-------------+
| email      | user | preferences |
+------------+-------+--------+------------+-------------+
|email1@gmail |     1 | 1,3,2,4     |
|email2@gmail |     2 | 5,6         |
+------------+-------+--------+------------+-------------+
monitor
fonte
Duplicação da resposta de Clinton, eu acho.
einpoklum de
-2

Acho que posso melhorar essa resposta. Experimente isto:

O parâmetro 'Pranks' é um CSV. ie. '1,2,3,4 ..... etc'

CREATE PROCEDURE AddRanks(
IN Pranks TEXT
)
BEGIN
  DECLARE VCounter INTEGER;
  DECLARE VStringToAdd VARCHAR(50);
  SET VCounter = 0;
  START TRANSACTION;
  REPEAT
    SET VStringToAdd = (SELECT TRIM(SUBSTRING_INDEX(Pranks, ',', 1)));
    SET Pranks = (SELECT RIGHT(Pranks, TRIM(LENGTH(Pranks) - LENGTH(SUBSTRING_INDEX(Pranks, ',', 1))-1)));
    INSERT INTO tbl_rank_names(rank)
    VALUES(VStringToAdd);
    SET VCounter = VCounter + 1;
  UNTIL (Pranks = '')
  END REPEAT;
  SELECT VCounter AS 'Records added';
  COMMIT;
END;

Este método torna a string pesquisada de valores CSV progressivamente mais curta com cada iteração do loop, o que eu acredito que seria melhor para otimização.

user2288580
fonte
A que 'esta resposta' você está se referindo? Além disso, você não precisa ter um arquivo CSV.
einpoklum
Eu não estava me referindo a um arquivo CSV, estava me referindo a um valor CSV, como '1,2,3,4 ... etc'
user2288580
-2

Eu tentaria algo assim para várias coleções. Sou um iniciante em MySQL. Desculpe pelos nomes das funções, não consegui decidir quais nomes seriam os melhores.

delimiter //

drop  procedure init_
//
create procedure init_()
begin
  CREATE TEMPORARY TABLE if not exists 
    val_store(  
    realm  varchar(30) 
    ,  id  varchar(30) 
    ,  val   varchar(255) 
    ,  primary key ( realm , id )
    );
end;
//

drop function if exists get_
//
create function get_( p_realm varchar(30) , p_id varchar(30) )
  returns varchar(255)
  reads sql data
begin 
  declare ret_val varchar(255);
  declare continue handler for 1146 set ret_val = null;
  select val into ret_val from val_store where id = p_id;
  return ret_val;
end;
//

drop procedure if exists set_
//
create procedure set_( p_realm varchar(30) , p_id varchar(30) , p_val varchar(255) )
begin
  call init_(); 
  insert into val_store (realm,id,val) values (p_realm , p_id , p_val) on duplicate key update val = p_val;
end;
//

drop   procedure if exists remove_
//
create procedure remove_( p_realm varchar(30) , p_id varchar(30) )
begin
  call init_();
  delete from val_store where realm = p_realm and id = p_id;
end;
//

drop   procedure if exists erase_
//
create procedure erase_( p_realm varchar(30) ) 
begin
  call init_();
  delete from val_store where realm = p_realm;
end;
//

call set_('my_array_table_name','my_key','my_value');

select get_('my_array_table_name','my_key');
Dave
fonte
Acho que entendo o que você está sugerindo, mas isso é bastante pesado e provavelmente também incrivelmente lento ...
einpoklum
Não posso endossar ou rejeitar isso sem fazer um teste de resistência. É basicamente uma pesquisa e inserção de chave primária em uma tabela temporária (ou tabela normal). Vou usá-lo até que tenha problemas ou encontre uma maneira melhor; mas eu faço coisas estranhas como escrever compiladores e jogos completamente em Oracle PL / SQL.
Dave
-2

Em vez de salvar os dados como um array ou em uma linha apenas, você deve criar linhas diferentes para cada valor recebido. Isso tornará muito mais simples de entender, em vez de colocar tudo junto.

chirag mathur
fonte
Compartilhe como fazer isso
Nico Haase,
-5

Você tentou usar serialize () do PHP? Isso permite que você armazene o conteúdo de um array de variável em uma string que o PHP entende e é segura para o banco de dados (supondo que você tenha escapado primeiro).

$array = array(
    1 => 'some data',
    2 => 'some more'
);

//Assuming you're already connected to the database
$sql = sprintf("INSERT INTO `yourTable` (`rowID`, `rowContent`) VALUES (NULL, '%s')"
     ,  serialize(mysql_real_escape_string($array, $dbConnection)));
mysql_query($sql, $dbConnection) or die(mysql_error());

Você também pode fazer exatamente o mesmo sem uma matriz numerada

$array2 = array(
    'something' => 'something else'
);

ou

$array3 = array(
    'somethingNew'
);
Magictallguy
fonte
8
Não estou trabalhando com PHP, então isso não é muito relevante para mim.
einpoklum
2
Use JSON em vez de serializar. É mais genérico e independente do idioma.
Rick James