আমি কীভাবে মাইএসকিউএল এ অ্যারে ভেরিয়েবল অনুকরণ করতে পারি?


91

এটি প্রদর্শিত হয় যে মাইএসকিউএলে অ্যারে ভেরিয়েবলগুলি নেই। পরিবর্তে আমার কী ব্যবহার করা উচিত?


প্রস্তাবিত দুটি বিকল্প রয়েছে বলে মনে হচ্ছে: একটি সেট-টাইপ স্কেলার এবং অস্থায়ী সারণী । আমি যে প্রশ্নটির সাথে লিঙ্ক করেছি তা প্রাক্তনটির পরামর্শ দেয়। তবে অ্যারে ভেরিয়েবলের পরিবর্তে এগুলি ব্যবহার করা কি ভাল অনুশীলন? বিকল্পভাবে, আমি যদি সেটগুলি নিয়ে যাই তবে সেট-ভিত্তিক আইডিয়ামটি সমান কী হবে foreach?


4
ব্যবহার ELT
পেসারিয়ার

4
@ পেসারিয়র: আপনি কি আরও দীর্ঘতর উদাহরণ দিয়ে ইএলটি-র আরও ভার্জোজ আলোচনার সাথে লিঙ্ক করতে পারেন?
einpoklum

উত্তর:


77

ঠিক আছে, আমি অ্যারে ভেরিয়েবলের পরিবর্তে অস্থায়ী টেবিলগুলি ব্যবহার করছি। সবচেয়ে বড় সমাধান নয়, তবে এটি কাজ করে।

মনে রাখবেন যে তাদের ক্ষেত্রগুলি আনুষ্ঠানিকভাবে সংজ্ঞায়িত করার দরকার নেই, কেবল সেফেক্ট ব্যবহার করে এগুলি তৈরি করুন:

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

(এছাড়াও সারণী তৈরি না করে নির্বাচন করা বিবৃতি থেকে অস্থায়ী সারণী তৈরি করুন দেখুন ))


4
ওহ: ও, আমি জানতাম না এসকিউএল এটি ছিল !! টেবিলগুলি কেবলমাত্র ক্যোয়ারী চালানোর সুযোগের জন্য জীবিত। সুন্দর!
iGbanam

4
@ ইয়াস্কি, এটি আপনাকে সরবরাহ করে যে সংযোগটি পুনরায় ব্যবহার করবেন না। কারণ এটি পুরো অধিবেশন স্থায়ী হবে ।
পেসারিয়ার

এবং আপনি একটি অস্থায়ী টেবিলটি পুনরায় ব্যবহার করতে পারবেন না। সুতরাং এটি খুব দরকারী নয়।
জন 18


4
@ জন: হ্যাঁ, আপনি এটি পুনরায় ব্যবহার করতে পারেন , তবে একই ক্যোয়ারিতে নয়।
einpoklum

46

আপনি WHILEলুপ ব্যবহার করে মাইএসকিউএল এ অর্জন করতে পারেন :

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

4
হ্যাঁ ঠিক আছে, সঞ্চিত পদ্ধতি, ফাংশন এবং ট্রিগারগুলির মধ্যে এটির সম্ভাব্য।
ওমেশ

4
সুতরাং আপনার প্রদত্ত কোডটি আমি ব্যবহার করতে পারি না ... আমার এমন কিছু প্রয়োজন যা সাধারণত প্রয়োগ হয়।
einpoklum

আপনি একটি নমুনা সঞ্চিত পদ্ধতি লিখতে পারেন এবং CALLএটি।
ওমেশ

4
আমি মনে করি না অ্যারে দরকার হয়। আপনি অস্থায়ী টেবিলগুলি ব্যবহার করে বা UNION ALLপদ্ধতিটি ব্যবহার না করে সহজেই এটি করতে পারেন ।
ওমেশ

28

মাইএসকিউএল যেমন FIND_IN_SET () ফাংশনটি ব্যবহার করে দেখুন

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

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

দ্রষ্টব্য: আপনি যদি CSV মানগুলির সাথে প্যারামিটারটি পাস করে থাকেন তবে আপনার স্টোরেডপ্রসেসুয়োরে এসইটি ভেরিয়েবলের দরকার নেই।


দৈর্ঘ্যের সীমা সম্পর্কে সতর্ক থাকুন, যা বেশ কম হতে পারে: stackoverflow.com/q/2567000/1333493
নিমো

19

