เพิ่มคอลัมน์ในตาราง mysql หากไม่มีอยู่


109

การวิจัยและการทดลองของฉันยังไม่ได้รับคำตอบดังนั้นฉันจึงหวังว่าจะได้รับความช่วยเหลือ

ฉันกำลังแก้ไขไฟล์การติดตั้งของแอปพลิเคชันซึ่งในเวอร์ชันก่อนหน้าไม่มีคอลัมน์ที่ฉันต้องการเพิ่มในตอนนี้ ฉันไม่ต้องการเพิ่มคอลัมน์ด้วยตนเอง แต่อยู่ในไฟล์การติดตั้งและเฉพาะในกรณีที่คอลัมน์ใหม่ไม่มีอยู่ในตาราง

ตารางถูกสร้างขึ้นดังนี้:

CREATE TABLE IF NOT EXISTS `#__comm_subscribers` (
      `subscriber_id` int(11) NOT NULL auto_increment,
      `user_id` int(11) NOT NULL default '0',
      `subscriber_name` varchar(64) NOT NULL default '',
      `subscriber_surname` varchar(64) NOT NULL default '',
      `subscriber_email` varchar(64) NOT NULL default '',
      `confirmed` tinyint(1) NOT NULL default '0',
      `subscribe_date` datetime NOT NULL default '0000-00-00 00:00:00',
      PRIMARY KEY  (`subscriber_id`),
      UNIQUE KEY `subscriber_email` (`subscriber_email`)
    ) ENGINE=MyISAM CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' COMMENT='Subscribers for Comm are stored here.';

หากฉันเพิ่มสิ่งต่อไปนี้ด้านล่างคำสั่งสร้างตารางฉันไม่แน่ใจว่าจะเกิดอะไรขึ้นถ้าคอลัมน์มีอยู่แล้ว (และอาจมีการเติมข้อมูล):

ALTER TABLE `#__comm_subscribers` ADD `subscriber_surname`;
ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';

ดังนั้นฉันจึงลองสิ่งต่อไปนี้ซึ่งฉันพบที่ไหนสักแห่ง ดูเหมือนจะไม่ได้ผล แต่ฉันไม่แน่ใจว่าใช้อย่างถูกต้องทั้งหมด

/*delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='subscriber_surname' AND TABLE_NAME='#__comm_subscribers'
)
THEN
    ALTER TABLE `#__comm_subscribers`
    ADD COLUMN `subscriber_surname` varchar(64) NOT NULL default '';
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;*/

ใครมีวิธีทำดีๆบ้างคะ?


2
การแก้ไข information_schema.COLUMNS นั่นคือสิ่งที่ขั้นตอนการจัดเก็บทำคือวิธีไปที่ IMHO ส่วนใดของมัน "ดูเหมือนจะไม่ทำงาน"?
rodion

คำตอบ:


49

โปรดทราบว่าINFORMATION_SCHEMAไม่รองรับ MySQL ก่อนหน้า 5.0 และไม่รองรับขั้นตอนการจัดเก็บก่อนหน้า 5.0 ดังนั้นหากคุณต้องการรองรับ MySQL 4.1 โซลูชันนี้ไม่ดี

โซลูชันหนึ่งที่ใช้โดยเฟรมเวิร์กที่ใช้การโอนย้ายฐานข้อมูลคือการบันทึกหมายเลขการแก้ไขสำหรับสคีมาในฐานข้อมูลของคุณ เพียงตารางที่มีคอลัมน์เดียวและแถวเดียวโดยมีจำนวนเต็มระบุว่าการแก้ไขใดมีผลบังคับใช้ในปัจจุบัน เมื่อคุณอัปเดตสคีมาให้เพิ่มจำนวน

อีกวิธีหนึ่งก็คือลองใช้ALTER TABLE ADD COLUMNคำสั่ง ควรทำให้เกิดข้อผิดพลาดหากมีคอลัมน์นี้อยู่แล้ว

ERROR 1060 (42S21): Duplicate column name 'newcolumnname'

ตรวจจับข้อผิดพลาดและเพิกเฉยในสคริปต์อัปเกรดของคุณ


