Register Register Member Login Member Login Member Login Forgot Password ??
PHP , ASP , ASP.NET, VB.NET, C#, Java , jQuery , Android , iOS , Windows Phone
 

Registered : 109,036

HOME > บทความจากสมาชิก > อธิบาย MySQL error message ในการเขียนโปรแกรม PHP ที่ตั้งกระทู้ถามกันบ่อยๆ



 
Clound SSD Virtual Server

อธิบาย MySQL error message ในการเขียนโปรแกรม PHP ที่ตั้งกระทู้ถามกันบ่อยๆ



ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page




อธิบาย MySQL error message ในการเขียนโปรแกรม PHP ที่ตั้งกระทู้ถามกันบ่อยๆ

error message (ข้อความแสดงความผิดพลาด) เหล่านี้เป็นข้อความแสดงความผิดพลาดที่ MySQL Server จะส่งกลับมาให้เราอ่านได้ด้วยฟังก์ชั่น mysql_error() บทความนี้จะอธิบายความผิดพลาดที่พบเห็นกันบ่อยๆ




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

เนื่องจากฟังก์ชั่น mysql_query() หรือ mysql_db_query() จะไม่แสดงความผิดพลาดที่เกิดจากการประมวลผล SQL ผ่าน PHP คือจะไม่มี Notice, Warning, Fatal error เกิดจากกระบวนการนี้

และจะกลายเป็นว่าในหลายๆ ครั้ง ผู้ที่พบเจอกับปัญหานี้ จะเจอกับ error message ของ PHP ในจุดอื่นแทน
และเข้าใจไปว่าน่าจะผิดตรงจุดนั้น


$result = mysql_query("SELECT * FROM order"); // จะเกิด error ณ จุดต่อจากนี้ while ($result = mysql_fetch_array($result)) { // Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given // เพราะ mysql_query() เกิด error จึงคืนค่ากลับมาให้ $result เป็น false // และเมื่อนำไปใช้กับ mysql_fetch_array() ก็จะเกิด error // ซึ่งหลายๆ คนคิดว่าผิดตรงนี้ แต่จริงๆ ไม่ใช่ ผิดก่อนหน้านั้นแล้ว }


วิธีเดียวที่เราจะสามารถรับรู้ได้ว่าการประมวลผล SQL ล่าสุดที่เราได้สั่งไปนั้นมีความผิดพลาด
เราต้องตรวจจากค่าที่คืนมาจาก mysql_query()
ซึ่ง mysql_query() จะคืนค่ากลับมาเป็น false เสมอเมื่อเกิดความผิดพลาด
และเมื่อมีความผิดพลาดเกิดขึ้น เราจะสามารถอ่าน error message ได้จากฟังก์ชั่น mysql_error()
ซึ่งเราจะเขียนโปรแกรมได้ในลักษณะนี้