আজকাল JSON অ্যারে ব্যবহার করা একটি সুস্পষ্ট উত্তর হবে।

যেহেতু এটি একটি পুরানো তবে এখনও প্রাসঙ্গিক প্রশ্ন আমি একটি ছোট উদাহরণ তৈরি করেছি produced মাইএসকিউএল 5.7.x / মারিয়াডিবি 10.2.3 থেকে জেএসএন ফাংশন উপলব্ধ

আমি এই সমাধানটি ইএলটি () এর চেয়ে বেশি পছন্দ করি কারণ এটি সত্যিই আরও বেশি অ্যারের মতো এবং এই 'অ্যারে' কোডটিতে পুনরায় ব্যবহার করা যেতে পারে।

তবে সতর্কতা অবলম্বন করুন: এটি (জেএসএন) অস্থায়ী টেবিল ব্যবহারের চেয়ে অবশ্যই অনেক ধীর। এটি আরও সহজ। 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();

আপনি কি বলছেন ইএলটি ধীর বা জেএসএন ধীর?
কানাগাভেলু সুগুমার

4
@ কানগাভেলু সুগুমার: জেএসওএন লেখার সময় অবশ্যই ধীর। আরও পরিষ্কার করার জন্য আমি উত্তরটি সম্পাদনা করেছি।
বিচ্ছিন্নতা

16

অ্যারেগুলি সম্পর্কে জানেন না, তবে সাধারণ ভিচারার কলামে কমা-বিচ্ছিন্ন তালিকা সংরক্ষণ করার একটি উপায় রয়েছে।

এবং যখন আপনাকে সেই তালিকায় কোনও কিছু সন্ধান করার দরকার পড়ে আপনি এফআইND_IN_SET () ফাংশনটি ব্যবহার করতে পারেন ।


আমি যদি একটি সেটে সাবসেটটি খুঁজতে চাই তবে কোনও উপায় আছে কি?
অক্ষয় বিষ্ণোই

দুঃখিত! আমি নিশ্চিত যে এটি সম্ভব।
ওয়ার্মহিত

আপনার কাছে সেরা সমাধান রয়েছে
ক্যালভিন

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 ;

4
দয়া করে ব্যাখ্যা করুন যে এই কোডটি কীভাবে ব্যবহার করতে হয় এবং এটি কীভাবে প্রশ্নের উত্তর দেয়।
einpoklum

এখানে যেমন আপনি সাধারণ পদ্ধতি তৈরি করেন যা নির্দিষ্ট স্ট্রিংয়ের একটি করে একটি উপাদান দেয় যা ওরাকলে অ্যারে হিসাবে কাজ করে।
সাগর গাঙ্গওয়াল

ওরাকল? এই প্রশ্নটি ওরাকল সম্পর্কে নয়। এছাড়াও, দেখে মনে হচ্ছে আপনি প্রক্রিয়াটির মধ্যে একটি অ্যারের সংজ্ঞা দিচ্ছেন।
einpoklum

দয়া করে
সিনটেক্স

শেষ কমা মিস করবেন না!
agগল_এই

4

আমি জানি যে এটি কিছুটা দেরিতে প্রতিক্রিয়া, তবে আমি সম্প্রতি একটি অনুরূপ সমস্যা সমাধান করতে হয়েছিল এবং ভেবেছিলাম এটি অন্যের পক্ষে কার্যকর হতে পারে।

পটভূমি

নীচের টেবিলটি 'মাইটেবিল' বলে বিবেচনা করুন:

টেবিল শুরু হচ্ছে

সমস্যাটি ছিল কেবলমাত্র সর্বশেষ 3 টি রেকর্ড রাখা এবং পুরানো রেকর্ডগুলি মুছে ফেলা যার সিস্টেমেড = 1 (অন্যান্য সিস্টেমেড মান সহ টেবিলে আরও অনেক রেকর্ড থাকতে পারে)

এটি ভাল হবে আপনি বিবৃতি ব্যবহার করে এটি করতে পারেন

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

তবে এটি এখনও মাইএসকিউএলে সমর্থিত নয় এবং আপনি যদি এটি চেষ্টা করেন তবে আপনি এর মতো একটি ত্রুটি পাবেন

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

সুতরাং একটি workaround প্রয়োজন হয় যার মাধ্যমে মানগুলির একটি অ্যারে পরিবর্তনশীল ব্যবহার করে 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);

@ মাইভারে সঞ্চিত ফলাফল

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