1
ตกลงนี่มันหยาบคายจริงๆ แต่มีคนพูด หากคุณเพียงแค่เรียกใช้สคริปต์ SQL จากบรรทัดคำสั่งคุณสามารถให้ mysql --forceสวิตช์ซึ่งหมายความว่าจะดำเนินต่อไปแม้ว่าจะมีข้อผิดพลาดก็ตาม จากนั้นไปได้เลย คุณเพียงแค่ต้องการให้แน่ใจว่าไม่มีข้อความใดที่คุณไม่ต้องการประสบความสำเร็จหากสิ่งที่ผ่านมาล้มเหลว
เดวิด

86

นี่คือโซลูชันที่ใช้งานได้ (เพิ่งทดลองใช้กับ MySQL 5.0 บน Solaris):

DELIMITER $$

DROP PROCEDURE IF EXISTS upgrade_database_1_0_to_2_0 $$
CREATE PROCEDURE upgrade_database_1_0_to_2_0()
BEGIN

-- rename a table safely
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
        AND TABLE_NAME='my_old_table_name') ) THEN
    RENAME TABLE 
        my_old_table_name TO my_new_table_name,
END IF;

-- add a column safely
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
        AND COLUMN_NAME='my_additional_column' AND TABLE_NAME='my_table_name') ) THEN
    ALTER TABLE my_table_name ADD my_additional_column varchar(2048) NOT NULL DEFAULT '';
END IF;

END $$

CALL upgrade_database_1_0_to_2_0() $$

DELIMITER ;

ในแวบแรกอาจดูซับซ้อนกว่าที่ควร แต่เราต้องจัดการกับปัญหาต่อไปนี้ที่นี่:

  • IF คำสั่งใช้งานได้เฉพาะในโพรซีเดอร์ที่เก็บไว้เท่านั้นไม่ใช่เมื่อรันโดยตรงเช่นในไคลเอนต์ mysql
  • สง่างามและรัดกุมมากขึ้นSHOW COLUMNSไม่ทำงานในขั้นตอนการจัดเก็บดังนั้นต้องใช้ INFORMATION_SCHEMA
  • ไวยากรณ์สำหรับการคั่นงบเป็นเรื่องแปลกใน MySQL ดังนั้นคุณต้องกำหนดตัวคั่นใหม่เพื่อให้สามารถสร้างโพรซีเดอร์ที่จัดเก็บได้ อย่าลืมสลับตัวคั่นกลับ!
  • INFORMATION_SCHEMA เป็นสากลสำหรับฐานข้อมูลทั้งหมดอย่าลืมกรองTABLE_SCHEMA=DATABASE()ข้อมูล DATABASE()ส่งคืนชื่อของฐานข้อมูลที่เลือกในปัจจุบัน

1
หวังว่าฉันจะได้รับคะแนนโบนัสสำหรับการอธิบายปัญหาที่เกี่ยวข้องซึ่งนำไปสู่แนวทางนี้ ขอบคุณ.
Bryan Petty

48

หากคุณใช้ MariaDB ไม่จำเป็นต้องใช้กระบวนงานที่เก็บไว้ เพียงใช้ตัวอย่างเช่น:

ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name tinyint(1) DEFAULT 0;

ดูที่นี่


8
ยอดเยี่ยม! อีกเหตุผลหนึ่งที่ต้องใช้ MariaDB
Andrew Ensley

+1 ฉันทำงานร่วมกับมาเรียมาตลอดและลองทำตามขั้นตอนเหล่านี้ทั้งหมดข้างต้นก็ไม่ได้ผลเลยจนกระทั่งฉันได้ทำสิ่งนี้สิ่งนี้ช่วยชีวิตฉันได้
Thielicious

น่าสนใจ .. ฉันไม่เคยลำบากเกี่ยวกับ MariaDB และบทความนี้สามารถให้ความคิดเกี่ยวกับเรื่องนี้ได้seravo.fi/2015/…
walv

