MySQL에서 배열 변수를 어떻게 시뮬레이션 할 수 있습니까?


91

나타납니다 MySQL이 배열 변수를 가지고 있지 않습니다. 대신 무엇을 사용해야합니까?


제안 된 두 가지 대안이있는 것 같습니다 : 집합 유형 스칼라임시 테이블 . 내가 연결 한 질문은 전자를 제안합니다. 그러나 배열 변수 대신 이것을 사용하는 것이 좋은 습관입니까? 또는 세트로 가면 세트 기반 관용구는 foreach무엇입니까?

답변:


78

글쎄, 나는 배열 변수 대신 임시 테이블을 사용하고 있습니다. 최고의 솔루션은 아니지만 작동합니다.

공식적으로 필드를 정의 할 필요는 없으며 SELECT를 사용하여 생성하기 만하면됩니다.

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

( Create Table을 사용하지 않고 select 문에서 임시 테이블 만들기 도 참조하십시오 .)


1
Ohhh : o 나는 SQL이 이것을 가지고 있다는 것을 몰랐다 !! 테이블은 실행중인 모든 쿼리의 범위에 대해서만 살아 있습니다. 산뜻한!
iGbanam 2014

2
@Yasky, 그것은 당신이 연결을 재사용하지 않는다면 제공됩니다. 실제로 전체 세션 동안 지속될 것이기 때문입니다 .
Pacerier 2015


4
@ 존 : 그래, 당신은 할 수 있지만 동일한 쿼리에서, 재사용.
einpoklum

1
연결을 재사용하는 경우 일반적으로 DROP TEMPORARY TABLE IF EXISTS my_temp_table; 그것을 만들기 전에.
Aurast

46

WHILE루프를 사용하여 MySQL에서이를 수행 할 수 있습니다 .

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;

편집 : 또는 다음을 사용하여 수행 할 수 있습니다 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
 ...
);

4
저장 프로 시저에서만 루프가 가능하지 않습니까?
einpoklum 2012-08-29

2
예, 저장 프로 시저, 함수 및 트리거 내부에서 가능합니다.
Omesh

1
그래서 당신이 제공 한 코드를 사용할 수 없습니다 ... 좀 더 일반적으로 적용 할 수있는 것이 필요합니다.
einpoklum 2012-08-29

샘플 저장 프로 시저를 작성할 수 있습니다 CALL.
Omesh 2012-08-29

1
나는 배열이 필요하다고 생각하지 않습니다. 임시 테이블 UNION ALL을 사용 하거나 절차를 사용하지 않고 쉽게 할 수 있습니다 .
Omesh

28

MySql의 FIND_IN_SET () 함수를 사용해보십시오.

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

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

참고 : CSV 값과 함께 매개 변수를 전달하는 경우 StoredProcedure에서 변수를 설정할 필요가 없습니다.


매우 낮을 수있는 길이 제한에주의하십시오. stackoverflow.com/q/2567000/1333493
Nemo

19

요즘에는 JSON 배열을 사용하는 것이 분명한 대답이 될 것입니다.

이것은 오래되었지만 여전히 관련이있는 질문이기 때문에 짧은 예를 만들었습니다. mySQL 5.7.x / MariaDB 10.2.3부터 JSON 함수를 사용할 수 있습니다.

ELT ()보다이 솔루션을 선호하는 이유는 배열과 비슷하고 코드에서이 '배열'을 재사용 할 수 있기 때문입니다.

하지만 조심하세요. (JSON)은 임시 테이블을 사용하는 것보다 확실히 훨씬 느립니다. 더 편리합니다. imo.

다음은 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

다음은 함수 / 프로 시저에서 어떻게 작동하는지 보여주는 간단한 예입니다.

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();

ELT가 더 느리거나 JSON이 더 느리다는 말입니까?
Kanagavelu Sugumar

2
@Kanagavelu Sugumar : JSON 작성 당시에는 확실히 느립니다. 나는 그것을 더 명확하게하기 위해 대답을 편집했습니다.
SeparateReality

16

배열에 대해서는 모르지만 일반 VARCHAR 열에 쉼표로 구분 된 목록을 저장하는 방법이 있습니다.

