เพื่อแก้ปัญหานี้ถ้าใช้ Application layer มาช่วยจะทำได้ค่อนข้างจะง่าย
โจทย์คือ เรามี CHARACTER FIELD อยู่ และอยาก SLIT ออกเป็น Column ย่อยๆ
จำนวน n Column แตละ ข้อมูลแต่ละ Column คือ ตัวอักษรลำดับที่ n
โดยที่ n เริ่มจาก 1 ถึง ความยาวที่มากที่สุดของ Field นั้น
โจทย์นี้น่าจะมีทางออกทางเดียวในกรณีที่ใช้ DATA LAYER คือ DYNAMIC SQL
ตอนแรกพยายามทำให้เป็น FULL DYNAMIC แต่ไปไม่รอดค่ะ
มันจะมีการส่งค่าหากันระหว่าง Function เลยต้องผสมๆ
ใน Code เป็น MySQL Store procedure โดยอ้างจากตารางชื่อ A1
และมี FIELD ชื่อ DATA เป็นเก็บตัวข้อมูล
คุณก็เอาไปเปลี่ยนเป็นชื่อ TABLE และ FIELD ของคุณค่ะ
โดยไปแก้ใน GENERATE_RICE_GENOTYPE ที่เป็น Procedure หลัก
ค่าที่ใช้ทดสอบ ดังที่เห็นใน Screen shot ซึ่งก็น่าจะคล้ายข้อมูลจริงนะคะ
อีกอย่าง procedure GENERATE_RICE_GENOTYPE มี Parameter หนึ่งตัว
เป็นชื่อ Field อื่นๆ ที่คุณต้องการให้ output ออกมาด้วย เช่น id ค่ะ
แล้ว ทำไมไม่เขียน เป็น PHP ตอบแบบเดิม ส่วนตัวไม่ชอบ PHP ค่ะ
และการใช้ STORE PROCEDURE ก้อใช้ได้ทุกภาษาอีกทั้งความเร็วในการ Run
Store procedure จะเร็วกว่าในทุกกรณีค่ะ และเมื่อพัฒนาเสร็จ
เราก็เรียกใช้งานแบบง่ายๆ ได้สะดวกค่ะ
Code (C#)
DELIMITER $$
DROP PROCEDURE IF EXISTS `GENERATE_RICE_GENOTYPE` $$
CREATE PROCEDURE `GENERATE_RICE_GENOTYPE`
(
_VAR_ORTHER_FIELDS_LIST TEXT
)
BEGIN
DECLARE _STR TEXT DEFAULT '';
DECLARE _DYNAMIC_COLUMN_STR TEXT DEFAULT '';
DECLARE _MAX_LENGTH INT DEFAULT 0 ;
SELECT MAX(LENGTH(`DATA`)) INTO _MAX_LENGTH FROM `A1` ;
SET _DYNAMIC_COLUMN_STR = GENERATE_GENOTYPE_COLUMN ( '_GENOTYPE_PRIME' ,_MAX_LENGTH ) ;
IF (LENGTH(_VAR_ORTHER_FIELDS_LIST) > 0) THEN
SET _STR = CONCAT(_VAR_ORTHER_FIELDS_LIST, ',') ;
END IF;
SET _STR = CONCAT( 'SELECT ' ,_STR ,' RPAD(`DATA`, @MAXLENGTH ,\' \')'
,' AS _GENOTYPE_PRIME FROM A1 AS QR_MAIN'
,' \t,(SELECT @MAXLENGTH:=MAX(LENGTH(`DATA`))'
,' FROM `A1`) as QR_GETMAXLENGTH ');
SET _STR = CONCAT('SELECT * ,',_DYNAMIC_COLUMN_STR , ' FROM '
,'( ', _STR, ') AS QR_SECONDARY ;');
SET @CMDSTR = _STR ;
PREPARE _DYNAMIC_SQL FROM @CMDSTR ;
EXECUTE _DYNAMIC_SQL ;
DEALLOCATE PREPARE _DYNAMIC_SQL ;
END $$
DELIMITER ;
และ
Code (C#)
DELIMITER $$
DROP FUNCTION IF EXISTS `GENERATE_GENOTYPE_COLUMN` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `GENERATE_GENOTYPE_COLUMN`(
_VAR_FIELD_NAME TEXT ,_VAR_MAX_DATA_IN_FIELD_LEN INT
) RETURNS text CHARSET tis620
BEGIN
DECLARE _STR_RET TEXT DEFAULT '';
DECLARE _COUNTER INT DEFAULT 0 ;
DECLARE _TEMP_STR TEXT DEFAULT '' ;
DECLARE _FIELD_PARSER TEXT DEFAULT '' ;
REPEAT
SET _COUNTER = _COUNTER + 1;
SET _TEMP_STR = CONCAT ('SUBSTRING(`', _VAR_FIELD_NAME, '`,'
,_COUNTER, ',1) AS `', _COUNTER ,'`');
IF _COUNTER = 1 THEN
SET _FIELD_PARSER = CONCAT('\t', _TEMP_STR) ;
ELSE
SET _FIELD_PARSER = CONCAT( _FIELD_PARSER,'\n\t, ', _TEMP_STR ) ;
END IF ;
UNTIL (_COUNTER > _VAR_MAX_DATA_IN_FIELD_LEN) END REPEAT ;
SET _STR_RET = _FIELD_PARSER ;
RETURN _STR_RET ;
END $$
DELIMITER ;
ที่คุณต้องทำคือเอา RUN ใน MYSQL BROWSER
จะได้ STORE PROCEDURE มาสองอัน
ที่คุณต้องไปแก้นิดหน่อย คือ GENERATE_RICE_GENOTYPE
เพื่อเปลี่ยนเป็นชื่อ FIELD กับ TABLE ของคุณเท่านั้นเองค่ะ