Board logo

標題: [教學] (PHP+IIS+MsSQL教學第27篇) 資料讀取的 mssql 函數群 [打印本頁]

作者: 小誌    時間: 2010-5-17 16:06     標題: (PHP+IIS+MsSQL教學第27篇) 資料讀取的 mssql 函數群

經過上一章的洗禮,相信您對於資料庫與資料表已有基礎的認識,同時,您應該也已清楚的知道:要在PHP中連結Access資料庫或SQL Server必須透過odbc_connect()函數,而連結SQL Server還可以使用專屬的mssql_connection()函數。

因為本教學的主角之一為SQL Server,所以後續將以使用SQL Server專屬的mssql函數為學習重點。

mssql_connection()函數只負責連結資料庫,至於如何存取資料表內的資料可就派不上用場了,要存取資料必須靠mssql_query()、mssql_fetch_row()、mssql_fetch_field()等等函數。

本篇教學內容皆以SQL資料庫為使用對象,在下列附檔中有一個SQL資料庫「Student」,主資料檔Student.mdf、記錄檔Student.ldf,請您將檔案複製到您的硬碟裡並附加到SQL Server中,以方便您操作範例時使用。資料庫內的範例資料來自小誌參加技術士檢定考試的公開題庫資料,如有雷同存屬巧合。
[attach]538[/attach]


查詢與取得資料
當我們建立與SQL Server的連結後,第一件事情不是馬上急著提取資料,而是應該選取我們要使用的資料庫,要選取操作的資料庫可使用「mssql_select_db()」函數:
mssql_select_db() 函數
  1. int mssql_select_db ( string database_name [, int link_identifier])
複製代碼
mssql_select_db()函數使用時需給定兩個參數:

例如:
  1. <?
  2.     $conn = mssql_connect("127.0.0.1", "sa", "12345");
  3.     mssql_select_db("STUDENT", $conn);
  4. ?>
複製代碼
mssql_connect()函數好用的地方在於:欲連上的資料庫伺服器參數內容可以是我們設定的DNS、資料庫伺服器名稱,設置是資料庫伺服器的IP,如上例中的「127.0.0.1」。

mssql_select_db()函數的回傳值為一布林值,若選取資料庫成功則回傳true,若失敗則回傳fase,因此,我們可利用mssql_select_db()函數來測知資料庫是否存在,例如:
  1. <?
  2.     $conn = mssql_connect("127.0.0.1", "sa", "12345");
  3.     if(@mssql_select_db("STUDENT", $conn))
  4.      {
  5.       echo "資料庫存在";
  6.      }
  7.     else
  8.      {
  9.       echo "資料庫不存在";
  10.      }
  11. ?>
複製代碼
在上例中:if判斷式中怎有一個「@(小老鼠)」符號?因為小誌希望:當mssql_select_db()函數執行失敗時PHP不要印出如下圖中PHP回應的錯誤訊息,也就是這個「@(小老鼠)」符號會隱藏PHP回應的錯誤訊息!
[attach]539[/attach]


查詢與取得資料的mssql_query()函數
當使用mssql_select_db()函數選取我們要使用的資料庫後,就可以開始利用「mssql_query()」函數來查詢並取得資料庫內某個資料表的資料記錄:

mssql_query() 函數
  1. int mssql_query ( string query [, int link_identifier])
複製代碼
mssql_query()函數使用時需給定兩個參數:
  1. query:查詢字串,也就是要對資料庫下達的SQL字串,例如「Select」命令。
  2. link_identifier:連線代號,某個已建立並完成資料庫連結的「連線代號」,這個參數可以不指定,在mssql_query()函數執行時會自動找尋最近由mssql_connect()函數所建立的連線。
複製代碼
例如:
  1. <?
  2.     $conn = mssql_connect("127.0.0.1", "sa", "12345");
  3.     if(mssql_select_db("STUDENT", $conn))
  4.      {
  5.       //資料庫存在,進行資料查詢
  6.       $SQL="SELECT * FROM 成績單";
  7.       mssql_query($SQL);
  8.      }
  9.     else
  10.      {
  11.       echo "資料庫不存在";
  12.      }
  13. ?>
