1

PHP でこのクエリを実行すると、エラーが発生します。

SELECT hit.timestamp, 
       hit.id, 
       config.Name, 
       hit.meter_id, 
       levels.LevelName, 
       pos.sm_pos, 
       hit.hit_value 
FROM   hit 
       INNER JOIN config 
               ON hit.id = config.id 
       INNER JOIN levels 
               ON hit.meter_id = levels.id 
       INNER JOIN POS 
               ON pos.id = hit.id 
       INNER JOIN controllers 
               ON pos.controller_id = controllers.id; 

問題は、選択ステートメントの最初の列を除く各列で未定義のインデックスを取得していることです。最初の 1 つでエラーが発生することはなく、正常にデータが返されます。他はエラーを出しています。

何が間違っているのですか?そして、私は何を変える必要がありますか?

編集: このクエリは、 DataTablesスクリプトを使用するときに使用されます。したがって、このスクリプトを使用する場合、完全な php コードは次のようになります。

<?php
    /*
     * Script:    DataTables server-side script for PHP and MySQL
     * Copyright: 2010 - Allan Jardine
     * License:   GPL v2 or BSD (3-point)
     */

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Easy set variables
     */

    /* Array of database columns which should be read and sent back to DataTables. Use a space where
     * you want to insert a non-database field (for example a counter or static image)
     */
    $aColumns = array( 'hit.timestamp','hit.id', 'config.Name', 'hit.meter_id','levels.LevelName','pos.sm_pos','hit.hit_value'  );

    /* Indexed column (used for fast and accurate table cardinality) */
    $sIndexColumn = "hit.id";

    /* DB table to use */
    $sTable = "hit 
       INNER JOIN config 
               ON hit.id = config.id 
       INNER JOIN levels 
               ON hit.meter_id = levels.id 
       INNER JOIN POS 
               ON pos.id = hit.id 
       INNER JOIN controllers 
               ON pos.controller_id = controllers.id";

    /* Database connection information */
    $gaSql['user']       = "";
    $gaSql['password']   = "";
    $gaSql['db']         = "";
    $gaSql['server']     = "localhost";


    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * If you just want to use the basic configuration for DataTables with PHP server-side, there is
     * no need to edit below this line
     */

    /* 
     * MySQL connection
     */
    $gaSql['link'] =  mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password']  ) or
        die( 'Could not open connection to server' );

    mysql_select_db( $gaSql['db'], $gaSql['link'] ) or
        die( 'Could not select database '. $gaSql['db'] );


    /* 
     * Paging
     */
    $sLimit = "";
    if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
    {
        $sLimit = "LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".
            mysql_real_escape_string( $_GET['iDisplayLength'] );
    }


    /*
     * Ordering
     */
    $sOrder = "";
    if ( isset( $_GET['iSortCol_0'] ) )
    {
        $sOrder = "ORDER BY  ";
        for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
        {
            if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
            {
                $sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
                    ".mysql_real_escape_string( $_GET['sSortDir_'.$i] ) .", ";
            }
        }

        $sOrder = substr_replace( $sOrder, "", -2 );
        if ( $sOrder == "ORDER BY" )
        {
            $sOrder = "";
        }
    }


    /* 
     * Filtering
     * NOTE this does not match the built-in DataTables filtering which does it
     * word by word on any field. It's possible to do here, but concerned about efficiency
     * on very large tables, and MySQL's regex functionality is very limited
     */
    $sWhere = "";
    if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" )
    {
        $sWhere = "WHERE (";
        for ( $i=0 ; $i<count($aColumns) ; $i++ )
        {
            if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" )
            {
                $sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string( $_GET['sSearch'] )."%' OR ";
            }
        }
        $sWhere = substr_replace( $sWhere, "", -3 );
        $sWhere .= ')';
    }

    /* Individual column filtering */
    for ( $i=0 ; $i<count($aColumns) ; $i++ )
    {
        if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
        {
            if ( $sWhere == "" )
            {
                $sWhere = "WHERE ";
            }
            else
            {
                $sWhere .= " AND ";
            }
            $sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string($_GET['sSearch_'.$i])."%' ";
        }
    }


    /*
     * SQL queries
     * Get data to display
     */
    $sQuery = "
        SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
        FROM   $sTable
        $sWhere
        $sOrder
        $sLimit
    ";
    $rResult = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());

    /* Data set length after filtering */
    $sQuery = "
        SELECT FOUND_ROWS()
    ";
    $rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
    $aResultFilterTotal = mysql_fetch_array($rResultFilterTotal);
    $iFilteredTotal = $aResultFilterTotal[0];

    /* Total data set length */
    $sQuery = "
        SELECT COUNT(".$sIndexColumn.")
        FROM   $sTable
    ";
    $rResultTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
    $aResultTotal = mysql_fetch_array($rResultTotal);
    $iTotal = $aResultTotal[0];


    /*
     * Output
     */
    $output = array(
        "sEcho" => intval($_GET['sEcho']),
        "iTotalRecords" => $iTotal,
        "iTotalDisplayRecords" => $iFilteredTotal,
        "aaData" => array()
    );

    while ( $aRow = mysql_fetch_array( $rResult ) )
    {
        $row = array();
        for ( $i=0 ; $i<count($aColumns) ; $i++ )
        {
            if ( $aColumns[$i] == "version" )
            {
                /* Special output formatting for 'version' column */
                $row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
            }
            else if ( $aColumns[$i] != ' ' )
            {
                /* General output */
                $row[] = $aRow[ $aColumns[$i] ];
            }
        }
        $output['aaData'][] = $row;
    }

    echo json_encode( $output );
?>

出力時のこの最後の部分が使用$row[] = $aRow[ $aColumns[$i] ];されています。select ステートメントで table.column タイプを使用しているため、ここに問題があると思います。そして面白いことに、select ステートメントの最初の列が通過し、値を取得しています。そして他の人は私に未定義のインデックスを与えています。

4

1 に答える 1

2

この問題は、修正されたバージョンの DataTables サンプル スクリプトを使用し、 SO チャットでさらに議論することで解決されました。

時間ができ次第、将来の訪問者のために適切な回答の形で完全な記事を書きます.


手短に:

DataTablesサンプル PHP スクリプトは、フィールド リスト メカニズムで列エイリアスまたは MySQL 関数呼び出しを使用する可能性に対応していません。これにより、JOIN を実行したり、なんらかの形式のデータ変換を結果に適用したりするクエリは、なんらかの変更なしでは達成できなくなります。

上にリンクされている修正版では、正規表現を使用してフィールド エイリアスを安全に使用していますが、関数呼び出しはまだ許可されていません。これは、このインスタンスで目的の結果を生成するために実際に必要なものです。これは、変換作業の一部を PHP にサブブリングし、返された結果にユーザー定義の日付範囲を適用するためにいくつかの追加の変更を加えることで回避されました。

正確に何が行われたか、およびその理由の完全な詳細は、上記のリンクを表示することで確認できます。


将来の訪問者に役立つ可能性があるプロセスから私が取ったことが1つあるとすれば、それは次のとおりです。

DataTables で使用するための非常に単純なクエリ以上のものが必要な場合は、バックエンド コードの最後の行をすべて理解し、それがフロントエンドとどのようにやり取りするかを確認することをお勧めします。

提供されているサンプル スクリプトは良い出発点となりますが、それらの機能が網羅されているわけではありません。目的の結果を得るには、スクリプトを変更したり、完全に書き直したりする準備をする必要があります。

于 2012-06-15T09:45:20.500 に答える