Chương 3: Đọc dữ liệu 

Chương 3 : Đọc dữ liệu

Chương này khá dài nhưng rất thú vị! Hơn nữa tầm quan trọng của CSDL là nằm ở chương này và chương sau, cho nên nhất thiết các bạn phải đọc kĩ!
precedent chapter Mục Lục next chapter

Kết nối vào cơ sở dữ liệu

Để có thể làm việc trên CSDL, việc đầu tiên là phải kết nối (connect) vào CSDL.
Các bạn còn nhớ không, tôi đã có nhắc rằng để ra lệnh cho MySQL mình không thể nói trực tiếp với nó mà phải nhờ PHP làm "thông dịch viên" trung gian. Vấn đề là trước hết PHP không thể bảo ngay "MySQL ơi, làm ơn cho tớ lấy link phim Tây Du Kí nhé !" được. Vì đầu tiên MySQL đòi user name và password, phải có user name và password mới vào được CSDL của mình chứ, nếu không thì ai cũng có thể vào được rồi xóa hết hoặc thay đổi hết thì sao.
Để theo dõi chi tiết việc kết nối và thao tác trên CSDL, mình sẽ học lần lượt các cách để :
  • Kết nối vào CSDL (lấy chìa khóa mở cửa vào nhà)
  • Chọn CSDL cần làm việc (vào nhà và chọn nơi làm việc)
  • Ngắt kết nối với CSDL sau khi đã làm việc xong (khóa cửa lại, ra khỏi nhà)

Kết nối (connection)

Để connect vào CSDL chúng ta dùng một hàm PHP: mysql_connect
Hàm này cần có 3 thông số:
  • Tên (địa chỉ) của máy chủ chứa CSDL (server), nếu bạn test trên máy tính của bạn thì địa chỉ này là "localhost"
  • User name: liên hệ admin để biết username đăng nhập vào CSDL, nếu bạn có một cái host miễn phí, thì thông thường username này trùng với username bạn đăng nhập vào FTP, nếu bạn test trên máy của bạn thì user name là "root"
  • Password: 99% là giống với password bạn dùng để kết nối FTP. Test trên máy thì để "" (không có password)
Ví dụ test trên máy với WAMP: mysql_connect("localhost","root","");

Chọn CSDL làm việc

Sau khi đã đăng nhập vào CSDL rồi, bạn cần phải lựa chọn tên CSDL mà bạn cần làm việc (nếu bạn có nhiều CSDL). Đối với các host miễn phí (như FREE.FR chẳng hạn) thì nó chỉ cho mình một CSDL thôi, vậy cũng quá đủ rồi! Và tên của CSDL này thường là trùng với username đăng nhập vào MySQL của bạn (do server tạo tự động).
Hàm PHP để lựa chọn CSDL: mysql_select_db (chữ db là viết tắt của DataBase)
Ví dụ nếu tên của CSDL của tôi là khoailang, thì tôi làm như sau:
Code PHP:
<?php
mysql_connect("localhost","root",""); // đăng nhập vào CSDL trên máy tính
mysql_select_db("khoailang"); //Chọn CSDL tên là khoailang
?>

Ngắt kết nối

Sau khi đã làm việc với CSDL xong, việc cuối cùng của bạn là phải ngắt kết nối! Giống như căn nhà của bạn vậy, bạn muốn vào thì phải có chìa khóa (ở đây là username và password), rồi vào làm việc riêng, sau khi xong việc bạn muốn ra khỏi nhà hay đi đâu đó thì phải khóa cửa lại!
Hàm để ngắt kết nối (đóng CSDL lại) : mysql_close(); không cần thông số bên trong
Cấu trúc tóm tắt như sau:
Code PHP:
<?php
mysql_connect("localhost","root","");
mysql_select_db("khoailang");
// Làm việc riêng trên CSDL
//…
mysql_close(); // xong việc rồi thì khóa CSDL lại
?>
Nếu bạn khai báo đúng địa chỉ server, username, password, tên CSDL thì mọi việc suông sẻ, không vấn đề gì, còn một trong những thông số trên mà sai thì bạn sẽ bị báo lỗi!

Lấy dữ liệu