যদি আপনি সহযোগী অ্যারে চান তবে কলামগুলি (কী, মান) দিয়ে একটি অস্থায়ী মেমরি টেবিল তৈরি করুন। মেমোসিএলে অ্যারে রাখার সবচেয়ে কাছের জিনিস একটি মেমরি টেবিল থাকা


উম্ম, আমি সহযোগী অ্যারে চাই না, কেবল অ্যারে চাই।
einpoklum

আপনি কেবলমাত্র একটি কলাম সহ একটি অস্থায়ী মেমরি টেবিল ব্যবহার করতে পারেন এবং তারপরে কার্সার ব্যবহার করে মানগুলি লুপ করে নিতে পারেন, এটি অ্যারে ব্যবহারের সবচেয়ে কাছের জিনিস এবং যখন / অ-ঘোষণামূলক প্রোগ্রামিং ভাষায় লুপগুলি হয়
পাভলে লেকিক

ভাষার প্রকৃতপক্ষে এই বৈশিষ্ট্যটি রয়েছে, অর্থাত্ কোনও সিন্ট্যাক্টিক কারণ নেই যে আপনি কোনও ভেক্টরকে কোনও ভেরিয়েলেলেটের মতো বেছে নিতে সক্ষম হবেন না যেমন আপনি এটিতে কোনও স্কেলার নির্বাচন করেন।
einpoklum

3

আমি এটি কীভাবে করেছি তা এখানে।

প্রথমত, আমি একটি ফাংশন তৈরি করেছি যা পরীক্ষা করে একটি দীর্ঘ / পূর্ণসংখ্যার / যে কোনও মান কমা দ্বারা পৃথক করা মানগুলির তালিকায় রয়েছে:

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;

সুতরাং এখন আপনি এই জাতীয় আইডির কমা-বিচ্ছিন্ন তালিকায় একটি আইডি অনুসন্ধান করতে পারেন:

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

এবং আপনি এই জাতীয় ফাংশনটি যেখানে একটি ক্লুজের মধ্যে ব্যবহার করতে পারেন:

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

এটিই কেবলমাত্র কোনও পদ্ধতির কোনও "অ্যারে" পরামিতিটি দেখতে পেলাম।


2

অ্যারে এর বিন্দু কি কার্যকর হবে না? যদি আপনি কেবল মানগুলির মাধ্যমে পুনরাবৃত্তি করেন, আমার মনে হয় একটি অস্থায়ী (বা স্থায়ী) টেবিলের একটি কার্সার কমা অনুসন্ধানের চেয়ে আরও বেশি অর্থবোধ করে, না? ক্লিনারও। "Mysql DECLARE CURSOR" সন্ধান করুন।

এলোমেলোভাবে অ্যাক্সেসের জন্য সংখ্যাসূচকভাবে সূচিত প্রাথমিক কী সহ একটি অস্থায়ী টেবিল। দুর্ভাগ্যক্রমে আপনি যে দ্রুততম অ্যাক্সেস পাবেন তা হ্যাশ টেবিল, সত্য র্যান্ডম অ্যাক্সেস নয়।


এটি একটি মন্তব্য নয়, কোনও উত্তর নয়। অ্যারের সাথে আমি কী করতে চাই তা আমি নির্দেশ করি নি।
einpoklum

2

আমি বিস্মিত হয়েছি উত্তরগুলির কোনওটিই ইএলটি / ফিল্ডের উল্লেখ করে না।

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

সেট ব্যবহার করে উভয় সংস্করণই আমার পক্ষে কার্যকর হয়নি (মাইএসকিউএল 5.5 এর সাথে পরীক্ষিত)। ELT () ফাংশনটি পুরো সেটটি দেয়। WHIL এর বিবৃতি বিবেচনা করা কেবলমাত্র প্রক্রিয়া প্রসঙ্গেই এটি উপলব্ধ i

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

0

Y.7.x এর পরে এমওয়াইএসকিউএল সংস্করণে, আপনি অ্যারে সঞ্চয় করতে JSON প্রকারটি ব্যবহার করতে পারেন। আপনি এমওয়াইএসকিউএল এর মাধ্যমে একটি অ্যারের মান পেতে পারেন।


7
আমি কীভাবে এটি করব তার উদাহরণ দিতে পারেন?
einpoklum

0

ELT (সূচক সংখ্যা, স্ট্রিং 1, স্ট্রিং 2, স্ট্রিং 3,…) দ্বারা অনুপ্রাণিত হয়ে আমি মনে করি যে নিম্নলিখিত উদাহরণটি অ্যারের উদাহরণ হিসাবে কাজ করে:

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

