質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1126閲覧

Windows server上にあるPHPのWebアプリからあいまい検索ができない

sanpei

総合スコア15

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/04/05 02:35

編集2018/04/05 09:22

データベースにある製品情報をWEBブラウザで閲覧するアプリをPHPで作成しております。
製品の名前を検索できるページがあるのですが、
ローカルの開発環境では問題なくSQLのLIKE句によるあいまい検索ができるのですが、
Windows Server上にアップすると、
全文一致はできますが、あいまい検索ができなくなり、結果が取得できません。

いろいろ調べたのですが、解決できず、
ぜひともお力添えをいただければ幸いです。


PHPバージョン:7

データベースの場所
サーバーA
・Windows Server 2008 SP2
・IIS 6
・SQL server 12

◎あいまい検索ができる環境
ローカルの開発環境
・Windows10
・IIS 10

×あいまい検索ができない環境(※全文一致は可能)
サーバーB
・Windows Server 2008 SP2
・IIS 6

ともにローカルからChromeでアクセスしています。

HTMLは下記のようにしており

HTML

1<div class="nameArea"> 2 <label>製品名</label> 3  <input type="text" id="name"> 4</div> 5 6<button type="button" class="sendFrom">検索</button>

SQLは下記のように発行しております。

PHP

1$sql = <<<SQL 2SELECT 3 NAME 4FROM 56WHERE 7 NAME LIKE ? 8SQL; 9 10 $stmt = $dbh->prepare($sql ); 11 $stmt->execute(array(sprintf('%%%s%%', addcslashes($name, '\_%'))));

検証

あいまい検索ができないサーバーBに対して下記の検証を行いました。

製品名:ホゲのパソコン

値をスタティックにした場合

$stmt = $dbh->prepare($sql ); stmt->execute(["%ホゲの%"]);

結果が返ってこず。

プレースホルダを止め、SQL文に直接値を記述

$sql = <<<SQL SELECT NAME FROM ~ WHERE NAME LIKE %ホゲの% SQL; $stmt = $dbh->query($sql );

返ってきました。

プレースホルダへの値の入れ方が悪いのでしょうか…。

全文一致は問題ないので、
ワイルドカード「%」が入ると、サーバーBで何かが起こる…?

あいまい検索ができるローカル環境と、
できないサーバーBの違いといえば、
OS(Windows10 or Windows server 2008)
IISのバージョン(10 or 6)なのですが…

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/04/05 02:40

実際に実行されたSQLを確認してみては?addcslashes()の結果が気になります。
退会済みユーザー

退会済みユーザー

2018/04/05 03:01

SQLSERVERだろうけどバージョンは?
sanpei

2018/04/05 03:07

SQL serverのバージョンは12です
退会済みユーザー

退会済みユーザー

2018/04/05 03:11

質問に追記でサーバーとローカルの両方に書いてね
sanpei

2018/04/05 03:13

mts10806様、ありがとうございます。プレースホルダが反映されたSQL文の確認方法を調べたのですが分からず…。addcslashes()はエスケープされた文字を返す関数と知りました。これから使い方調べながら調査してみます!
sanpei

2018/04/05 03:21

asahina1979様、失礼いたしました。質問内容に追記いたしました。
m.ts10806

2018/04/05 05:29

そういえば、プレースホルダ ってエスケープしてくれてるはずなのでaddcslashes()は不要に思います。
guest

回答2

0

自己解決

自己解決いたしました。

ODBCドライバのバージョンアップで改善しました。

まずSQL Server ProfilerでローカルとサーバーBからのSQLをトレースしてみると、
サーバーBからのSQLの場合だけ下記の表示が出ていました。

select 504,c.name,c.description,c.definition from master.dbo.syscharsets c where c.id = convert(tinyint, databasepropertyex ( db_name() , 'sqlcharset'))

検索すると、下記ページにたどり着き、ODBCが怪しい?

  • stackoverflow

QODBCResult :: exec:ステートメントを実行できません:
"[Microsoft] [ODBC SQL Server Driver] COUNTフィールドが正しくないか構文エラー

ODBC経由でSQLサーバーに接続しているのですが、

  • ローカル環境:SQL Server Native Client 11
  • サーバーB:SQL Server Native Client 10

とドライバのバージョンが異なっていることに気づき、
サーバーBのSQL Server Native Clientのバージョンを11にすると解決いたしました。

投稿2018/04/20 07:14

sanpei

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ステートメントのインスタンスが
$stmtと$stmt2を併用しているのは意味がありますか?
そのままではエラーになるでしょうし最低でも同じSQLのセッションで
処理はされないと思いますが

追記

見る限り問題なさそうです

PHP

1$name="hoge"; 2print_r(array(sprintf('%%%s%%', addcslashes($name, '\_%')))); 3//出力:Array ( [0] => %hoge% )

一つは

PHP

1$stmt = $dbh->prepare($sql ); 2stmt->execute(["%hoge%"]);

のようにスタティックに値をいれて検証してみること

それでもだめなら

PHP

1$sql="SELECT * FROM ... WHERE NAME LIKE '%hoge%'"; 2$stmt = $dbh->query($sql );

で、検証してみることです。

投稿2018/04/05 02:50

編集2018/04/05 03:49
yambejp

総合スコア114784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanpei

2018/04/05 02:55

すいません、実際のコードから転記する際の記述ミスです。 質問内容を修正いたしました。 $stmt2 ↓ $stmt
sanpei

2018/04/05 05:29

ご返答ありがとうございます。 検証させていただき、結果を質問内容に追記いたしました。 プレースホルダを使用して値をバインドさせると、サーバーBではあいまい検索ができないようです。 SQLに直接値を入れるとサーバーBでもあいまい検索ができました。
yambejp

2018/04/05 05:41

stmt->execute(["%ホゲの%"]); だとどうでしょうか?
sanpei

2018/04/05 08:15

また記述ミス…大変失礼しました。 質問内容を修正しました。 stmt->execute(["%ホゲの%"]); で検証しましたが駄目でした…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問