Как получить имена столбцов через PDO / Sqlite, когда запрос не возвращает записи?

Следующий код позволяет мне передать инструкцию SQL классу и вызвать его метод для отображения хорошей таблицы результатов, включая имена столбцов.

Однако, если результатов нет, я все равно хочу, чтобы имена столбцов отображались.

К сожалению, 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> 

Мета-таблица 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]) ) ; } 
  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 независящей).

  1. Во-вторых, я думаю, что это легче сделать: если результаты не возвращаются из запроса, не отображаются имена coulmn или таблица вообще, просто выведите сообщение: «Результаты не найдены». Это может быть достигнуто в вашем методе displayHtmlTable :

      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; } 

И вам не нужно беспокоиться о именах столбцов …

EDIT: для первого случая найден запрос SQLite, который должен делать то же самое, что select * from information_schema.columns where table_name = 'xxx' :

 PRAGMA table_info(table-name); 

Просто чтобы увеличить комментарий @shadyyx:

PRAGMA table_info(table-name);

У меня нет песочницы PDO_SQLITE, но с использованием встроенного драйвера SQLite3 этот фрагмент даст вам имена столбцов таблицы table-name в $ 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);