2012-06-13 60 views
2

以下代碼允許我將SQL語句傳遞給一個類,並調用其方法來顯示結果的好表,包括列名。當查詢返回沒有記錄時,如何通過PDO/Sqlite獲取列名?

但是,如果沒有結果,我仍然想顯示列名

不幸的是,getColumnMeta沒有像我在其他例子中發現的那樣返回任何數據。

有沒有人知道如何獲得getColumnMeta()在這個例子中工作,或另一種方式,我可以從查詢返回零行時從SQL語句的字段的名稱?

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
     <style type="text/css"> 
      table thead tr td { 
       background-color: #ddd; 
       padding: 5px; 
       font-weight: bold; 
      } 
      table tbody tr td { 
       background-color: #eee; 
       padding: 5px; 
       color: navy; 
      } 
      div.sqlCommand { 
       font-family: courier; 
      } 

      h2 { 
       border-bottom: 1px solid #777; 
      } 
     </style> 
    </head> 
    <body> 
     <?php 

     $sql = 'SELECT LastName,FirstName,Title FROM employee WHERE 1=2 ORDER BY LastName'; 

     echo '<h2>sqlite</h2>'; 
     $dbSqlite = new DbSqlite($sql); 
     echo $dbSqlite -> displayHtmlTable(); 

     class DbSqlite { 
      protected $sql; 
      protected $records = array(); 
      protected $columnNames = array(); 
      public function __construct($sql) { 
       $this -> sql = $sql; 
       $this -> initialize(); 
      } 

      protected function initialize() { 
       $db = new PDO('sqlite:chinook.sqlite'); 
       $result = $db -> query($this -> sql); 
       $result -> setFetchMode(PDO::FETCH_ASSOC); 
       $columnsAreDefined = false; 
       while ($row = $result -> fetch()) { 
        $this -> records[] = $row; 
        if (!$columnsAreDefined) { 
         foreach ($row as $columnName => $dummy) { 
          $this -> columnNames[] = $columnName; 
         } 
         $columnsAreDefined = true; 
        } 
       } 

       if (count($this -> records) == 0) { 
        $total_column = $result -> columnCount(); 
        var_dump($total_column); 

        for ($x = 0; $x < $total_column; $x++) { 
         $meta = $result -> getColumnMeta($x); 
         //var_dump($meta); 
         //bool(false) 
         //$column[] = $meta['name']; 
        } 
       } 
      } 

      public function displayHtmlTable() { 
       $r = ''; 

       $r .= '<div class="sqlCommand">' . $this -> sql . '</div>'; 

       $r .= '<table>'; 

       $r .= '<thead>'; 
       $r .= '<tr>'; 
       foreach ($this->columnNames as $columnName) { 
        $r .= '<td>' . $columnName . '</td>'; 
       } 
       $r .= '</tr>'; 
       $r .= '</thead>'; 

       $r .= '<tbody>'; 
       foreach ($this->records as $record) { 
        $r .= '<tr>'; 
        foreach ($record as $data) { 
         $r .= '<td>' . $data . '</td>'; 
        } 
        $r .= '</tr>'; 
       } 
       $r .= '</tbody>'; 
       $r .= '<table>'; 
       return $r; 
      } 

     } 
     ?> 
    </body> 

</html> 
+1

但是您的查詢具有列名稱,PDO返回它們是否重要? – allen213

+0

沒錯,但是如果我發送'SELECT *',那麼我需要依靠PDO從數據庫中獲取列名。 –

+0

夠公平的,只是想知道你是不是正在想它 – allen213

回答

2
  1. 第一種方法我會嘗試:
    • 運行查詢
    • 檢查,如果有結果返回
    • 如果是,運行initialize()displayHtmlTable
    • 如果沒有 ,運行您的initializeEmptyResult()將運行下一個查詢,並只填寫$this->columnNames[]
SELECT column_name FROM information_schema.columns WHERE table_name = 'my_table_name' 

查詢依賴於MySQL的BU應該有其他數據庫更多的選擇,或者你仍然可以運行DESCRIBE table和結果解析列名(應該是SQL DBMS undependent) 。

  1. 二是我認爲更容易實現:如果沒有從該查詢返回的結果,完全不顯示coulmn的名字,也沒有表,只顯示一條消息:「沒有找到結果」。

    public function displayHtmlTable() { 
         $r = ''; 
    
         $r .= '<div class="sqlCommand">' . $this -> sql . '</div>'; 
    
         if(count($this->records) > 0) { 
          $r .= '<table>'; 
    
          $r .= '<thead>'; 
          $r .= '<tr>'; 
          foreach ($this->columnNames as $columnName) { 
           $r .= '<td>' . $columnName . '</td>'; 
          } 
          $r .= '</tr>'; 
          $r .= '</thead>'; 
    
          $r .= '<tbody>'; 
          foreach ($this->records as $record) { 
           $r .= '<tr>'; 
           foreach ($record as $data) { 
            $r .= '<td>' . $data . '</td>'; 
           } 
           $r .= '</tr>'; 
          } 
          $r .= '</tbody>'; 
          $r .= '<table>'; 
         } else { 
          $r .= '<div class="no-results">No results found for query.</div>'; 
         } 
    
         return $r; 
        } 
    

而且你不必與列名打擾...

編輯:這可能您displayHtmlTable方法內實現對於第一種情況中發現的查詢SQLite的那應該做的一樣select * from information_schema.columns where table_name = 'xxx'

PRAGMA table_info(table-name); 
3

元表sqlite_master包含了所有的信息。下面的代碼將解析sqlite_master成列名$colnames

$colnames = array() ; 

$stmt = $dbh->prepare("SELECT sql FROM sqlite_master WHERE tbl_name = 'put_table_name_here'") ; 
$stmt->execute() ; 
$row = $stmt->fetch() ; 

$sql = $row[0] ; 
$r = preg_match("/\(\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE) ; 
while ($r) { 
    array_push($colnames, $m[1][0]) ; 
    $r = preg_match("/,\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE, $m[0][1] + strlen($m[0][0])) ; 
} 
+0

好的答案,非常感謝! –

0

只是對@shadyyx評論擴大:

PRAGMA table_info(table-name);

我沒有PDO_SQLITE沙箱方便,但使用本地SQLite3驅動程序,此代碼段將爲您提供表的列名稱$ arrColumns

$db = new SQLite3('db.sqlite'); 
$db->query('PRAGMA table_info(table-name)'); 
while ($col = $res->fetchArray(SQLITE3_ASSOC)) { 
    $arrColnames[]=$col['name']; 
} 
print_r($arrColnames); 
相關問題