複製代碼
由mssql_query()函數的格式您可以發現其回傳值為一個整數值,其實不然,例如我們所下達的SQL指令為「Select」(取得某個資料表內的資料記錄),如果順利取回資料,則回傳值其實是一張虛擬的「資料表」,反之,未順利取得資料此時回傳值才會是整數0。
當然,上例是可以執行的,但卻未達到我們提取資料的目的,為什麼呢?因為我們沒有將mssql_query()函數執行後的回傳結果保留下來!所以我們應該將範例更正如下:
  1.     …
  2.     if(@mssql_select_db("STUDENT", $conn))
  3.      {
  4.       //資料庫存在,建立SQL命令字串
  5.       $SQL="SELECT * FROM 成績單";
  6.       //將回傳結果存放於變數中
  7.       $datalist=mssql_query($SQL);
  8.      }
  9.     else
複製代碼



何謂SQL
SQL是Structure Query Language的簡寫,翻譯為"結構化查詢語言"。SQL語言是使用一些淺顯易懂的口語化句子構成指令,來存取資料庫的內容。就因為它口語化的指令敘述,所以各大廠商的資料庫軟體就大多使用SQL語言,而微軟的「SQL Server」只是得到了「名稱」之便罷了,像Orcale、Interbase或我們之前說明中一直在使用的Access(*.mdb)資料庫等,都是使用SQL語言的資料庫。
作者: 小誌    時間: 2010-5-17 16:31

讀取資料集
要讀取mssql_query()函數所取得的資料,就必須先了解資料表的結構,如果我們將資料表作大部的分解,則可區分為欄位抬頭與資料表內容(欄位資料)兩大部分:
[attach]541[/attach]

「欄位抬頭」是由數個「欄位名稱」所組合而成,如下圖的欄位抬頭就是由「姓名」、「出生年月日」、「身分證字號」、「住址」、「家長」、「電話」、「科別」等欄位名稱所組合而成:
[attach]542[/attach]

而「資料表內容」則是由多筆「資料錄(Record)」所集合而成;而每一筆的資料錄又是由多個「欄位(Field)」所組成:
[attach]543[/attach]

所以,我們可以把資料庫的結構分析如圖8-5,以文字來解釋就是:「資料欄位組成資料錄,資料錄組成資料表,資料表組成資料庫」。
[attach]544[/attach]


Field物件
資料庫中最小的資料單位為『欄位』,也就是Field物件,Filed物件擁有三個屬性,分別為『Name』(欄位名稱)、『Value』(欄位資料值)、『Type』(欄位資料型態,例如:數字、文字、日期....等等)等三種:
[attach]545[/attach]

要得知資料表中共有多少個欄位可使用「mssql_num_fields()」函數:
mssql_num_fields() 函數
  1. int mssql_num_fields ( int result)
複製代碼
當我們知道資料表中共有多少個欄位就可利用「mssql_field_name()」函數列舉各個欄位的抬頭:
mssql_field_name() 函數
  1. int mssql_field_name ( int result [, int offset])
複製代碼
如果我們要將全部欄位名稱列舉出來,可利用下列這段程式碼:
  1.            //將回傳結果存放於變數中
  2.       $datalist=mssql_query($SQL);
  3.       //取得欄位數量
  4.       $fieldnum=mssql_num_fields($datalist);
  5.       //列出欄位抬頭
  6.       for ($x=0 ;$x<$fieldnum;$x++)
  7.          {
  8.           echo mssql_field_name($datalist,$x) . "<br>";
  9.          }
複製代碼
使用「mssql_field_type()」函數則可列舉出每個欄位的儲存資料型態:
mssql_field_type() 函數
  1. string mssql_field_type ( int result [, int offset])
複製代碼
如果我們要將全部欄位的儲存資料型態列舉出來,可利用下列這段程式碼:
  1.      //將回傳結果存放於變數中
  2.       $datalist=mssql_query($SQL);
  3.       //取得欄位數量
  4.       $fieldnum=mssql_num_fields($datalist);
  5.       //列出欄位資料型態
  6.       for ($x=0 ;$x<$fieldnum;$x++)
  7.          {
  8.           echo mssql_field_type($datalist,$x) . "<br>";
  9.          }
複製代碼
Fields 集合物件
Field物件的集合就是Fields集合物件,對比於資料庫的組織結構來看,欄位的集合就構成『資料錄』,每一筆的資料錄(Fields集合物件)是由多個「欄位(Field)」所組成,也就說資料錄是採用「陣列」的方式集合多個欄位而成;換言之:「資料錄就是欄位陣列」。
[attach]546[/attach]

所以我們可以利用「mssql_fetch_array()」函數取得一筆資料錄:
mssql_fetch_array() 函數
  1. array mssql_fetch_array ( int result)