วิธีนี้ดีมาก แต่ต้องใช้ MariaDB 10.0.2 เพียงแค่เตรียมพร้อมสำหรับทุกคนที่ต้องการใช้โซลูชันที่หรูหรานี้ แต่ติดอยู่กับเวอร์ชันที่เก่ากว่า
jblopez

แก้ไขตาราง table_name CHANGE COLUMN ถ้ามีอยู่ column_wrong_name column_name tinyint (1) ค่าเริ่มต้น 0; - งานดีด้วย!
Damonsson

35

ส่วนใหญ่ของคำตอบอยู่ที่วิธีการที่จะเพิ่มคอลัมน์อย่างปลอดภัยในขั้นตอนการเก็บผมก็มีความจำเป็นในการเพิ่มคอลัมน์ในตารางได้อย่างปลอดภัยโดยไม่ต้องใช้ proc จัดเก็บและค้นพบว่า MySQL ไม่อนุญาตให้ใช้ของIF Exists()นอกSP ฉันจะโพสต์วิธีแก้ปัญหาที่อาจช่วยใครบางคนในสถานการณ์เดียวกัน

SELECT count(*)
INTO @exist
FROM information_schema.columns 
WHERE table_schema = database()
and COLUMN_NAME = 'original_data'
AND table_name = 'mytable';

set @query = IF(@exist <= 0, 'alter table intent add column mycolumn4 varchar(2048) NULL after mycolumn3', 
'select \'Column Exists\' status');

prepare stmt from @query;

EXECUTE stmt;

1
หมายเหตุฉันต้องเพิ่ม "LIMIT 1" ในคำสั่ง SELECT เมื่อทำงานผ่าน MySQL workbench GUI
Al Dass

23

อีกวิธีในการทำเช่นนี้คือการละเว้นข้อผิดพลาดด้วยdeclare continue handler:

delimiter ;;
create procedure foo ()
begin
    declare continue handler for 1060 begin end;
    alter table atable add subscriber_surname varchar(64);
end;;
call foo();;

ฉันคิดว่าวิธีนี้existsทำได้ดีกว่าการสืบค้นย่อย โดยเฉพาะอย่างยิ่งถ้าคุณมีคอลัมน์จำนวนมากที่จะเพิ่มและคุณต้องการเรียกใช้สคริปต์หลาย ๆ ครั้ง

ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวจัดการต่อได้ที่http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html


รักเลย! ไม่เคยคิดแบบนั้น ฉันกำลังจะเปลี่ยนไปใช้วิธีนี้อย่างแน่นอน
Johnny Kauffman

ข้อผิดพลาด 1060 (42S21): ชื่อคอลัมน์ที่ซ้ำกัน 'newcolumnname'
Jake

นี่เป็นสิ่งที่ดีจริงๆ!
ATOzTOA

6

ฉันใช้ MySQL 5.5.19

ฉันชอบมีสคริปต์ที่คุณสามารถเรียกใช้และรันใหม่ได้โดยไม่มีข้อผิดพลาดโดยเฉพาะอย่างยิ่งเมื่อคำเตือนดูเหมือนจะค้างอยู่และปรากฏขึ้นอีกครั้งในภายหลังขณะที่ฉันกำลังเรียกใช้สคริปต์ที่ไม่มีข้อผิดพลาด / คำเตือน เท่าที่การเพิ่มช่องไปฉันเขียนขั้นตอนด้วยตัวเองเพื่อให้พิมพ์น้อยลง:

-- add fields to template table to support ignoring extra data 
-- at the top/bottom of every page
CALL addFieldIfNotExists ('template', 'firstPageHeaderEndY', 'INT NOT NULL DEFAULT 0');
CALL addFieldIfNotExists ('template', 'pageHeaderEndY', 'INT NOT NULL DEFAULT 0');
CALL addFieldIfNotExists ('template', 'pageFooterBeginY', 'INT NOT NULL DEFAULT 792');

รหัสเพื่อสร้างขั้นตอนaddFieldIfNotExistsมีดังนี้:

DELIMITER $$

DROP PROCEDURE IF EXISTS addFieldIfNotExists 
$$

DROP FUNCTION IF EXISTS isFieldExisting 
$$