그리고 그 목록에서 무언가를 찾아야 할 때 FIND_IN_SET () 함수를 사용할 수 있습니다 .


집합에서 하위 집합을 찾고 싶다면 방법이 있습니까?
Akshay Vishnoi

죄송합니다! 가능할지 모르겠습니다.
wormhit

당신은 최고의 솔루션이
캘빈

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 ;

2
이 코드를 사용하는 방법과 질문에 대한 답변을 설명해주십시오.
einpoklum

여기와 같이 오라클에서 배열로 작동하는 특정 문자열의 요소를 하나씩 제공하는 간단한 절차를 만듭니다.
Sagar Gangwal

신탁? 이 질문은 오라클에 관한 것이 아닙니다. 또한 프로 시저 내에서 배열을 정의하는 것처럼 보입니다.
einpoklum

친절하게 체크 Syntex 만 mysql을위한거야
사가르 Gangwal

마지막 쉼표를 놓치지 마세요!
Eagle_Eye

4

답변이 다소 늦었다는 것을 알고 있지만 최근에 비슷한 문제를 해결해야했고 이것이 다른 사람에게 유용 할 것이라고 생각했습니다.

배경

'mytable'이라는 아래 테이블을 고려하십시오.

시작 테이블

문제는 최신 3 개의 레코드 만 유지하고 systemid = 1 인 이전 레코드를 삭제하는 것이 었습니다 (다른 systemid 값이있는 테이블에 다른 레코드가 많이있을 수 있음).

다음 문장을 사용하여 이것을 할 수 있다면 좋을 것입니다.

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

그러나 이것은 MySQL에서 아직 지원되지 않으며 이것을 시도하면 다음과 같은 오류가 발생합니다.

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

따라서 변수를 사용하여 값 배열이 IN 선택기에 전달되는 해결 방법이 필요합니다. 그러나 변수는 단일 값이어야 하므로 배열시뮬레이션 해야합니다 . 트릭은 쉼표로 구분 된 값 목록 (문자열)으로 배열을 만들고 다음과 같이 변수에 할당하는 것입니다.

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);

@myvar에 저장된 결과는 다음과 같습니다.

5,6,7

다음으로 FIND_IN_SET 선택기는 시뮬레이션 된 배열에서 선택하는 데 사용됩니다.

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

결합 된 최종 결과는 다음과 같습니다.

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);

나는 이것이 매우 특정한 경우라는 것을 알고 있습니다. 그러나 변수가 값의 배열을 저장해야하는 다른 경우에 맞게 수정할 수 있습니다.

이것이 도움이되기를 바랍니다.


3

연관 배열을 원하는 경우 열 (키, 값)이있는 임시 메모리 테이블을 만들 수 있습니다. 메모리 테이블을 갖는 것은 mysql에 배열을 갖는 것과 가장 가까운 것입니다.


음, 저는 연관 배열이 아니라 배열 만 원합니다.
einpoklum 2013-08-01

열이 하나 뿐인 임시 메모리 테이블을 사용한 다음 커서를 사용하여 값을 통해 루프를 수행 할 수 있습니다. 이는 비 선언적 프로그래밍 언어에서 배열 및 for / while 루프를 사용하는 것과 가장 가까운 것입니다
Pavle Lekic

언어에는 실제로이 기능이 있습니다. 즉, 스칼라를 선택하는 것처럼 벡터를 변수로 선택할 수 없어야하는 구문상의 이유가 없습니다.
einpoklum 2013 년

3

내가 한 방법은 다음과 같습니다.

먼저 Long / Integer / 어떤 값이 쉼표로 구분 된 값 목록에 있는지 확인하는 함수를 만들었습니다.

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;

이제 다음과 같이 쉼표로 구분 된 ID 목록에서 ID를 검색 할 수 있습니다.

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

그리고 다음과 같이 WHERE 절 내에서이 함수를 사용할 수 있습니다.

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

이것이 PROCEDURE에 "array"매개 변수를 전달하는 유일한 방법이었습니다.


2

