Bagaimana cara mensimulasikan variabel array di MySQL?

91

Ini muncul bahwa MySQL tidak memiliki variabel array yang. Apa yang harus saya gunakan?


Tampaknya ada dua alternatif yang disarankan: Skalar tipe-set dan tabel sementara . Pertanyaan yang saya tautkan menyarankan yang pertama. Tetapi apakah praktik yang baik untuk menggunakan ini sebagai ganti variabel array? Atau, jika saya menggunakan set, apa yang akan menjadi idiom berbasis set yang setara foreach?

einpoklum
sumber
2
Gunakan ELT.
Pacerier
1
@Pacerier: Dapatkah Anda menautkan ke diskusi ELT yang lebih verbose, mungkin dengan contoh yang lebih panjang?
einpoklum

Jawaban:

77

Nah, saya telah menggunakan tabel sementara, bukan variabel array. Bukan solusi terhebat, tapi berhasil.

Perhatikan bahwa Anda tidak perlu menentukan bidangnya secara formal, cukup buat menggunakan SELECT:

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

(Lihat juga Membuat tabel sementara dari pernyataan pilih tanpa menggunakan Buat Tabel .)

einpoklum
sumber
1
Ohhh: o Saya tidak tahu SQL memiliki ini !! Tabel hanya hidup untuk lingkup kueri al yang sedang dijalankan. RAPI!
iGbanam
2
@Yasky, Itu asalkan Anda tidak menggunakan kembali koneksi. Karena memang itu akan berlangsung sepanjang sesi.
Pacerier
Dan Anda tidak dapat menggunakan kembali tabel sementara. Jadi itu tidak terlalu berguna.
Yohanes
4
@ John: Ya, Anda dapat menggunakannya kembali, tetapi tidak dalam kueri yang sama.
einpoklum
46

Anda dapat mencapai ini di MySQL menggunakan 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;

EDIT: Atau Anda dapat melakukannya dengan menggunakan 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
 ...
);
Ya ampun
sumber
4
Bukankah loop hanya mungkin dalam prosedur tersimpan?
einpoklum
2
ya benar, mungkin di dalam prosedur, fungsi, dan pemicu yang tersimpan.
Omesh
1
Jadi saya tidak dapat menggunakan kode yang Anda berikan ... Saya membutuhkan sesuatu yang dapat diterapkan secara lebih umum.
einpoklum
Anda dapat menulis prosedur sampel yang disimpan dan CALLitu.
Omesh
1
Saya tidak berpikir array diperlukan. Anda dapat dengan mudah melakukannya menggunakan tabel sementara atau UNION ALLtanpa menggunakan prosedur.
Omesh
28

Coba gunakan fungsi FIND_IN_SET () dari MySql mis

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

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

Catatan: Anda tidak perlu SET variabel di StoredProcedure jika Anda meneruskan parameter dengan nilai CSV.

Himalaya Garg
sumber
Waspadai batas panjang, yang bisa sangat rendah: stackoverflow.com/q/2567000/1333493
Nemo
19

Saat ini menggunakan array JSON akan menjadi jawaban yang jelas.

Karena ini adalah pertanyaan lama tetapi masih relevan, saya memberikan contoh singkat. Fungsi JSON tersedia sejak mySQL 5.7.x / MariaDB 10.2.3

Saya lebih suka solusi ini daripada ELT () karena ini benar-benar lebih seperti sebuah array dan 'array' ini dapat digunakan kembali dalam kode.

Tapi hati-hati: Ini (JSON) pasti jauh lebih lambat daripada menggunakan tabel sementara. Ini hanya lebih berguna. imo.

Berikut adalah cara menggunakan array 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

Dan berikut sedikit contoh untuk menunjukkan cara kerjanya dalam suatu fungsi / prosedur:

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
sumber
Apakah Anda mengatakan ELT lebih lambat atau JSON lebih lambat?
Kanagavelu Sugumar
2
@Kanagavelu Sugumar: Pada saat penulisan, JSON pasti lebih lambat. Saya mengedit jawabannya untuk membuatnya lebih jelas.
SeparateReality
16

Tidak tahu tentang array, tetapi ada cara untuk menyimpan daftar yang dipisahkan koma di kolom VARCHAR normal.