CREATE FUNCTION isFieldExisting (table_name_IN VARCHAR(100), field_name_IN VARCHAR(100)) 
RETURNS INT
RETURN (
    SELECT COUNT(COLUMN_NAME) 
    FROM INFORMATION_SCHEMA.columns 
    WHERE TABLE_SCHEMA = DATABASE() 
    AND TABLE_NAME = table_name_IN 
    AND COLUMN_NAME = field_name_IN
)
$$

CREATE PROCEDURE addFieldIfNotExists (
    IN table_name_IN VARCHAR(100)
    , IN field_name_IN VARCHAR(100)
    , IN field_definition_IN VARCHAR(100)
)
BEGIN

    -- http://javajon.blogspot.com/2012/10/mysql-alter-table-add-column-if-not.html

    SET @isFieldThere = isFieldExisting(table_name_IN, field_name_IN);
    IF (@isFieldThere = 0) THEN

        SET @ddl = CONCAT('ALTER TABLE ', table_name_IN);
        SET @ddl = CONCAT(@ddl, ' ', 'ADD COLUMN') ;
        SET @ddl = CONCAT(@ddl, ' ', field_name_IN);
        SET @ddl = CONCAT(@ddl, ' ', field_definition_IN);

        PREPARE stmt FROM @ddl;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

    END IF;

END;
$$

ฉันไม่ได้เขียนขั้นตอนการแก้ไขคอลัมน์อย่างปลอดภัย แต่ฉันคิดว่าขั้นตอนข้างต้นสามารถแก้ไขได้อย่างง่ายดายเพื่อทำเช่นนั้น


5

ฉันได้ใช้ sproc ของ OP และทำให้สามารถใช้ซ้ำได้และสคีมาเป็นอิสระ เห็นได้ชัดว่ายังต้องใช้ MySQL 5

DROP PROCEDURE IF EXISTS AddCol;

DELIMITER //

CREATE PROCEDURE AddCol(
    IN param_schema VARCHAR(100),
    IN param_table_name VARCHAR(100),
    IN param_column VARCHAR(100),
    IN param_column_details VARCHAR(100)
) 
BEGIN
    IF NOT EXISTS(
    SELECT NULL FROM information_schema.COLUMNS
    WHERE COLUMN_NAME=param_column AND TABLE_NAME=param_table_name AND table_schema = param_schema
    )
    THEN
        set @paramTable = param_table_name ;
        set @ParamColumn = param_column ;
        set @ParamSchema = param_schema;
        set @ParamColumnDetails = param_column_details;
        /* Create the full statement to execute */
        set @StatementToExecute = concat('ALTER TABLE `',@ParamSchema,'`.`',@paramTable,'` ADD COLUMN `',@ParamColumn,'` ',@ParamColumnDetails);
        /* Prepare and execute the statement that was built */
        prepare DynamicStatement from @StatementToExecute ;
        execute DynamicStatement ;
        /* Cleanup the prepared statement */
        deallocate prepare DynamicStatement ;

    END IF;
END //

DELIMITER ;