배열의 요점이 효율적이지 않습니까? 값을 반복하는 경우 임시 (또는 영구) 테이블의 커서가 쉼표를 찾는 것보다 더 합리적이라고 생각합니다. 또한 깨끗합니다. "mysql DECLARE CURSOR"를 찾습니다.

무작위 액세스를 위해 숫자로 색인 된 기본 키가있는 임시 테이블. 불행히도 가장 빠른 액세스는 진정한 랜덤 액세스가 아닌 해시 테이블입니다.


이것은 답변이 아니라 설명입니다. 나는 그것이 내가 어레이로하고 싶은 일임을 나타내지 않았다.
einpoklum

2

ELT / FIELD에 대한 답변이 없다는 것에 놀랐습니다.

ELT / FIELD는 특히 정적 데이터가있는 경우 배열과 매우 유사하게 작동합니다.

FIND_IN_SET도 유사하게 작동하지만 보완 기능이 내장되어 있지 않지만 작성하기 쉽습니다.

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)

1

이것은 값 목록에 대해 잘 작동합니다.

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;

1

세트를 사용하는 두 버전 모두 나에게 적합하지 않았습니다 (MySQL 5.5로 테스트). ELT () 함수는 전체 집합을 반환합니다. WHILE 문은 PROCEDURE 컨텍스트에서만 사용할 수 있다는 것을 고려하여 솔루션에 추가했습니다.

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__;

솔직히 말해서 이것이 좋은 습관이라고 생각하지 않습니다. 실제로 필요한 경우에도 거의 읽을 수없고 매우 느립니다.


1

같은 문제를 보는 또 다른 방법. 도움이되는 희망

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,');

사실, 여기서 무슨 말을하는지 명확하지 않습니다. 7 년 전의이 질문에는 몇 가지 관련 답변이 있습니다. 답변을 삭제하거나 예시를 통하지 않고 직접 / 일반적으로 말하려는 내용을 설명해보세요.
einpoklum 19 년

0

5.7.x 이후의 MYSQL 버전에서는 JSON 유형을 사용하여 배열을 저장할 수 있습니다. MYSQL을 통해 키로 배열 값을 얻을 수 있습니다.


7
내가 어떻게할지 예를 들어 주실 수 있나요?
einpoklum

0

ELT (index number, string1, string2, string3,…) 함수에서 영감을 받아 다음 예제가 배열 예제로 작동한다고 생각합니다.

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

도움이 되었기를 바랍니다.


0

다음은 쉼표로 구분 된 문자열을 반복하는 MySQL의 예입니다.

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;

get_from_delimiter_split_string여기에 정의 된 함수를 사용합니다 : https://stackoverflow.com/a/59666211/3068233


쉼표로 구분 된 문자열은 이미 몇 년 전에 제안되었습니다.
einpoklum

@einpoklum yep-그리고 여기에 그들과 상호 작용하는 또 다른 방법이 있습니다
Ulad Kasach

0

배열 변수가 정말 필요합니까?

원래 여기에 MySQL 테이블 변수로 배열을 추가하고 싶었 기 때문에 묻습니다. 저는 데이터베이스 디자인에 비교적 익숙하지 않았고 일반적인 프로그래밍 언어 방식으로 어떻게 할 것인지 생각하려고했습니다.

그러나 데이터베이스는 다릅니다. 나는 생각했다 나는 변수로 배열을 싶었지만, 그냥 일반적인 MySQL 데이터베이스 연습이 아니다 것으로 나타났다.

표준 관행

배열에 대한 대체 솔루션은 추가 테이블을 추가 한 다음 외래 키로 원본 테이블을 참조하는 것입니다.

예를 들어, 가정의 모든 사람이 상점에서 구매하고자하는 모든 항목을 추적하는 애플리케이션을 상상해 봅시다.

원래 구상했던 테이블을 만드는 명령은 다음과 같을 것입니다.

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

나는 buy_list가 쉼표로 구분 된 항목의 문자열 또는 이와 유사한 것으로 구상했다고 생각합니다.

그러나 MySQL에는 배열 유형 필드가 없으므로 다음과 같은 것이 정말로 필요했습니다.

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)
);