Thường thường sau khi đã có một trang web (và có CSDL) thì mình phải nhập CSDL vào, sau đó đọc CSDL và truy xuất dữ liệu mà mình cần dùng.
Bây giờ tôi sẽ hướng dẫn các bạn làm sao để đọc dữ liệu, còn việc ghi dữ liệu tôi sẽ nói sau.
Nhưng để đọc CSDL thì đầu tiên mình cần phải có sẵn một CSDL đầy đủ để mà đọc chứ nhỉ, không có gì cả thì lấy gì mà đọc?!
May cho các bạn là hôm nay tôi hơi bị siêng năng, nên đã chuẩn bị sẵn cho các bạn một bảng dữ liệu về video games (jeux_videos trong tiếng Pháp). Các bạn hãy tải bảng này về trước đã:
Download bảng jeux_videos (2,5 Kb)
File có phần mở rộng là .sql
Bạn định mở file ra để đọc hả ? Nói nhỏ nghe nè : chả có gì thú vị để đọc trong đó đâu, chỉ là một đám rừng toàn là text.
Việc cần làm bây giờ là nạp cái bảng này vào PHPMyAdmin. Hãy theo trình tự sau đây nhé :
  • Mở PhpMyAdmin ra,
  • Chọn CSDL test trong menu đổ xuống bên trái
  • Chọn tab Importer (import) trên hàng menu lớn bên trái
  • Nhìn xuống dưới, nhấp nút parcourrir (Browse)
  • Một hộp thoại hiện ra, bạn hãy đi tìm nơi đặt file jeux_videos.sql mà bạn đã tải hồi nãy, nhấp chọn nó
  • Cuối cùng, nhấp exécuter (execute)
Xong rồi , bạn sẽ thấy bên trái, dưới Test có một bảng mới xuất hiện tên là jeux_videos đấy!
Nếu bạn nhấp vào hình cái bảng bên cạnh chữ jeux_videos thì bảng dữ liệu sẽ hiện ra bên phải, sau đây là 5 dòng đầu tiên trong bảng dữ liệu:
ID nom possesseur console prix nbre_joueurs_max commentaires
1 Super Mario Bros Florent NES 4 1 Un jeu d'anthologie !
2 Sonic Patrick Megadrive 2 1 Pour moi, le meilleur jeu au monde !
3 Zelda : ocarina of time Florent Nintendo 64 15 1 Un jeu grand, beau et complet comme on en voit rarement de nos jours
4 Mario Kart 64 Florent Nintendo 64 25 4 Un excellent jeu de kart !
5 Super Smash Bros Melee Michel GameCube 55 4 Un jeu de baston délirant !

Tạm thời, hãy khoan sửa đổi gì cái bảng này nhé !
Chúng ta làm gì tiếp theo vậy chú ?
Mục đích của chúng ta bây giờ là : viết một trang php cho phép in ra tất cả dữ liệu chứa trong bảng trên !

Viết một query

Đã đến hồi quan trọng của buổi học hôm nay rồi, bây giờ mình sẽ yêu cầu MySQL làm vài thứ bằng ngôn ngữ SQL. Viết một yêu cầu gọi là thực hiện một query . Mình sẽ nhờ MySQL in ra nội dung của cái bảng trò chơi điện tử (jeux_videos) mà hồi nãy mình có đề nghị bạn tải về đấy !
Để viết một query chúng ta sử dụng hàm PHP : mysql_query
  • Hàm này chứa một thông số, đó là những gì mà PHP sắp yêu cầu MySQL làm (bằng ngôn ngữ SQL)
  • Hàm này trả về một giá trị, vì vậy mình cần phải có một biến để chứa những gì mà MySQL trả lời.
Mình luôn viết như thế này :

Code PHP:
<?php
$traloi=mysql_query ("gõ query vào đây") ;
?>

$traloi chứa những gì mà MySQL trả lời theo đơn yêu cầu của mình.
Bây giờ chúng ta hãy xem làm sao để hỏi MySQL những gì có trong bảng jeux_videos nhé.

Query SQL đầu tiên của bạn

Như đã nói, SQL là một ngôn ngữ cho phép mình giao tiếp với MySQL, đây là query SQL đầu tiên :

Code SQL :
SELECT * FROM jeux_videos
Dòng này có thể hiểu là : chọn tất cả các dữ liệu trong bảng jeux_videos.
Mình cùng phân tích vài từ khóa trong này nhé :
  • SELECT : trong ngôn ngữ SQL, việc đầu tiên là mình phải xác định kiểu (loại) thao tác mà mình sẽ làm với MySQL. Ở chương này chúng ta chỉ xem mỗi một thao tác CHỌN thôi (SELECT). SELECT cho phép hiển thị tất cả nội dung trong một bảng.
  • * : ngay sau SELECT, chúng ta phải xác định rằng chúng ta muốn lấy dữ liệu trong cột (trường, fields) nào. Dấu * ám chỉ "lấy hết cho tao ! Không chừa lại thứ gì cả! ». Giả sử bạn muốn chọn cột "nom" (tên) và "possesseur" (người sở hữu) thì bạn gõ : SELECT nom, possesseur FROM jeux_videos
  • FROM là một từ nối (từ liên kết), ý nói "ở trong" cái bảng nào ! Sau FROM mình sẽ chỉ ra tên của cái bảng mà mình muốn lấy dữ liệu.
  • Jeux_videos chính là tên của cái bảng mà mình muốn lấy dữ liệu !