Dan ketika Anda perlu menemukan sesuatu dalam daftar itu, Anda dapat menggunakan fungsi FIND_IN_SET () .

cacing
sumber
Jika saya ingin mencari subset dalam satu set, apakah ada cara?
Akshay Vishnoi
Maaf! Saya tidak yakin itu mungkin.
wormhit
Anda memiliki solusi terbaik
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
sumber
2
Tolong jelaskan bagaimana kode ini digunakan dan bagaimana itu menjawab pertanyaan.
einpoklum
Seperti di sini Anda membuat prosedur sederhana yang memberikan satu per satu elemen dari string tertentu yang berfungsi sebagai array dalam oracle.
Sagar Gangwal
Peramal? Pertanyaan ini bukan tentang Oracle. Juga, sepertinya Anda sedang mendefinisikan sebuah array di dalam prosedur.
einpoklum
Mohon periksa Syntex itu hanya untuk mysql
Sagar Gangwal
Jangan lewatkan koma terakhir!
Eagle_Eye
4

Saya tahu bahwa ini adalah respons yang agak terlambat, tetapi baru-baru ini saya harus menyelesaikan masalah yang serupa dan berpikir bahwa ini mungkin berguna bagi orang lain.

Latar Belakang

Pertimbangkan tabel di bawah ini yang disebut 'mytable':

Tabel awal

Masalahnya adalah menyimpan hanya 3 catatan terbaru dan menghapus semua catatan lama yang systemid = 1 (mungkin ada banyak catatan lain dalam tabel dengan nilai systemid lainnya)

Akan lebih baik jika Anda dapat melakukan ini hanya dengan menggunakan pernyataan

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

Namun ini belum didukung di MySQL dan jika Anda mencoba ini maka Anda akan mendapatkan kesalahan seperti

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

Jadi solusi diperlukan di mana array nilai diteruskan ke pemilih IN menggunakan variabel. Namun, karena variabel harus berupa nilai tunggal, saya perlu mensimulasikan sebuah array . Caranya adalah dengan membuat array sebagai daftar nilai yang dipisahkan koma (string) dan menetapkannya ke variabel sebagai berikut

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

Hasil yang disimpan di @myvar adalah

5,6,7

Selanjutnya, pemilih FIND_IN_SET digunakan untuk memilih dari larik yang disimulasikan

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

Hasil akhir gabungan adalah sebagai berikut:

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

Saya sadar bahwa ini adalah kasus yang sangat spesifik. Namun dapat dimodifikasi agar sesuai dengan kasus lain di mana variabel perlu menyimpan array nilai.

Saya harap ini membantu.

Clinton
sumber
3

Mungkin membuat tabel memori sementara dengan kolom (key, value) jika Anda menginginkan array asosiatif. Memiliki tabel memori adalah hal yang paling dekat dengan memiliki array di mysql

Pavle Lekic
sumber
Umm, saya tidak ingin array asosiatif, hanya array.
einpoklum
Anda dapat menggunakan tabel memori sementara dengan hanya satu kolom dan kemudian mengulang melalui nilai menggunakan kursor, yang paling dekat dengan menggunakan array dan untuk / sementara loop dalam bahasa pemrograman non-deklaratif
Pavle Lekic
Bahasa sebenarnya memiliki fitur ini, yaitu, tidak ada alasan sintaksis Anda tidak dapat memilih vektor ke dalam variabel seperti Anda memilih skalar ke dalamnya.
einpoklum
3

Begini cara saya melakukannya.

Pertama, saya membuat fungsi yang memeriksa apakah nilai Long / Integer / apa pun yang ada dalam daftar nilai yang dipisahkan dengan koma:

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;

Jadi sekarang Anda dapat mencari ID dalam daftar ID yang dipisahkan koma, seperti ini:

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

Dan Anda dapat menggunakan fungsi ini di dalam klausa WHERE, seperti ini:

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

Ini adalah satu-satunya cara yang saya temukan untuk meneruskan parameter "array" ke PROSEDUR.

chuckw
sumber
2

Bukankah titik larik harus efisien? Jika Anda hanya mengulang nilai, menurut saya kursor pada tabel sementara (atau permanen) lebih masuk akal daripada mencari koma, bukan? Juga lebih bersih. Cari "mysql DECLARE CURSOR".