複製代碼
取得一筆資料錄後,即可利用陣列特性取得取得特定欄位的欄位資料,如下列程式敘述:
  1.       //資料庫存在,建立SQL命令字串
  2.       $SQL="SELECT * FROM 通訊錄";
  3.       //將回傳結果存放於變數中
  4.       $datalist=mssql_query($SQL);
  5.       //將資料錄轉換為欄位陣列集合
  6.       $fielddatas=mssql_fetch_array($datalist);
  7.       //取出註標編號為0的欄位資料
  8.       echo $fielddatas[0] . "<br>";
  9.       //取出姓名欄位的資料
  10.       echo $fielddatas["姓名"];
複製代碼
利用「mssql_featch_array()」函數取得一筆資料錄,我們可以數字的元素陣列註標編號(欄位編號)或元素陣列字串註標(欄位抬頭)取得特定欄位內的資料,如上例粗體字部分的程式敘述。
作者: 小誌    時間: 2010-5-17 16:37

「作用中」的資料錄
在我們存取資料表的資料時,是以一筆資料錄為單位!也就是說:我們只能對「作用中」的資料錄進行資料存取的動作。當我們開啟資料表時,「作用中」的資料錄位置是在資料表的第一筆資料上,如果我們想要改變目前操作的「作用中」的資料錄位置,怎辦呢?

當我們利用「mssql_featch_array()」函數取得一筆資料錄資料後,則「作用中」的資料錄位置會自動移到下一筆尚未提取資料的資料錄位置上,當我們在變換資料錄位置時(變更作用中資料錄位置),要小心一件事,那就是作用中資料錄位置是否移過了最後一筆資料的位置!也就是全部的資料錄都已經提取過資料了。

那我們如何得知全部的資料錄都已經提取過資料了呢?當我們利用「mssql_fetch_array()」函數取得資料錄資料所得的回傳值是false時就是作用中資料錄位置移過頭了,回傳值是false的原因還有一個,就是開啟的是一個空的資料表。

要提取全部的資料錄資料,又要避免「移過頭」的錯誤發生,則我們應該利用while迴圈敘述來提取資料:
  1. //取得欄位數量
  2.       $fieldnum=mssql_num_fields($datalist);
  3.       //將資料錄轉換為欄位陣列集合
  4.       while ($fielddatas=mssql_fetch_array($datalist))
  5.           {
  6.              //輸出欄位資料
  7.              for ($x=0;$x<$fieldnum;$x++)
  8.                 {
  9.                  echo $fielddatas[$x] . "\t";
  10.                 }
  11.              echo "<br>";  
  12.           }
複製代碼
實做學習:
讀取Stuent資料庫裡「成績單」資料表中全部的資料,並以表格型式輸出於網頁中:
[attach]547[/attach]
  1. <?
  2.     $conn = mssql_connect("127.0.0.1", "sa", "12345");
  3.     if(@mssql_select_db("STUDENT", $conn))
  4.      {
  5.       //資料庫存在,建立SQL命令字串
  6.       $SQL="SELECT * FROM 成績單";
  7.       //將回傳結果存放於變數中
  8.       $datalist=mssql_query($SQL);
  9.       //取得欄位數量
  10.       $fieldnum=mssql_num_fields($datalist);
  11. ?>
  12. <html>
  13. <head>
  14. <title>範例ex08_06</title>
  15. </head>
  16. <center><table border=1 width=100%>
  17. <?
  18. /**************列出欄位抬頭***************/
  19. echo "<tr>";     
  20.       for ($x=0 ;$x<$fieldnum;$x++)
  21.          {
  22.           echo "<td>" . mssql_field_name($datalist,$x) . "</td>";
  23.          }
  24. echo "</tr>";   
  25. /**************列出欄位資料***************/
  26.       //將資料錄轉換為欄位陣列集合
  27.       while ($fielddatas=mssql_fetch_array($datalist))
  28.           {
  29.              //輸出欄位資料
  30.              echo "<tr>";
  31.              for ($x=0;$x<$fieldnum;$x++)
  32.                 {
  33.                  echo "<td>" . $fielddatas[$x] . "</td>";
  34.                 }
  35.              echo "</tr>";  
  36.           }
  37. ?>
  38. <table></body>
  39. </html>
  40. <?
  41.      }
  42.     else
  43.      {
  44.       echo "資料庫不存在";
  45.      }
  46. ?>
複製代碼

作者: 小誌    時間: 2010-5-17 16:40