আশা করি এটি সাহায্য করবে।


0

কমা বিস্মৃত স্ট্রিংয়ের মাধ্যমে লুপিংয়ের জন্য মাইএসকিউএলের একটি উদাহরণ এখানে।

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

@ আইনপোকলুম ইয়েপ - এবং তাদের সাথে আলাপচারিতার আরেকটি উপায় এখানে রয়েছে
উলাদ কাসাচ

0

একটি অ্যারে ভেরিয়েবল কি আসলেই প্রয়োজনীয়?

আমি জিজ্ঞাসা করি কারণ আমি এখানে মূলত একটি মাইএসকিউএল টেবিল ভেরিয়েবল হিসাবে একটি অ্যারে যুক্ত করতে চাইছিলাম land আমি ডাটাবেস ডিজাইনে তুলনামূলকভাবে নতুন ছিলাম এবং এটি কীভাবে একটি সাধারণ প্রোগ্রামিং ভাষার ফ্যাশনে করব তা ভেবে দেখার চেষ্টা করছিলাম।

তবে ডাটাবেসগুলি আলাদা। আমি ভেবেছিলাম যে আমি একটি ভেরিয়েবল হিসাবে অ্যারে চেয়েছি, তবে এটি সক্রিয় যে এটি একটি সাধারণ মাইএসকিউএল ডাটাবেস অনুশীলন নয়।

মানসম্মত চর্চা

অ্যারেগুলির বিকল্প সমাধানটি একটি অতিরিক্ত টেবিল যুক্ত করা এবং তারপরে একটি বিদেশী কী দিয়ে আপনার মূল টেবিলটি উল্লেখ করুন।

উদাহরণস্বরূপ, আসুন এমন একটি অ্যাপ্লিকেশনটি কল্পনা করুন যা পরিবারের প্রতিটি ব্যক্তি দোকানে কেনাকাটা করতে চায় এমন সমস্ত আইটেমের উপর নজর রাখে।

মূলত আপনি যে টেবিলটি কল্পনা করেছিলেন সেগুলি তৈরির জন্য যে কমান্ডগুলি রয়েছে তা দেখতে এরকম কিছু দেখতে পেত:

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

আমি মনে করি আমি ক্রেতা তালিকাটি আইটেমের কমা-বিচ্ছিন্ন স্ট্রিং বা এর মতো কিছু হিসাবে কল্পনা করেছি।

তবে মাইএসকিউএলের একটি অ্যারে টাইপ ক্ষেত্র নেই, সুতরাং আমার সত্যিই এর মতো কিছু দরকার ছিল:

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_Press নামে একটি সীমাবদ্ধতা সংজ্ঞায়িত করি। এটি বলে যে বায়লিস্টে 'ব্যক্তি' ক্ষেত্রটি একটি বিদেশী কী। অন্য কথায়, এটি অন্য টেবিলের একটি প্রাথমিক কী, বিশেষত পার্সন টেবিলের 'নাম' ক্ষেত্র, যা নির্দেশকে বোঝায়।

আমরা ব্যক্তি এবং আইটেমের সমন্বয়টিকে প্রাথমিক কী হিসাবে সংজ্ঞায়িত করেছি, তবে প্রযুক্তিগতভাবে এটি প্রয়োজনীয় নয় necessary

অবশেষে, আপনি যদি কোনও ব্যক্তির তালিকায় সমস্ত আইটেম পেতে চান তবে আপনি এই ক্যোয়ারীটি চালাতে পারেন:

SELECT item FROM BuyList WHERE person='John';

এটি আপনাকে জন তালিকার সমস্ত আইটেম দেয়। কোন অ্যারে প্রয়োজন নেই!


আমার গৃহীত সমাধান হয় একটি অস্থায়ী টেবিল ব্যবহার করতে।
einpoklum