Untuk akses acak, tabel sementara dengan kunci utama yang diindeks secara numerik. Sayangnya akses tercepat yang akan Anda dapatkan adalah tabel hash, bukan akses acak yang sebenarnya.

Amaigus
sumber
Ini adalah komentar, bukan jawaban. Saya tidak menunjukkan bahwa itulah yang ingin saya lakukan dengan array.
einpoklum
2

Saya heran tidak ada jawaban yang menyebutkan ELT / FIELD.

ELT / FIELD bekerja sangat mirip dengan array terutama jika Anda memiliki data statis.

FIND_IN_SET juga berfungsi serupa tetapi tidak memiliki fungsi pelengkap bawaan tetapi cukup mudah untuk menulisnya.

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
sumber
1

Ini berfungsi dengan baik untuk daftar nilai:

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;
pengguna2664904
sumber
1

Kedua versi yang menggunakan set tidak berfungsi untuk saya (diuji dengan MySQL 5.5). Fungsi ELT () mengembalikan seluruh set. Mempertimbangkan pernyataan WHILE hanya tersedia dalam konteks PROSEDUR, saya menambahkannya ke solusi saya:

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

Sejujurnya, menurut saya ini bukan praktik yang baik. Bahkan jika benar-benar diperlukan, ini hampir tidak bisa dibaca dan cukup lambat.

jmmeier
sumber
1

Cara lain untuk melihat masalah yang sama. Semoga bermanfaat

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
sumber
Sebenarnya, tidak jelas apa yang Anda katakan di sini. Pertanyaan dari 7 tahun yang lalu ini memiliki beberapa jawaban yang relevan. Pertimbangkan untuk menghapus jawaban Anda atau menjelaskan apa yang ingin Anda sampaikan kepada kami secara langsung / umumnya daripada melalui contoh.
einpoklum
0

Dalam versi MYSQL setelah 5.7.x, Anda dapat menggunakan tipe JSON untuk menyimpan array. Anda bisa mendapatkan nilai array dengan kunci melalui MYSQL.

nick sialan
sumber
7
Dapatkah Anda memberi contoh bagaimana saya akan melakukan ini?
einpoklum
0

Terinspirasi oleh fungsi ELT (nomor indeks, string1, string2, string3,…), saya rasa contoh berikut berfungsi sebagai contoh array:

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

Semoga membantu.

Edward
sumber
0

Berikut adalah contoh MySQL untuk melakukan perulangan melalui string yang dipisahkan koma.

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;

ini menggunakan get_from_delimiter_split_stringfungsi yang ditentukan di sini: https://stackoverflow.com/a/59666211/3068233

Ulad Kasach
sumber
string yang dipisahkan koma telah disarankan - bertahun-tahun yang lalu.
einpoklum
@einpoklum ya - dan ini adalah cara lain untuk berinteraksi dengan mereka
Ulad Kasach
0

Apakah variabel array benar-benar diperlukan?

Saya bertanya karena saya awalnya mendarat di sini ingin menambahkan array sebagai variabel tabel MySQL. Saya relatif baru dalam desain database dan mencoba memikirkan bagaimana saya akan melakukannya dengan gaya bahasa pemrograman yang khas.

Tetapi database berbeda. Saya pikir saya ingin sebuah array sebagai variabel, tetapi ternyata itu bukan praktik database MySQL yang umum.

Praktek Standar

Solusi alternatif untuk array adalah dengan menambahkan tabel tambahan, dan kemudian mereferensikan tabel asli Anda dengan kunci asing.

Sebagai contoh, mari kita bayangkan aplikasi yang melacak semua barang yang ingin dibeli setiap orang di rumah tangga di toko.

Perintah untuk membuat tabel yang awalnya saya bayangkan akan terlihat seperti ini:

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

Saya rasa saya membayangkan buy_list menjadi string item yang dipisahkan koma atau sesuatu seperti itu.

Tetapi MySQL tidak memiliki kolom tipe array, jadi saya sangat membutuhkan sesuatu seperti ini:

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