Mổ xẻ xong rồi, bây giờ mình hãy đặt lá đơn này vào hàm mysql_query đi !

Code PHP :
<?php
$traloi=mysql_query("SELECT * FROM jeux_videos") ;
?>
Thế là biến $traloi của mình bây giờ đã chứa câu trả lời của MySQL rồi đấy!
Cool, bây giờ làm sao in kết quả ra đây?

In (hiển thị) kết quả của một query

Vấn đề là cái biến $traloi của mình chứa một thứ gì đó không thể bung ra được, nghĩa là không giống như một biến bình thường chứa số hay chứa text mà mình có thể dùng lệnh echo để in ra, mà nó chứa một thứ rất hỗn độn vô trật tự.
Bạn tưởng tượng nếu cái bảng của mình có 10 cột, 200 dòng, thì cái biến $traloi chứa 2000 thông tin! Bây giờ làm sao lấy ra 2000 thông tin đó đây? Loại biến nào lại có kiểu bảng giống như vậy nhỉ? Từ "cái bảng" giúp tôi nhớ đến Array!
PHP có sẵn một hàm giúp tạo ra một array từ $traloi: mysql_fetch_array($traloi)
Đây là một mảng kiểu bảng kết hợp (kiểu thứ nhất là bảng đánh số như mình đã học ở chương Array rồi đấy), nếu bạn muốn lấy dữ liệu ở cột "console" chẳng hạn, thì bạn phải sử dụng một mảng khác: $dulieu['console'] ($dulieu là một biến array luôn đấy)
Tiếp theo, mình cần dùng một vòng lặp để in hết các hàng ra! Mỗi lần các bạn dùng hàm mysql_fetch_array, bạn sẽ truy nhập vào hàng kế tiếp của bảng. Vòng lặp sẽ tự động lặp lại cho đến khi nào không còn hàng nào nữa trong bảng của mình thì thôi. Đây là điểm thuận lợi khi mình không biết bảng của mình có bao nhiêu hàng!
Đây là những gì tôi đã làm để in ra nội dung của cái bảng:

Code PHP:
<?php
mysql_connect("localhost","root",""); //đăng nhập vào CSDL
mysql_select_db("khoailang"); // chọn CSDL
// viết đơn chọn tất cả các cột của bảng jeux_videos
$traloi=mysql_query("SELECT * FROM jeux_videos");
while($dulieu=mysql_fetch_array($traloi))
{
?>
<p>
<strong>Trò chơi</strong> <?php echo $dulieu['nom'];?>
<br>
<strong>Tên người sỡ hữu</strong> <?php echo $dulieu['possesseur'];?>
và nó bán trò này với giá : <?php echo $dulieu['prix'];?> dollars
<br>
<strong>Trò chơi này hoạt động trên nền</strong>: <?php echo $dulieu['console'];?> và mình có thể chơi cùng lúc <?php echo $dulieu['nbre_joueurs_max']; ?> người maximum.
<br>
Thằng <?php echo $dulieu['possesseur'];?> đã đánh giá trò <?php echo $dulieu['nom'];?> là : <em> <?php echo $dulieu['commentaires'];?> </em>
</p>
<?php
}
mysql_close();
?>