অবশ্যই. তারপরে আমি আমার মতো যে কারও জন্য এই উত্তরটি অন্তর্ভুক্ত করেছি যা এই পৃষ্ঠায় পেয়েছে একটি অ্যারে টাইপ তৈরির উপায় খুঁজছেন - যারা প্রাথমিকভাবে বুঝতে পারেন নি কেন অ্যারেগুলি মাইএসকিউএল তে টাইপ নয় কেন। এটি নকশা দ্বারা এটি মনে হয়। সাধারণ কেসটি এখানে উপস্থাপন করা হয়নি তাই অন্যদের বুঝতে যে অ্যারেগুলি সাধারণত প্রয়োজন হয় না তা আমি অন্তর্ভুক্ত করি। আমি আশা করি না আপনি আমার উত্তরটি নির্বাচন করবেন। এটি নির্ভর করে ব্যবহারের ক্ষেত্রে। নির্দিষ্ট ব্যবহারের ক্ষেত্রে আপনার কাছে স্বীকৃত উত্তর রয়েছে এবং আমি সাধারণ ব্যবহারের ক্ষেত্রে এই উত্তরটি সরবরাহ করছি।
ক্রাফটিদেবিল

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 |

কনক্যাট ফাংশন সহ আমরা দ্বিতীয় টেবিলের সারিগুলি একটি অ্যারে হিসাবে নির্বাচন করতে পারি:

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

ক্লিনটনের উত্তরটির সদৃশ, আমার ধারণা।
আইনপোকলম

-2

আমি মনে করি আমি এই উত্তরে উন্নতি করতে পারি। এটা চেষ্টা কর:

'প্রংকস' প্যারামিটারটি একটি সিএসভি। অর্থাত্ '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 মানগুলির অনুসন্ধানের স্ট্রিংটিকে লুপের প্রতিটি পুনরাবৃত্তির সাথে ক্রমান্বয়ে সংক্ষিপ্ত করে তোলে, যা আমি বিশ্বাস করি যে এটি অপ্টিমাইজেশনের জন্য আরও ভাল।


আপনি যে 'এই উত্তর' উল্লেখ করছেন তা কী? এছাড়াও, আপনার কাছে কোনও সিএসভি ফাইল নেই।
einpoklum

আমি কোনও সিএসভি ফাইলের উল্লেখ করছি না, আমি সিএসভি মান উল্লেখ করছি যেমন '1,2,3,4 ... ইত্যাদি'
ইউজার 2288580

-2

আমি একাধিক সংগ্রহের জন্য এরকম কিছু চেষ্টা করব। আমি একজন মাইএসকিউএল শিক্ষানবিস। ফাংশনটির নামগুলির জন্য দুঃখিত, কোন নামটি সবচেয়ে ভাল হবে তা সিদ্ধান্ত নিতে পারেনি।

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

আমি মনে করি আপনি কী পরামর্শ দিচ্ছেন তা আমি বুঝতে পেরেছি তবে এটি বেশ
অযৌক্তিক

স্ট্রেস টেস্ট না করে আমি এটিকে অনুমোদন বা বরখাস্ত করতে পারি না। এটি মূলত অস্থায়ী টেবিলের (বা সাধারণ টেবিল) একটি প্রাথমিক কী লুক এবং সন্নিবেশ। যতক্ষণ না আমি সমস্যায় পড়েছি বা আরও ভাল উপায় না পাচ্ছি আমি এটিকে ব্যবহার করব; তবে আমি পুরোপুরি ওরাকল পিএল / এসকিউএল-এ কম্পাইলার এবং গেমস লেখার মতো অদ্ভুত জিনিস করি।
ডেভ

-2

অ্যারে হিসাবে বা এক সারিতে ডেটা সংরক্ষণ করার পরিবর্তে আপনার প্রাপ্ত প্রতিটি মানের জন্য পৃথক সারি করা উচিত। এটি সমস্ত একসাথে রাখার চেয়ে বোঝা আরও সহজ করে তুলবে।


এটি কীভাবে করবেন তা ভাগ করুন
নিকো হাজেস

-5

আপনি কি পিএইচপি এর সিরিয়ালাইজ () ব্যবহার করার চেষ্টা করেছেন? এটি আপনাকে পিষে পিএইচপি বুঝতে পারে এমন একটি স্ট্রিংয়ে ভেরিয়েবলের অ্যারের সামগ্রী সংরক্ষণ করতে দেয় এবং ডাটাবেসটির জন্য নিরাপদ (ধরে নিলে আপনি এটির আগে পালিয়ে গেছেন)।

$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
আমি পিএইচপি এর সাথে কাজ করছি না, সুতরাং এটি আমার পক্ষে সত্যিকারের প্রাসঙ্গিক নয়।
einpoklum

4
সিরিয়ালাইজের পরিবর্তে জেএসএন ব্যবহার করুন। এটি আরও জেনেরিক এবং ভাষা-স্বাধীন।
রিক জেমস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.