資料錄位置變換
在上一小節中,我們已知道:利用「mssql_featch_array()」函數取得一筆資料錄資料後,則「作用中」的資料錄位置會自動移到下一筆尚未提取資料的資料錄位置上,其實還有一個快速變換作用中資料錄位置的函數:mssql_data_seek():

mssql_data_seek() 函數
  1. int mssql_data_seek ( int result_identifier, int row_number)
複製代碼
當變換作用中資料錄位置成功回傳true值,反之,回傳false值;例如,快速變換作用中資料錄位置到第一筆資料錄上:
  1. $datalist=mssql_query($SQL);
  2. mssql_data_seek($datalist,0);
複製代碼
請注意:資料錄的位置編號是從0開始!


若我們想知到共有多少筆資料記錄可提取,則「mssql_num_rows()」函數可以告訴我們:
mssql_num_rows() 函數
  1. int mssql_num_rows ( int result)
複製代碼
例如:
  1. //資料庫存在,建立SQL命令字串
  2. $SQL="SELECT * FROM 成績單";
  3. //將回傳結果存放於變數中
  4. $datalist=mssql_query($SQL);
  5. //取得資料錄筆數
  6. $x=mssql_num_rows($datalist);
  7. echo "共 $X 筆資料記錄";
複製代碼
以上一個範例為例,我們可利用上述兩函數修改如下,讓程式只列印出1,3,5…等單數編號的資料錄:
  1. <?
  2.     $conn = mssql_connect("127.0.0.1", "sa", "12345");
  3.     if(@mssql_select_db("STUDENT", $conn))
  4.      {
  5.       //資料庫存在,建立SQL命令字串
  6.       $SQL="SELECT * FROM 成績單";
  7.       //將回傳結果存放於變數中
  8.       $datalist=mssql_query($SQL);
  9.       //取得欄位數量
  10.       $fieldnum=mssql_num_fields($datalist);
  11. ?>
  12. <html>
  13. <head>
  14. <title>範例ex08_07</title>
  15. </head>
  16. <center><table border=1 width=100%>
  17. <?
  18. /**************列出欄位抬頭***************/
  19. echo "<tr>";     
  20.       for ($x=0 ;$x<$fieldnum;$x++)
  21.          {
  22.           echo "<td>" . mssql_field_name($datalist,$x) . "</td>";
  23.          }
  24. echo "</tr>";   
  25. /**************列出欄位資料***************/
  26.       //取得資料錄數量
  27.       $rowsnum=mssql_num_rows($datalist);
  28.       for ($y=0;$y<=$rowsnum;$y+=2)  
  29.           {
  30.              //變換作用中資料錄位置
  31.             mssql_data_seek($datalist,$y);
  32.              //將資料錄轉換為欄位陣列集合
  33.             $fielddatas=mssql_fetch_array($datalist);
  34.              //輸出欄位資料
  35.              echo "<tr>";
  36.              for ($x=0;$x<$fieldnum;$x++)
  37.                 {
  38.                  echo "<td>" . $fielddatas[$x] . "</td>";
  39.                 }
  40.              echo "</tr>";  
  41.           }
  42. ?>
  43. <table></body>
  44. </html>
  45. <?
  46.      }
  47.     else
  48.      {
  49.       echo "資料庫不存在";
  50.      }
  51. ?>
複製代碼

作者: a01456655    時間: 2013-8-7 16:25

小誌大大
我會出現
此錯誤訊息:Fatal error: Call to undefined function mssql_connect()
我有去Google  修改後沒得到幫助。。。
想請問一下
大大有沒有遇過此問題  要如何修改呢??
作者: 小誌    時間: 2013-8-7 21:47

小誌大大
我會出現
此錯誤訊息:Fatal error: Call to undefined function mssql_connect()
我有去Googl ...
a01456655 發表於 2013-8-7 16:25


打開你的PHP.ini
  1. ;extension=php_msqll.dll
複製代碼
改為(去掉前方的分號)
  1. extension=php_msqll.dll
複製代碼
然後重新啟動你的網頁伺服器
作者: a01456655    時間: 2013-8-8 09:21

我在網路上找到解決方法了,給版大看看是否有差別
如下:
$conn = mysql_connect("127.0.0.1",'userid','password') or die("can't open this DB");
版大您用的是  mssql 但我用別人教的  mysql 就可以連上
mssql 與 mysql 這二個函式有什麼差別嗎??
作者: 小誌    時間: 2013-8-8 11:17

mysql_connect 用於連結 MySQL資料庫
mssql_connect 用於連結微軟SQL SERVER
本篇教學是針對連結微軟SQL SERVER ,你是不是搞混了?




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)