Nhấp vào đây để chạy thử
Bạn nhìn thấy gì? Nó in ra khoảng 50 kết quả, không gì lạ bởi vì cái bảng của mình chứa khoảng 50 hàng mà.
Sự khác nhau giữa $traloi và $dulieu là gì?
$traloi là một biến chứa câu trả lời của MySQL, là một mớ hỗn độn vô trật tự có kiểu dữ liệu là resource (hiếm gặp từ này). Nhờ vào hàm mysql_fetch_array mà mình tạo được mảng $dulieu ! Mảng này chứa 1 dòng trong bảng dữ liệu của mình, khi mình dùng hàm mysql_fetch_array một lần nữa thì mảng $dulieu sẽ chứa hàng thứ 2 trong bảng dữ liệu. Tưởng tượng thế này nhé :
Lần đầu tiên gọi : $dulieu= mysql_fetch_array($traloi) ;
Thì $dulieu có dạng một mảng như thế này : {'nom' :'Super mario Bros', 'possesseur' :'Florent','prix' :4, 'console' :'NES', 'nbre_joueurs_max' :1,'commentaires' :'un jeu d'anthologie'}
Sau khi in hết dòng này, vòng lặp while cho phép gọi tiếp hàm mysql_fetch_array một lần nữa, và lần này mảng $dulieu tự động chứa hàng thứ 2 của bảng jeux_videos và có cấu trúc như trên !
'fetch' trong tiếng Anh nghĩa là "đi tìm"
Vậy đó! Bây giờ bạn có thể cho in ra bất cứ thứ gì bạn muốn, không ai ép bạn phải in ra cả cái bảng đâu, ví dụ bạn có thể chỉ in ra tên của trò chơi bằng cách chọn cột 'nom':

Code PHP:
<?php
mysql_connect("localhost","root","");
mysql_select_db("khoailang") ;
$traloi=mysql_query("SECLECT nom FROM jeux_videos");
$dem = 1;
while($dulieu=mysql_fetch_array($traloi))
{
?>
Trò chơi thứ <?php echo $dem;?><?php echo $dulieu['nom'] ; $dem++ ; ?>
<br>
<?php
}
mysql_close() ;
?>
Nhấp vào đây để chạy thử

Lỗi lầm vây kín …

Khi một query SQL của bạn bị treo, thường thì PHP sẽ báo là có lỗi ở dòng chứa hàm mysql_fetch_array. Điều này thực ra không chính xác đâu, có thể bạn đã bị lỗi đâu đó phía trên kia, chứ không phải chính xác tại dòng mysql_fetch_array đâu. Để biết rõ chi tiết lỗi gì, ở đâu, bạn nên tập thói quen chèn thêm dòng này vào cùng dòng với mysql_query nhé : or die(mysql_error());
Ví dụ với trường hợp mình đang làm :
$traloi = mysql_query("SELECT * FROM jeux_videos") or die(mysql_error()) ;
Dòng code vừa thêm vào sẽ không làm gì cả nếu bạn không có lỗi, trái lại nếu có lỗi đâu đó, nó sẽ báo cho mình biết chi tiết hơn!

Tiêu chuẩn lựa chọn

Ở đây chúng ta chỉ quan tâm tới các query query SQL thôi. Bạn sẽ thấy, bằng cách thay đổi điều kiện và tiêu chuẩn chọn lựa, mình có thể sắp xếp dữ liệu một cách gọn gàng ngăn nắp dễ dàng!
Các từ khóa sẽ đề cập: WHERE, ORDER BY, LIMIT

WHERE

Where giúp mình lọc bớt dữ liệu theo tiêu chuẩn mà mình đặt ra. Chẳng hạn bây giờ mình chỉ muốn lấy ra các trò chơi của Patrick (trong bảng jeux_videos), query của mình sẽ thêm WHERE possesseur='Patrick' vào sau từ khóa FROM:

Code SQL:
SELECT * FROM jeux_videos WHERE possesseur='Patrick'
Dòng này được hiểu là : chọn tất cả các cột trong bảng jeux_videos sao cho cột possesseur chứa Patrick.

Code PHP:
<?php
mysql_connect("localhost","root","");
mysql_select_db("khoailang");
$traloi=mysql_query("SELECT * FROM jeux_videos WHERE possesseur='Patrick'") or die(mysql_error());
while($dulieu=mysql_fetch_array($traloi))
{
?>
Trò chơi <?php echo $dulieu['nom'];?> là của <?php echo $dulieu['possesseur'];?>
<br>
<?php
}
mysql_close() ;
?>
Nếu thích bạn có thể thay đổi một chút, chẳng hạn bạn muốn xem tất cả trò chơi của Michel, bạn hãy thay WHERE possesseur='Patrick' bằng WHERE possesseur='Michel' thử xem !
Mình cũng có thể đặt điều kiện vào trong query nữa, chẳng hạn mình muốn xem những trò nào của Patrick mà nó bán với giá thấp hơn 20 dollars :

Code SQL :
SELECT * FROM jeux_videos WHERE possesseur='Patrick' AND prix<20

ORDER BY

ORDER BY cho phép chúng ta sắp xếp lại kết quả thu được cho có trật tự! Chẳng hạn mình sẽ sắp xếp lại bảng trò chơi điện tử jeux_videos theo thứ tự tăng dần của giá cả (prix):

Code SQL:
SELECT * FROM jeux_videos ORDER BY prix
Ứng dụng :

Code PHP:
<?php
mysql_connect("localhost","root","");
mysql_select_db("khoailang");
$traloi=mysql_query("SELECT * FROM jeux_videos ORDER BY prix") or die(mysql_error());
while($dulieu=mysql_fetch_array($traloi))
{
echo "Trò $dulieu['nom'] giá $dulieu['prix'] dollars";
echo "<br>" ;
}
mysql_close() ;
?>
Nếu tớ muốn sắp xếp theo thứ tự giảm dần thì sao ?
Thì thêm DESC vào cuối dòng lệnh SQL trên :

Code SQL :
SELECT * FROM jeux_videos ORDER BY prix DESC
Nếu chúng ta thực hiện việc sắp xếp thứ tự cho một cột chứa text, thì text đó sẽ được sắp xếp theo mẫu tự ABC

LIMIT

LIMIT cho phép chúng ta giới hạn được kết quả xuất ra, chẳng hạn chúng ta chỉ cần lấy 20 dòng đầu tiên ra thôi thì chúng ta sẽ thêm từ LIMIT vào cuối query, kèm theo 2 con số, ngăn cách bằng dấu phẩy:

Code SQL:
SELECT * FROM jeux_videos LIMIT 0,20
Những con số này có ý nghĩa gì?
Đầu tiên, số 0 chỉ ra rằng MySQL sẽ đọc dữ liệu kể từ hàng số 0 (tức hàng thứ 1), cách đánh số của nó giống như cách đánh số trong mảng vậy!
Số thứ 2 cho biết SỐ LƯỢNG hàng cần phải đọc! Ở đây nó sẽ đọc từ hàng số 0 đến hàng số 19 để được 20 hàng!
Ví dụ, nếu mình đặt:
LIMIT 0,10: in ra 10 hàng đầu tiên (từ hàng thứ 1 đến hàng thứ 10)
LIMIT 5,10: in ra 10 hàng, từ hàng thứ 6 đến hàng thứ 15
LIMIT 10,2: in ra 2 hàng, từ hàng thứ 11 đến hàng thứ 12
Cuc cu! Xin chào! Tớ là người thích cảm giác mạnh, cho tớ hỏi là tớ có thể để chung tất cả các tiêu chuẩn lựa chọn mà tớ học nãy giờ vào cùng một dòng query duy nhất được không ?
Nghe kĩ đây bạn !
Đây là món tả pín lù mà bạn vừa đề nghị nè :

Code SQL :
SELECT nom, possesseur, console, prix FROM jeux_videos WHERE console='Xbox' OR console='PS2' ORDER BY prix DESC LIMIT 0,10
Bạn phải sử dụng các từ khóa về tiêu chuẩn lựa chọn theo thứ tự mà tôi ghi trên đây, tức là WHERE rồi mới tới ORDER BY rồi mới tới LIMIT, nếu không thì MySQL sẽ không hiểu đâu !
Bạn thử dịch ngôn ngữ SQL trên đây sang tiếng Việt thử xem ! Rồi test thử dùm tôi nhé ! Tôi lười quá nên chưa test!

Đếm số hàng trong bảng dữ liệu

Trước khi kết thúc chương này, mình hãy thử làm một động tác mà đôi khi cũng thú vị: đếm số hàng trong bảng dữ liệu! Ví dụ bạn có thể ghi ra câu "Tạm thời có 50 trò chơi được bán" nếu như bạn đếm được rằng có 50 hàng (mỗi hàng tương ứng với một trò chơi) trong bảng jeux_videos!
Để đếm, mình dùng code như sau:

Code PHP:
<?php
mysql_connect("localhost","root","");
mysql_select_db("khoailang");
$traloi=mysql_query("SELECT COUNT(*) AS so_hang FROM jeux_videos");
$ketqua=mysql_fetch_array($traloi);
echo "Tổng cộng có $ketqua['so_hang'] trò chơi đang được bán!";
mysql_close();
?>
Từ khóa COUNT dùng để đếm xem có bao nhiêu hàng trong bảng jeux_videos rồi cho ra giá trị trong mảng $ketqua['so_hang']
Bạn cũng có thể thêm tiêu chuẩn lựa chọn vào query trên, chẳng hạn đếm xem có bao nhiêu trò chơi của Florent chẳng hạn! Thử xem!

Hết chương 3.


precedent chapter Mục Lục next chapter

Copyright© NGUYỄN Thanh Trà