2009-03-06 89 views
1

我在通過mysqli執行預備語句時遇到問題。SQL類似語句問題

首先我得到了命令不同步的錯誤。我正在存儲結果並關閉連接,並且我已經停止了這個錯誤,所以希望問題已經停止。

但是,我的sql語法錯誤,這是工作正常,而命令不同步的錯誤,再次出現。這是我當前的代碼:

我已經嘗試了很多不同的方法來糾正這個snytax錯誤,從使用CONCAT,它被註釋掉,因爲它失敗了,從綁定等前賦予%符號變量..沒有工作。

試圖使用:

$numRecords->bind_param("s", "%".$brand."%"); 

結果的誤差通過引用傳遞。

<?php 
$con = mysqli_connect("localhost", "blah", "blah", "blah"); 
if (!$con) { 
    echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error(); 
    exit; 
} 
$con->query("SET NAMES 'utf8'"); 
$brand = "o"; 
$brand = "% ".$brand." %"; 
echo "\n".$brand; 
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?"; 
//CONCAT('%', ?, '%')"; 
echo "\ntest"; 
if ($numRecords = $con->prepare($countQuery)) { 
    $numRecords->bind_param("s", $brand); 
    echo "\ntest bind"; 
    $numRecords->execute(); 
    echo "\ntest exec"; 
    $numRecords->store_result(); 
    $data = $con->query($countQuery) or die(print_r($con->error)); 
    $rowcount = $data->num_rows; 
    $numRecords->free_result(); 
    $numRecords->close(); 
    echo "/ntest before rows"; 
    $rows = getRowsByArticleSearch("test", "Auctions", " "); 
    $last = ceil($rowcount/$page_rows); 
} else { 
    print_r($con->error); 
} 
foreach ($rows as $row) { 
    $pk = $row['ARTICLE_NO']; 
    echo '<tr>' . "\n"; 
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n"; 
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n"; 
    echo '<td><a href="#" onclick="deleterec(\'Layer2\', \'' . $pk . '\')">DELETE RECORD</a></td>' . "\n"; 
    echo '</tr>' . "\n"; 
} 
function getRowsByArticleSearch($searchString, $table, $max) { 
    $con = mysqli_connect("localhost", "blah", "blah", "blah"); 
    //global $con; 
    $recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y') AS shortDate FROM $table WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max; 
    if ($getRecords = $con->prepare($recordsQuery)) { 
     $getRecords->bind_param("s", $searchString); 
     $getRecords->execute(); 
     $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate); 
     while ($getRecords->fetch()) { 
      $result = $con->query($recordsQuery); 
      $rows = array(); 
      while($row = $result->fetch_assoc()) { 
       $rows[] = $row; 
      } 
      return $rows; 
     } 
    } 
} 

確切的錯誤是:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 11 

11號線是定義$ countQuery行。

正如你所看到的,品牌被認爲是「o」;

所以SQL語句應該

SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE %o%; 

當我把它在手動工作正常。

+0

ps除非你的'ARTICLE_NAME'是一個二進制字符串,不需要大寫 - 正常的變量對比較操作不區分大小寫。 – Alnitak 2009-03-06 12:14:26

+0

,不要忘記清理結果集並關閉getRowsByArticleSearch函數中的數據庫連接。你似乎也離開這個功能太早。 – Alnitak 2009-03-06 12:19:25

+0

第11行不應該(AFAIK)指的是你的PHP源代碼中的行--MySQL不知道錯誤在哪行號。 – Alnitak 2009-03-06 12:23:55

回答

4

mysqli_stmt::bind_param只能結合特定變量,而不是一個表達式。提供的變量通過引用傳遞給「綁定」,而不是通過值傳遞,這意味着底層SQL獲取該命令執行時該變量具有的任何值,而不是綁定時的值。

用途:

WHERE field LIKE CONCAT('%', ?, '%") 

或做:

$brand = '%' . $brand . '%' 

之前執行命令。

什麼,你不能做的是:

WHERE field LIKE '%?% 

因爲?約束變量必須對應一個字符串或數值,而不是一個字符串(或字段名)。

編輯在這種情況下,你真正的問題似乎與普通的舊查詢中混合了預處理語句(由mysqli::preparemysqli_stmt::execute()爲支持)(如mysqli::query()完成)。你也應該只從數據庫服務器要求的行數,直接,而不是提取數據,並使用NUM_ROWS:

$countQuery = "SELECT COUNT(ARTICLE_NO) FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?"; 
if ($numRecords = $con->prepare($countQuery)) { 
    $numRecords->bind_param("s", $brand); 
    $numRecords->execute(); 
    $numRecords->bind_result($num_rows); 
    $numRecords->fetch(); 
    $numRecords->free_result(); 
    $numRecords->close(); 
    $last = ceil($rowcount/$page_rows); 
} else { 
    print_r($con->error); 
} 
0

這個職位上mysql.com似乎表明,CONCAT()應該工作: http://forums.mysql.com/read.php?98,111039,111060#msg-111060

您是否嘗試過使用名爲PARAMS?

您嘗試撥打:

$numRecords->bind_param("s", "%".$brand."%"); 

但是你的SQL是:

$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?"; 

不應該是什麼? (注意LIKE ?s

$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE ?s"; 
0

的問題是不是在準備好的聲明,但在調用「查詢」方法不應該在那裏 - 因爲它用於執行「標準」(未準備好)的語句。

$data = $con->query($countQuery) or die(print_r($con->error)); 
$rowcount = $data->num_rows; 

應該

$rowcount = $numRecords->num_rows; 

在getRowsByArticleSearch功能,您應該再次下降的查詢,並使用傳遞給bind_result的輸出變量:

$getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate); 
    while ($getRecords->fetch()) { 
    $pk = $ARTICLE_NO; 
    echo '<tr>' . "\n"; 
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$USERNAME.'</a></td>' . "\n"; 
    // etc... 
    } 

一個多一點信息,檢查PHP的bind_result手冊:http://php.net/manual/en/mysqli-stmt.bind-result.php