麻辣家族討論版版's Archiver

小誌 發表於 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中,以方便您操作範例時使用。[color=Red][b]資料庫內的範例資料來自小誌參加技術士檢定考試的公開題庫資料,如有雷同存屬巧合。[/b][/color]
[attach]538[/attach]


[size=5][b][color=DarkOrange]查詢與取得資料[/color][/b][/size]
當我們建立與SQL Server的連結後,第一件事情不是馬上急著提取資料,而是應該選取我們要使用的資料庫,要選取操作的資料庫可使用「mssql_select_db()」函數:
mssql_select_db() 函數[code]int mssql_select_db ( string database_name [, int link_identifier])[/code]mssql_select_db()函數使用時需給定兩個參數:
[list]
[*]database_name:指定我們要操作的資料庫名稱。
[*]link_identifier:連線代號,mssql_select_db()函數只能指定操作哪個資料庫,並沒有連結資料庫的能力,因此,mssql_select_db()函數必須透過某個已建立並完成資料庫連結的「連線代號」,這個「連線代號」是由mssql_connect()函數所建立的,這個參數可以不指定,在mssql_query()函數執行時會自動找尋最近由mssql_connect()函數所建立的連線。
[/list]
例如:[code]<?
    $conn = mssql_connect("127.0.0.1", "sa", "12345");
    mssql_select_db("STUDENT", $conn);
?>[/code]mssql_connect()函數好用的地方在於:欲連上的資料庫伺服器參數內容可以是我們設定的DNS、資料庫伺服器名稱,設置是資料庫伺服器的IP,如上例中的「127.0.0.1」。

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


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

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


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

小誌 發表於 2010-5-17 16:31

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

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

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

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


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

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

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

小誌 發表於 2010-5-17 16:37

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

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

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

要提取全部的資料錄資料,又要避免「移過頭」的錯誤發生,則我們應該利用while迴圈敘述來提取資料:[code] //取得欄位數量
      $fieldnum=mssql_num_fields($datalist);
      //將資料錄轉換為欄位陣列集合
      while ($fielddatas=mssql_fetch_array($datalist))
          {
             //輸出欄位資料
             for ($x=0;$x<$fieldnum;$x++)
                {
                 echo $fielddatas[$x] . "\t";
                }
             echo "<br>";  
          }[/code][color=Magenta][b][size=4]實做學習:[/size][/b][/color]
讀取Stuent資料庫裡「成績單」資料表中全部的資料,並以表格型式輸出於網頁中:
[attach]547[/attach][code]<?
    $conn = mssql_connect("127.0.0.1", "sa", "12345");
    if(@mssql_select_db("STUDENT", $conn))
     {
      //資料庫存在,建立SQL命令字串
      $SQL="SELECT * FROM 成績單";
      //將回傳結果存放於變數中
      $datalist=mssql_query($SQL);
      //取得欄位數量
      $fieldnum=mssql_num_fields($datalist);
?>
<html>
<head>
<title>範例ex08_06</title>
</head>
<center><table border=1 width=100%>
<?
/**************列出欄位抬頭***************/
echo "<tr>";     
      for ($x=0 ;$x<$fieldnum;$x++)
         {
          echo "<td>" . mssql_field_name($datalist,$x) . "</td>";
         }
echo "</tr>";   
/**************列出欄位資料***************/
      //將資料錄轉換為欄位陣列集合
      while ($fielddatas=mssql_fetch_array($datalist))
          {
             //輸出欄位資料
             echo "<tr>";
             for ($x=0;$x<$fieldnum;$x++)
                {
                 echo "<td>" . $fielddatas[$x] . "</td>";
                }
             echo "</tr>";  
          }
?>
<table></body>
</html>
<?
     }
    else
     {
      echo "資料庫不存在";
     }
?>[/code]

小誌 發表於 2010-5-17 16:40

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

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


若我們想知到共有多少筆資料記錄可提取,則「mssql_num_rows()」函數可以告訴我們:
mssql_num_rows() 函數[code]int mssql_num_rows ( int result)[/code]例如:[code]//資料庫存在,建立SQL命令字串
$SQL="SELECT * FROM 成績單";
//將回傳結果存放於變數中
$datalist=mssql_query($SQL);
//取得資料錄筆數
$x=mssql_num_rows($datalist);
echo "共 $X 筆資料記錄";[/code]以上一個範例為例,我們可利用上述兩函數修改如下,讓程式只列印出1,3,5…等單數編號的資料錄:[code]<?
    $conn = mssql_connect("127.0.0.1", "sa", "12345");
    if(@mssql_select_db("STUDENT", $conn))
     {
      //資料庫存在,建立SQL命令字串
      $SQL="SELECT * FROM 成績單";
      //將回傳結果存放於變數中
      $datalist=mssql_query($SQL);
      //取得欄位數量
      $fieldnum=mssql_num_fields($datalist);
?>
<html>
<head>
<title>範例ex08_07</title>
</head>
<center><table border=1 width=100%>
<?
/**************列出欄位抬頭***************/
echo "<tr>";     
      for ($x=0 ;$x<$fieldnum;$x++)
         {
          echo "<td>" . mssql_field_name($datalist,$x) . "</td>";
         }
echo "</tr>";   
/**************列出欄位資料***************/
      //取得資料錄數量
      $rowsnum=mssql_num_rows($datalist);
      for ($y=0;$y<=$rowsnum;$y+=2)  
          {
             //變換作用中資料錄位置
            mssql_data_seek($datalist,$y);
             //將資料錄轉換為欄位陣列集合
            $fielddatas=mssql_fetch_array($datalist);
             //輸出欄位資料
             echo "<tr>";
             for ($x=0;$x<$fieldnum;$x++)
                {
                 echo "<td>" . $fielddatas[$x] . "</td>";
                }
             echo "</tr>";  
          }
?>
<table></body>
</html>
<?
     }
    else
     {
      echo "資料庫不存在";
     }
?>[/code]

a01456655 發表於 2013-8-7 16:25

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

小誌 發表於 2013-8-7 21:47

[quote]小誌大大
我會出現
此錯誤訊息:Fatal error: Call to undefined function mssql_connect()
我有去Googl ...
[size=2][color=#999999]a01456655 發表於 2013-8-7 16:25[/color] [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=56711&ptid=323][img]http://forum.twbts.com/images/common/back.gif[/img][/url][/size][/quote]

打開你的PHP.ini[code];extension=php_msqll.dll[/code]改為(去掉前方的分號)[code]extension=php_msqll.dll[/code]然後重新啟動你的網頁伺服器

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 ,你是不是搞混了?

頁: [1]

麻辣家族討論版版為 麻辣學園 網站成員  由 昱得資訊工作室 © Since 1993 所提供