สิ่งนี้ใช้ได้ดีสำหรับฉัน การเปลี่ยนแปลงเพียงอย่างเดียวที่ฉันต้องทำคือการลบเครื่องหมายคำพูดย้อนกลับ (`) ในการเรียกเพื่อเชื่อมต่อ นอกจากนี้ยังสามารถลดความซับซ้อนของโค้ดโดยการลบตัวแปร @paramTable, @ParamColumn, @ParamSchema และ @ParamColumnDetails และใช้พารามิเตอร์โดยตรง
hrabinowitz

1

เพิ่งลองใช้สคริปต์กระบวนงานที่เก็บไว้ ดูเหมือนว่าปัญหาคือ'รอยรอบตัวคั่น MySQL เอกสารแสดงให้เห็นว่าตัวละครตัวคั่นไม่จำเป็นต้องมีราคาเดียว

ดังนั้นคุณต้องการ:

delimiter //

แทน:

delimiter '//'

ใช้ได้ผลสำหรับฉัน :)


@ แอนดี้คุณพลาดจุดนี้ไปแล้ว ความคิดเห็นนี้ชี้ให้เห็นว่า OP ทำผิดพลาดตรงไหน OP นั้นมีอยู่แล้วหากไม่มีสำหรับเครื่องหมายคำพูดเดียว
RichardTheKiwi

1

หากคุณกำลังเรียกใช้สิ่งนี้ในสคริปต์คุณจะต้องเพิ่มบรรทัดต่อไปนี้ในภายหลังเพื่อให้รันได้ใหม่มิฉะนั้นคุณจะได้รับข้อผิดพลาดที่มีอยู่แล้ว

drop procedure foo;

1

วิธีที่ดีที่สุดในการเพิ่มคอลัมน์ใน PHP> PDO:

$Add = $dbh->prepare("ALTER TABLE `YourCurrentTable` ADD `YourNewColumnName` INT NOT NULL");
$Add->execute();

หมายเหตุ: คอลัมน์ในตารางไม่สามารถทำซ้ำได้นั่นหมายความว่าเราไม่จำเป็นต้องตรวจสอบการมีอยู่ของคอลัมน์ แต่สำหรับการแก้ปัญหาเราตรวจสอบรหัสด้านบน:

ตัวอย่างเช่นหากใช้งานการแจ้งเตือน 1 หากไม่ใช่ 0 ซึ่งหมายความว่ามีคอลัมน์อยู่! :)


1

ตรวจสอบว่ามีคอลัมน์หรือไม่อยู่ใน PDO (100%)

{
    if(isset($_POST['Add']))
    {
        $ColumnExist = $dbh->prepare("SELECT * FROM ColumnChecker where column_name='$insert_column_name' LIMIT 1");
        $ColumnExist ->execute();
        $ColumnName = $ColumnExist->fetch(2);
        $Display_Column_Name = $ColumnName['column_name'];

        if($Display_Column_Name == $insert_column_name)
        {
            echo "$Display_Column_Name already exist";
        } //*****************************
        else 
        {
            $InsertColumn = $dbh->prepare("insert into ColumnChecker ( column_name ) values ('$insert_column_name')");
            $InsertColumn->execute();

            if($InsertColumn)
            {
                $Add = $dbh->prepare("ALTER TABLE `$Table` ADD `$insert_column_name` $insert_column_type($insert_column_Length) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ");
                $Add->execute();

                if($Add)
                {
                    echo 'Table has been updated';  
                }
                else 
                {
                    echo 'Sorry! Try again...'; 
                }
            }   
        }
    }
}#Add Column into Table :)

1

ขั้นตอนจาก Jake https://stackoverflow.com/a/6476091/6751901นั้นง่ายมากและเป็นทางออกที่ดีสำหรับการเพิ่มคอลัมน์ใหม่ แต่มีบรรทัดเพิ่มเติมหนึ่งบรรทัด:

DROP PROCEDURE IF EXISTS foo;;

คุณสามารถเพิ่มคอลัมน์ใหม่ได้ในภายหลังและจะใช้งานได้ในครั้งต่อไป:

delimiter ;;
DROP PROCEDURE IF EXISTS foo;;
create procedure foo ()
begin
    declare continue handler for 1060 begin end;
    alter table atable add subscriber_surname varchar(64);
    alter table atable add subscriber_address varchar(254);
end;;
call foo();;

0
$smpt = $pdo->prepare("SHOW fields FROM __TABLE__NAME__");
$smpt->execute();
$res = $smpt->fetchAll(PDO::FETCH_ASSOC);
//print_r($res);

จากนั้นใน $ res ตามวัฏจักรให้มองหาคีย์ของคอลัมน์ของคุณ Smth ดังนี้:

    if($field['Field'] == '_my_col_'){
       return true;
    }
+

**Below code is good for checking column existing in the WordPress tables:**
public static function is_table_col_exists($table, $col)
    {
        global $wpdb;
        $fields = $wpdb->get_results("SHOW fields FROM {$table}", ARRAY_A);
        foreach ($fields as $field)
        {
            if ($field['Field'] == $col)
            {
                return TRUE;
            }
        }

        return FALSE;
    }

1
สิ่งนี้สามารถทำได้อย่างมีประสิทธิภาพมากขึ้น SHOW fields FROM __TABLE__NAME__ where field='_my_col_'; จากนั้นตรวจสอบผลลัพธ์ที่ตั้งไว้ว่าไม่ว่างเปล่า
Eugen Mayer

0

ด้านล่างนี้เป็นขั้นตอนการจัดเก็บใน MySQL เพื่อเพิ่มคอลัมน์ในตารางต่างๆในฐานข้อมูลที่แตกต่างกันหากคอลัมน์ไม่มีอยู่ในตารางฐานข้อมูลพร้อมข้อดีดังต่อไปนี้

  • สามารถเพิ่มคอลัมน์หลายคอลัมน์พร้อมกันเพื่อเปลี่ยนตารางหลายตารางในฐานข้อมูลที่แตกต่างกัน
  • คำสั่ง mysql สามคำสั่งทำงาน ได้แก่ DROP, CREATE, CALL For Procedure
  • ชื่อฐานข้อมูลควรมีการเปลี่ยนแปลงตาม USE มิฉะนั้นปัญหาอาจเกิดขึ้นสำหรับข้อมูลหลายรายการ

DROP PROCEDURE  IF EXISTS `AlterTables`;
DELIMITER $$
CREATE PROCEDURE `AlterTables`() 
BEGIN
    DECLARE table1_column1_count INT;
    DECLARE table2_column2_count INT;
    SET table1_column1_count = (  SELECT COUNT(*) 
                    FROM INFORMATION_SCHEMA.COLUMNS
                    WHERE   TABLE_SCHEMA = 'DATABASE_NAME' AND
			    TABLE_NAME = 'TABLE_NAME1' AND 
                            COLUMN_NAME = 'TABLE_NAME1_COLUMN1');
    SET table2_column2_count = (  SELECT COUNT(*) 
                    FROM INFORMATION_SCHEMA.COLUMNS
                    WHERE   TABLE_SCHEMA = 'DATABASE_NAME' AND
			    TABLE_NAME = 'TABLE_NAME2' AND 
                            COLUMN_NAME = 'TABLE_NAME2_COLUMN2');
    IF table1_column1_count = 0 THEN
        ALTER TABLE `TABLE_NAME1`ADD `TABLE_NAME1_COLUMN1` text COLLATE 'latin1_swedish_ci' NULL AFTER `TABLE_NAME1_COLUMN3`,COMMENT='COMMENT HERE';
    END IF;
    IF table2_column2_count = 0 THEN
        ALTER TABLE `TABLE_NAME2` ADD `TABLE_NAME2_COLUMN2` VARCHAR( 100 ) NULL DEFAULT NULL COMMENT 'COMMENT HERE';
    END IF;
END $$
DELIMITER ;
call AlterTables();


0

นี่คือโซลูชัน PHP / PDO ของฉันที่จะทำ:

function addColumnIfNotExists($db, $table, $col, $type, $null = true) {
    global $pdo;
    if($res = $pdo->query("SHOW COLUMNS FROM `$db`.`$table` WHERE `Field`='$col'")) {
        if(!$res = $res->fetchAll(PDO::FETCH_ASSOC)) {
            $null = ($null ? 'NULL' : 'NOT NULL');
            $pdo->query("ALTER TABLE `$db`.`$table` ADD `$col` $type $null");
        }
    }
}

โปรดทราบว่าจะเพิ่มคอลัมน์โดยอัตโนมัติในส่วนท้ายของตาราง ฉันยังไม่ได้ติดตั้งDEFAULTส่วนของแบบสอบถาม


-1
ALTER TABLE `subscriber_surname` ADD  IF NOT EXISTS  `#__comm_subscribers`.`subscriber_surname`;

ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';

4
จะเป็นการดีมากหากคุณสามารถเพิ่มคำอธิบายบางอย่างให้กับโซลูชันของคุณเรา (ผู้ใช้) สามารถเข้าใจข้อดีของโซลูชันนี้ได้ นี่เป็นการปรับปรุงสำหรับคำตอบนี้และในอนาคต
Luís Cruz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.