2012-01-05 14 views
-1

土地の中で最高のプログラマではありません。私は、この質問を誰かが間違いを見つけたり、私が間違った方法で行っていると願ってこの質問をすると思っていました。サーバエラーMySQLエラー - 1064

MYSQLデータベースを検索して結果を返す検索機能を作成しようとしているFlash Builder Webサイトがあります。

ユーザーが関連する変数にデータを入力しない場合に備えて、私はnot nullの部分を含めました。

しかし、私はこのエラーを受けています 理由:サーバーエラーMySQLエラー - 1064:SQL構文にエラーがあります。 HEREライン1#0

に近い「女性LIKE井戸やセックス」を使用する権利構文についてはMySQLサーバのバージョンに対応するマニュアルを確認してくださいCODE

public function searchClients($fname, $lname, $country, $town, $sex) { 

$SQLStatment = "SELECT id, fname, lname, sex, country, town, dateofbirth, monthofbirth, yearofbirth FROM $this->tablename"; 
$WhereClause = ""; 
$where =" Where "; 

if($fname != "NULL") { 
      $WhereClause.= 'Fname LIKE '.$fname; 
}   

if($lname != "NULL") { 
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND lname LIKE ' .$lname; 
} 
else 
{ 
     $WhereClause = 'lname LIKE ' .$lname; 
} 
} 

if($country != "NULL") {  
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND country LIKE ' .$country; 
} 
else 
{ 
     $WhereClause = 'country LIKE ' .$country; 
} 
} 

if($town != "NULL") { 
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND town LIKE ' .$town; 
} 
else 
{ 
     $WhereClause = 'town LIKE ' .$town; 
} 
}  

if($sex != "NULL") { 
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND sex LIKE ' .$sex; 
} 
else 
{ 
     $WhereClause = 'sex LIKE ' .$sex; 
} 
}  
$SQLStatment.= $where; 
$SQLStatment.= $WhereClause; 

    $stmt = mysqli_prepare($this->connection, $SQLStatment); 
    $this->throwExceptionOnError(); 

    mysqli_stmt_execute($stmt); 
    $this->throwExceptionOnError(); 

    $rows = array(); 

    mysqli_stmt_bind_result($stmt, $row->ID, $row->fname, $row->lname, $row->sex, $row->country, $row->town, $row->dateofbirth, $row->monthofbirth, $row->yearofbirth); 

    while (mysqli_stmt_fetch($stmt)) { 
     $row->fname = ucfirst(substr($row->fname,0,1)); 
     $row->lname = ucfirst($row->lname); 
     $row->town = ucfirst($row->town); 
     $row->lname = (($row->fname) . " " . ($row->lname)); 
     $row->yearofbirth = GetAge($row->dateofbirth. '-' .$row->monthofbirth. '-' .$row->yearofbirth); 
     $row->Pic_loc = ""; 
     $row->Pic_loc= "IMAGES/".($row->ID)."/image01.jpg"; 
     $rows[] = $row; 
     $row = new stdClass(); 
     mysqli_stmt_bind_result($stmt, $row->ID, $row->fname, $row->lname, $row->sex, $row->country, $row->town, $row->dateofbirth, $row->monthofbirth, $row->yearofbirth); 
    } 

    mysqli_stmt_free_result($stmt); 
    mysqli_close($this->connection); 

    return $rows; 
} 

ISそれは私にはよさそうだけどどんな提案もうまくいきませんか?そのうめき声が

if($town != "NULL") { 
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND town LIKE ' .$town; 
} 
else 
{ 
     $WhereClause = 'town LIKE ' .$town; 
} 
}  

if($sex != "NULL") { 
if($WhereClause != "") 
{ 
      $WhereClause.= ' AND sex LIKE ' .$sex; 
} 
else 
{ 
     $WhereClause = 'sex LIKE ' .$sex; 
} 
}  

であることを はちょうどそれが本当に奇妙なことがあれば、他の条項3についてはうめき声ていないことが判明コードでポイント近い端子へのそれは最後の二つについて行います。あなたは、コードを簡素化し、

答えて

3

where句は次のようになります。

if($town != "NULL") { 
    if($WhereClause != "") 
    { 
       $WhereClause.= ' AND town LIKE "' .mysql_escape_string($town).'"'; 
    } 
    else 
    { 
      $WhereClause = 'town LIKE "' .mysql_escape_string($town).'"'; 
    } 
    }  

    if($sex != "NULL") { 
    if($WhereClause != "") 
    { 
       $WhereClause.= ' AND sex LIKE "' .$sex.'"'; 
    } 
    else 
    { 
      $WhereClause = ' sex LIKE "' .$sex.'"'; 
    } 
    } 

はところであなたが好き

+0

ワウは速く正しいですが、私はどんなエラーも出ませんでした:)感謝の仲間は私のテストが私が探していた結果を生み出すことを願っています:) – WhiteFinger

1

あなたの文字列は引用符で囲む必要があるSQLインジェクションからアプリケーションを保護するために、両方のプリペアドステートメント/ PDOを使用することができます

$WhereClause .= ' AND sex LIKE "' . mysql_escape_string($sex).'"'; 

+0

私はTeezに同意します最初の答えを与えた人が、エラーを解決してからもう一度エラーが発生するので、コードが私のIFを無視しているように見えて、変数がnullのまま続行することはできません。私はnullsを削除していたと思ったものはどこですか? – WhiteFinger

1

まず第一に、あなたはその場で文を構築しているチップ - デバッグに自分の価値観の周りにパーセント記号を使用する必要がshoud、および:句の変化下回っていますあなたがすぐに理解することはできませんSQLエラーを取得し、最初に行うことは、ビルドステートメントを印刷してください(そしてあなたの将来のSOの投稿にそれを含めてください)です。部分的に、それは次のようになりたい:あなたの値の前後に引用符をしていることがわかります、それから、

SELECT … lname LIKE wells AND sex LIKE female … 

不足している - それは次のようになります。だから、

SELECT … lname LIKE 'wells' AND sex LIKE 'female' … -- quoting non-numeric is NOT optional in SQL 

、これを実行するために取得するには、一重引用符を追加するだけで済みます。しかし、まだ2つの問題と潜在的な3番目の問題があります。

  1. これはまだ動作しません。私は部分文字列の一致を行いたいと考えている=の代わりにLIKEを使用すると仮定します。したがって、値の周りにパーセント記号を追加する必要があります:lname LIKE '%wells%'
  2. すでに準備済みのステートメントを使用しています。プレースホルダ(例:lname LIKE ?)を使用してクエリを作成してから、そのように記入するだけです。これはあなたのためにエスケープ処理を行い、SQLインジェクションを防ぎます。

潜在的な第3の問題は、LIKEを使用した部分文字列一致のパフォーマンスがひどいことです。そのタイプの一致はではなく、のインデックスを使用できます。あなたは完全なテーブルスキャンを行っています。本格的な検索ソリューション(Sphinx、fulltextなど)を使用すれば、これを解決できます(ただし、はるかに多くの作業を追加する可能性があります)。

+0

レスポンスのおかげでありがとう、私はすでに '%wells%'部分を使っていましたが、解決しようとしていたエラーのためにそれらを削除しました。この関数はすべての部分がnullではなく、変数が1つであれば精神的になります: – WhiteFinger