มาทำแบบนี้ให้เป็นนิสัยกันครับ
$result = mysql_query("SELECT * FROM order"); if (!$result) { // ตรวจว่า $result ให้ผลเป็นเท็จหรือไม่ echo mysql_error(); // แสดง error message exit; // จบการทำงาน (ซึ่งไม่จำเป็นเสมอไป) }


หรือจะแบบนี้
$sql = "SELECT * FROM order"; $result = mysql_query($sql); if (!$result) { // ตรวจว่า $result ให้ผลเป็นเท็จหรือไม่ echo mysql_error() . "<br />\n$sql"; // แสดง error message และ SQL ปัจจุบัน exit; }


ต่อไปนี้จะเป็นการอธิบาย MySQL error message ที่ตั้งกันเป็นกระทู้บ่อยๆ ในเว็บบอร์ดของ thaicreate
โดยจะอธิบายทั้งสาเหตุ และวิธีการแก้ปัญหาครับ





You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '???' at line ???

นี่คือ error ที่เจอบ่อยที่สุดสำหรับกรณีที่มีการเรียกใช้ mysql_query()
มีความหมายคร่าวๆ ว่า "SQL ที่คุณเขียนมานั้น มันผิดหลักไวยากรณ์"
ซึ่งผิดได้หลายแบบมากๆ

ที่พบเห็นบ่อยๆ ในกระทู้ต่างๆ ก็มีดังต่อไปนี้





ผิดไปเลย คำสั่งบ้าอะไรก็ไม่รู้
mysql_query("WHEN I WAS YOUNG I LISTEN TO THE RADIO");


กรณีแบบนี้ไม่ค่อยเกิดหรอกครับ
แต่อาจจะเกิดในกรณีแบบนี้ เวลาใช้การเชื่อมต่อสตริง แล้วลืมเครื่องหมาย .


$strSQL = "SELECT * FROM `table` "; $strSQL .= "WHERE `id` = '" . $_POST['id'] . "'"; $strSQL = " AND `name` = '" . $_POST['name'] . "'"; $strSQL .= " AND `iq` > '" . $_POST['iq'] . "'"; $strSQL .= " ORDER BY `id` DESC";


ซึ่งจะทำให้ตัวแปร $strSQL เริ่มต้นการกำหนดค่าใหม่ ณ บรรทัดนั้น กลายเป็น SQL ที่ไม่มีความหมายไปเสีย




ลืมปิดสตริงด้วยเครื่องหมาย '
mysql_query("SELECT * FROM `table` WHERE `id` = '1 AND `name` = 'cookie'");


ที่ถูกต้องคือ
mysql_query("SELECT * FROM `table` WHERE `id` = '1' AND `name` = 'cookie'");





ใช้ค่าวันที่ที่ไม่ได้ครอบด้วยเครื่องหมาย '
mysql_query("SELECT * FROM `table` WHERE `created` = 2013-03-01");


ที่ถูกต้องคือ
mysql_query("SELECT * FROM `table` WHERE `created` = '2013-03-01'");





พิมพ์ตกเครื่องหมาย ,
mysql_query("SELECT id, username password FROM `table`");


ที่ถูกต้องคือ
mysql_query("SELECT id, username, password FROM `table`");


ซึ่งส่วนใหญ่สาเหตุจะเป็นเพราะนิยมใช้การเชื่อมต่อสตริง (อีกแล้ว) ทำให้อ่านยาก และผิดพลาดง่าย
และการพิมพ์ตกเครื่องหมาย ' ก็เช่นกัน

$strSQL = "UPDATE `members` SET "; $strSQL .= "`username` = '" . $POST['username'] . "',"; $strSQL .= "`password` = '" . $POST['password'] . "'"; $strSQL .= "`email` = '" . $POST['email'] . "',"; $strSQL .= "`first_name` = '" . $POST['first_name'] . ","; $strSQL .= "`last_name` = '" . $POST['last_name'] . "'"; $strSQL .= "WHERE id = '" . $_POST['id'] . "'"; mysql_query($strSQL) or die(mysql_error());


ซึ่งแนะนำให้ใช้ ตัวแปรในสตริง จะทำให้อ่านง่าย แก้ไขง่าย โอกาสเกิดความผิดพลาดน้อยกว่า

// เราสามารถขึ้นบรรทัดใหม่ในสตริงได้เลย สามารถจัดรูปแบบให้อ่านง่ายตามที่เราต้องการ // ไม่จำเป็นต้องใช้การเชื่อมต่อสตริงให้ดูยุ่งเหยิง $strSQL = " UPDATE members SET username = '$POST[username]', password = '$POST[password]', email = '$POST[email]', first_name = '$POST[first_name]', last_name = '$POST[last_name]' WHERE id = '$_POST[id]' "; mysql_query($strSQL) or die(mysql_error());





ผิดเพราะใช้ "คำสงวน" เป็นชื่อคอลัมน์หรือชื่อตาราง โดยไม่ได้เปิดและปิดด้วยเครื่องหมาย `
mysql_query("SELECT * FROM order"); mysql_query("SELECT force FROM jedi"); mysql_query("UPDATE characters SET limit = 'Final Heaven' WHERE name = 'Tifa'");


แต่แบบนี้ OK
mysql_query("SELECT * FROM `order`"); mysql_query("SELECT `force` FROM jedi"); mysql_query("UPDATE characters SET `limit` = 'Final Heaven' WHERE name = 'Tifa'");


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

รู้หรือไม่?
คุณสามารถพิมพ์ ` ได้ด้วยการกด Alt ค้างไว้ และตามด้วยแป้นตัวเลข 9 และ 6
จากนั้นก็ปล่อย Alt แค่นี้คุณก็จะได้ตัวอักษร ` ไว้เชยชมแล้วครับ ไม่เห็นจะพิมพ์ยากตรงไหนเลย

คำสงวนใน MySQL ได้แก่

ADD ALL ALTER ANALYZE AND AS ASC ASENSITIVE BEFORE BETWEEN BIGINT BINARY BLOB BOTH BY CALL CASCADE CASE CHANGE CHAR CHARACTER CHECK COLLATE COLUMN CONDITION CONNECTION CONSTRAINT CONTINUE CONVERT CREATE CROSS CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR DATABASE DATABASES DAY_HOUR DAY_MICROSECOND DAY_MINUTE DAY_SECOND DEC DECIMAL DECLARE DEFAULT DELAYED DELETE DESC DESCRIBE DETERMINISTIC DISTINCT DISTINCTROW DIV DOUBLE DROP DUAL EACH ELSE ELSEIF ENCLOSED ESCAPED EXISTS EXIT EXPLAIN FALSE FETCH FLOAT FLOAT4 FLOAT8 FOR FORCE FOREIGN FROM FULLTEXT GOTO GRANT GROUP HAVING HIGH_PRIORITY HOUR_MICROSECOND HOUR_MINUTE HOUR_SECOND IF IGNORE IN INDEX INFILE INNER INOUT INSENSITIVE INSERT INT INT1 INT2 INT3 INT4 INT8 INTEGER INTERVAL INTO IS ITERATE JOIN KEY KEYS KILL LABEL LEADING LEAVE LEFT LIKE LIMIT LINES LOAD LOCALTIME LOCALTIMESTAMP LOCK LONG LONGBLOB LONGTEXT LOOP LOW_PRIORITY MATCH MEDIUMBLOB MEDIUMINT MEDIUMTEXT MIDDLEINT MINUTE_MICROSECOND MINUTE_SECOND MOD MODIFIES NATURAL NOT NO_WRITE_TO_BINLOG NULL NUMERIC ON OPTIMIZE OPTION OPTIONALLY OR ORDER OUT OUTER OUTFILE PRECISION PRIMARY PROCEDURE PURGE READ READS REAL REFERENCES REGEXP RELEASE RENAME REPEAT REPLACE REQUIRE RESTRICT RETURN REVOKE RIGHT RLIKE SCHEMA SCHEMAS SECOND_MICROSECOND SELECT SENSITIVE SEPARATOR SET SHOW SMALLINT SONAME SPATIAL SPECIFIC SQL SQLEXCEPTION SQLSTATE SQLWARNING SQL_BIG_RESULT SQL_CALC_FOUND_ROWS SQL_SMALL_RESULT SSL STARTING STRAIGHT_JOIN TABLE TERMINATED THEN TINYBLOB TINYINT TINYTEXT TO TRAILING TRIGGER TRUE UNDO UNION UNIQUE UNLOCK UNSIGNED UPDATE UPGRADE USAGE USE USING UTC_DATE UTC_TIME UTC_TIMESTAMP VALUES VARBINARY VARCHAR VARCHARACTER VARYING WHEN WHERE WHILE WITH WRITE XOR YEAR_MONTH ZEROFILL





ใช้ expression ในที่ที่ใช้ไม่ได้
mysql_query("SELECT * FROM `table` LIMIT $limit * 2");





ใช้เครื่องหมายวงเล็บใน WHERE แต่ปิดผิดที่
mysql_query("SELECT * FROM `table` WHERE (`id` = 1 AND `name` = 'cookie' ORDER BY `name` DESC)");


ที่ถูกต้องคือ
mysql_query("SELECT * FROM `table` WHERE (`id` = 1 AND `name` = 'cookie') ORDER BY `name` DESC");





No database selected

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


// query แบบระบุชื่อฐานข้อมูลไปเลย ซึ่งวิธีนี้เป็นวิธีที่ไม่ค่อยจะปกติ ไม่ค่อยมีคนใช้กัน mysql_query("SELECT * FROM `db`.`table`"); // query แบบไม่ระบุชื่อฐานข้อมูล ซึ่งถ้าหากว่าไม่ได้เลือกไว้ด้วย mysql_select_db() ก็จะเกิด error นี้ mysql_query("SELECT * FROM `db`.`table`");


หากเกิด error นี้ วิธีแก้ก็คือตรวจสอบดูว่ามีการเรียกใช้ mysql_select_db() อยู่ก่อนหน้านี้แล้วหรือยัง[/tt]

ขั้นตอนปกติของการเชื่อมต่อกับฐานข้อมูล MySQL
// ติดต่อฐานข้อมูล if (!mysql_connect('localhost', 'root', 'password')) { echo mysql_error(); exit; } // เลือกฐานข้อมูลหลักที่จะใช้ในทุกๆ คำสั่งที่เกี่ยวข้องกับตาราง mysql_select_db('default_database_name');





Query was empty

หมายถึง "คำสั่ง SQL" ที่ส่งไปให้ mysql_query() มันว่างเปล่า


// แบบนี้ครับ mysql_query(''); // หรือมีแต่ช่องว่าง หรือ whitespace mysql_query(' '); mysql_query(' '); // หรือค่าใดๆ แปลงเป็นสตริงแล้วได้สตริงว่าง '' mysql_query(null); mysql_query(false);


ดังนั้นถ้าหากเป็นการเรียกใช้ mysql_query() โดยที่ query เป็นตัวแปรแล้วเกิด error นี้
ก็ให้ตรวจสอบค่าของตัวแปรนั้นๆ ครับ





Duplicate entry '?' for key ?

อันนี้ก็เป็นอีก error หนึ่งที่เกิดขึ้นบ่อย
สาเหตุเกิดจากการพยายามให้ค่ากับคอลัมน์ที่เป็นชนิด PRIMARY หรือ UNIQUE
โดยที่ในตารางนั้นๆ มีแถวที่มีค่าดังกล่าวอยู่แล้ว

เช่น มีข้อมูลดังภาพ

ตารางตัวอย่าง

แล้วพยายามที่จะ INSERT แถวใหม่เข้าไปโดยการเพิ่มแถวที่มี id เหมือนกับแถวที่มีอยู่ในตารางแล้ว


mysql_query(" INSERT INTO `players` (`id`, `created`, `job`, `level`, `exp`, `hp`, `mp`) VALUES (1, NOW(), 'Mage', 1, 0, 10, 5) ");


ก็จะเกิด error ดังกล่าว




Incorrect integer value: '?' for column '?' at row ?

หมายถึงการที่เขียนข้อมูลลงในตาราง และให้ค่าที่ไม่ใช่ชนิดตัวเลข หรือแปลงเป็นตัวเลขไม่ได้
ให้แก่คอลัมน์ที่เป็นชนิดตัวเลข (INT, MEDIUMINT etc.)


mysql_query("UPDATE `players` SET `hp` = 'Hello World' WHERE `id` = 1");


แต่ตาราง players มีโครงสร้างเป็นแบบนี้

โครงสร้างตาราง players

ดังนั้นการให้ค่า 'Hello World' ให้กับคอลัมน์ hp จึงทำให้เกิด error ดังกล่าวครับ





บทความที่เกี่ยวข้อง





ศึกษาเพิ่มเติม




ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page







   
Share
Bookmark.   

  By : phpinfo()
  Article : บทความเป็นการเขียนโดยสมาชิก หากมีปัญหาเรื่องลิขสิทธิ์ กรุณาแจ้งให้ทาง webmaster ทราบด้วยครับ
  Score Rating :
  Create Date : 2013-03-06
  Download : No files
Sponsored Links
ThaiCreate.Com Forum


Comunity Forum Free Web Script
Jobs Freelance Free Uploads
Free Web Hosting Free Tools

สอน PHP ผ่าน Youtube ฟรี
สอน Android การเขียนโปรแกรม Android
สอน Windows Phone การเขียนโปรแกรม Windows Phone 7 และ 8
สอน iOS การเขียนโปรแกรม iPhone, iPad
สอน Java การเขียนโปรแกรม ภาษา Java
สอน Java GUI การเขียนโปรแกรม ภาษา Java GUI
สอน JSP การเขียนโปรแกรม ภาษา Java
สอน jQuery การเขียนโปรแกรม ภาษา jQuery
สอน .Net การเขียนโปรแกรม ภาษา .Net
Free Tutorial
สอน Google Maps Api
สอน Windows Service
สอน Entity Framework
สอน Android
สอน Java เขียน Java
Java GUI Swing
สอน JSP (Web App)
iOS (iPhone,iPad)
Windows Phone
Windows Azure
Windows Store
Laravel Framework
Yii PHP Framework
สอน jQuery
สอน jQuery กับ Ajax
สอน PHP OOP (Vdo)
Ajax Tutorials
SQL Tutorials
สอน SQL (Part 2)
JavaScript Tutorial
Javascript Tips
VBScript Tutorial
VBScript Validation
Microsoft Access
MySQL Tutorials
-- Stored Procedure
MariaDB Database
SQL Server Tutorial
SQL Server 2005
SQL Server 2008
SQL Server 2012
-- Stored Procedure
Oracle Database
-- Stored Procedure
SVN (Subversion)
แนวทางการทำ SEO
ปรับแต่งเว็บให้โหลดเร็ว


Hit Link
   







Load balance : Server 01
ThaiCreate.Com Logo
© www.ThaiCreate.Com. 2003-2024 All Rights Reserved.
ไทยครีเอทบริการ จัดทำดูแลแก้ไข Web Application ทุกรูปแบบ (PHP, .Net Application, VB.Net, C#)
[Conditions Privacy Statement] ติดต่อโฆษณา 081-987-6107 อัตราราคา คลิกที่นี่