Di sini kami mendefinisikan batasan bernama fk_person. Dikatakan bahwa bidang 'orang' di BuyList adalah kunci asing. Dengan kata lain, ini adalah kunci utama di tabel lain, khususnya bidang 'nama' di tabel Orang, yang ditunjukkan oleh REFERENSI.

Kami juga mendefinisikan kombinasi orang dan item menjadi kunci utama, tetapi secara teknis itu tidak perlu.

Terakhir, jika Anda ingin mendapatkan semua item di daftar seseorang, Anda dapat menjalankan kueri ini:

SELECT item FROM BuyList WHERE person='John';

Ini memberi Anda semua item di daftar John. Tidak perlu array!

kraftydevil.dll
sumber
Solusi yang saya terima adalah menggunakan tabel sementara.
einpoklum
Tentu saja. Saya kemudian menyertakan jawaban ini untuk orang seperti saya yang sampai ke halaman ini mencari cara untuk membuat tipe array - yang awalnya tidak mengerti mengapa array bukanlah tipe di MySQL. Sepertinya memang begitu. Kasus umum tidak terwakili di sini jadi saya menyertakan apa yang saya pelajari agar orang lain memahami bahwa array biasanya tidak diperlukan. Saya tidak berharap Anda memilih jawaban saya. Itu tergantung pada kasus penggunaan. Anda memiliki jawaban yang diterima untuk kasus penggunaan tertentu dan saya memberikan jawaban ini untuk kasus penggunaan umum.
kraftydevil
0

Jika kita punya satu meja seperti itu

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

dan tabel 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 |

Kita dapat memilih baris dari tabel kedua sebagai satu larik dengan fungsi 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         |
+------------+-------+--------+------------+-------------+
aitor
sumber
Duplikat dari jawaban Clinton, saya kira.
einpoklum
-2

Saya pikir saya dapat memperbaiki jawaban ini. Coba ini:

Parameter 'Pranks' adalah CSV. yaitu. '1,2,3,4 ..... dll'

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;

Metode ini membuat string nilai CSV yang dicari semakin pendek dengan setiap iterasi loop, yang menurut saya akan lebih baik untuk pengoptimalan.

pengguna2288580
sumber
Apa yang dimaksud dengan 'jawaban ini'? Selain itu, Anda tidak bisa memiliki file CSV.
einpoklum
Saya tidak mengacu pada file CSV, saya mengacu pada nilai CSV seperti '1,2,3,4 ... dll'
pengguna2288580
-2

Saya akan mencoba sesuatu seperti ini untuk beberapa koleksi. Saya seorang pemula MySQL. Maaf tentang nama fungsi, tidak bisa memutuskan nama mana yang terbaik.

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
sumber
Saya rasa saya mengerti apa yang Anda sarankan, tapi ini cukup berat dan mungkin juga sangat lambat ...
einpoklum
Saya tidak dapat mendukung atau mengabaikannya tanpa mengujinya. Ini pada dasarnya adalah pencarian dan penyisipan kunci utama pada tabel sementara (atau tabel normal). Saya akan menggunakannya sampai saya mengalami masalah atau menemukan cara yang lebih baik; tetapi saya melakukan hal-hal aneh seperti menulis kompiler dan game sepenuhnya di Oracle PL / SQL.
Dave
-2

Daripada Menyimpan data sebagai array atau hanya dalam satu baris, Anda harus membuat baris yang berbeda untuk setiap nilai yang diterima. Ini akan membuatnya lebih sederhana untuk dipahami daripada menyatukan semuanya.

chirag mathur
sumber
Silakan berbagi cara melakukan ini
Nico Haase
-5

Sudahkah Anda mencoba menggunakan serialize () PHP? Itu memungkinkan Anda untuk menyimpan konten array variabel dalam string yang dipahami PHP dan aman untuk database (dengan asumsi Anda telah lolos terlebih dahulu).

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

Anda juga dapat melakukan hal yang sama tanpa larik bernomor

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

atau

$array3 = array(
    'somethingNew'
);
Magictallguy
sumber
7
Saya tidak bekerja dengan PHP, jadi itu tidak terlalu relevan untuk saya.
einpoklum
1
Gunakan JSON sebagai ganti serialisasi. Ini lebih umum dan tidak bergantung pada bahasa.
Rick James