여기에서 fk_person이라는 제약 조건을 정의합니다. BuyList의 'person'필드가 외래 키라고 말합니다. 즉, 다른 테이블의 기본 키, 특히 REFERENCES가 나타내는 Person 테이블의 'name'필드입니다.

또한 사람과 항목의 조합을 기본 키로 정의했지만 기술적으로는 필요하지 않습니다.

마지막으로 사람의 목록에있는 모든 항목을 가져 오려면 다음 쿼리를 실행할 수 있습니다.

SELECT item FROM BuyList WHERE person='John';

이것은 John의 목록에있는 모든 항목을 제공합니다. 배열이 필요하지 않습니다!


내 허용되는 해결책 임시 테이블을 사용하는 것입니다.
einpoklum

물론이야. 그런 다음 배열 유형을 만드는 방법을 찾고있는 저와 같은 사람을 위해이 답변을 포함했습니다. 처음에는 배열이 MySQL에서 유형이 아닌 이유를 처음에 이해하지 못했습니다. 그것은 의도적으로 보인다. 일반적인 경우는 여기에 표시되지 않았으므로 다른 사람들이 일반적으로 어레이가 필요하지 않다는 것을 이해하도록 배운 내용을 포함했습니다. 나는 당신이 내 대답을 선택하기를 기대하지 않습니다. 사용 사례에 따라 다릅니다. 특정 사용 사례에 대한 답변을 수락했으며 일반적인 사용 사례에 대해이 답변을 제공합니다.
kraftydevil

0

그런 테이블이 하나 있으면

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

및 배열 테이블 :

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 |

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         |
+------------+-------+--------+------------+-------------+

클린턴의 대답과 중복되는 것 같습니다.
einpoklum

-2

이 답변을 개선 할 수 있다고 생각합니다. 이 시도:

'장난'매개 변수는 CSV입니다. 즉. '1,2,3,4 ..... 등'

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;

이 방법은 검색된 CSV 값 문자열을 루프가 반복 될 때마다 점점 더 짧아 지므로 최적화에 더 좋을 것이라고 생각합니다.


당신이 말하는 '이 대답'은 무엇입니까? 또한 CSV 파일이 없습니다.
einpoklum

CSV 파일이 아니라 '1,2,3,4 ... etc'와 같은 CSV 값을 참조했습니다.
user2288580

-2

여러 컬렉션에 대해 이와 같은 것을 시도합니다. 저는 MySQL 초보자입니다. 함수 이름에 대해 죄송합니다. 어떤 이름이 가장 좋을지 결정할 수 없습니다.

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');

나는 당신이 제안하는지 이해할 생각하지만,이 ... 아마도 매우 느린 매우 다루기 힘든이며
einpoklum

스트레스 테스트 없이는 그것을지지하거나 무시할 수 없습니다. 기본적으로 임시 테이블 (또는 일반 테이블)에 대한 기본 키 조회 및 삽입입니다. 문제가 발생하거나 더 나은 방법을 찾을 때까지 사용하겠습니다. 하지만 저는 Oracle PL / SQL로 완전히 컴파일러와 게임을 작성하는 것과 같은 이상한 일을합니다.
Dave

-2

데이터를 배열이나 한 행으로 저장하는 대신 수신 된 모든 값에 대해 다른 행을 만들어야합니다. 이렇게하면 모두 합치는 것보다 이해하기가 훨씬 간단 해집니다.


방법 을 공유 해주세요
Nico Haase

-5

PHP의 serialize ()를 사용해 보셨습니까? 이를 통해 변수 배열의 내용을 PHP가 이해하고 데이터베이스에 대해 안전합니다 (먼저 이스케이프했다고 가정).

$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());

번호가 매겨진 배열 없이도 똑같이 할 수 있습니다.

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

또는

$array3 = array(
    'somethingNew'
);

7
나는 PHP로 작업하지 않기 때문에 나에게별로 관련이 없습니다.
einpoklum 2013 년

1
직렬화 대신 JSON을 사용하십시오. 더 일반적이고 언어 독립적입니다.
Rick James
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.