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

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

新規登録して質問してみよう
ただいま回答率
85.50%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

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

Q&A

3回答

3778閲覧

Linux上のPHP7.0から SQLServer接続した際に、odbc_Prepareでパラメーターが使えない

hako2006084

総合スコア8

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

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

0グッド

0クリップ

投稿2016/10/03 00:14

編集2022/01/12 10:55

###前提・実現したいこと
<実現したいこと>
Linux(CentOS)上のPHP7.0 からMicrosoft SQLServer2012 上に接続して
データを取得したい。
(Prepareでパラメーターを使えない)

<環境>
CentOS 7.2
Apache 2.4.6
PHP 7.0.6

ODBC環境は以下をインストール
unixODBC 2.3.1
freetds 0.95

PHPのODBCドライバは以下
php70-php-odbc

ここからインストール
yum --enablerepo=remi install php70-php-odbc

###発生している問題・エラーメッセージ

odbc_prepareを使用して、パラメーターなしのSQLは実行できたが
where句にパラメーターを入れると
statementがそもそも取得できない

###該当のソースコード

<実行できるコード>
$sql = " SELECT * FROM usrtable WHERE column1 = 'XXXX' AND column2 = 'YYYY'";

$stmt = odbc_prepare($this->conn, $sql);
var_dump($stmt);
$result = odbc_execute($stmt,$param);
var_dump($result);
$row = odbc_fetch_array($stmt);

print_r($row,true);

<実行できないコード1>
$sql = " SELECT * FROM usrtable WHERE column1 =? AND column2 =?";
$param = array('XXXX','YYYY');

$stmt = odbc_prepare($this->conn, $sql);
var_dump($stmt);
$result = odbc_execute($stmt,$param);
var_dump($result);
$row = odbc_fetch_array($stmt);

print_r($row,true);

<実行できないコード2>
$sql = " SELECT * FROM usrtable WHERE column1 =:col1 AND column2 = :col2";
$param = array('col1' => 'XXXX',col2 => 'YYYY');

$stmt = odbc_prepare($this->conn, $sql);
var_dump($stmt);
$result = odbc_execute($stmt,$param);
var_dump($result);
$row = odbc_fetch_array($stmt);

print_r($row,true);

###試したこと
・パラメーターなしのprepareは実行され、データが取得できた。

・実行できないコード1のように?のパラメーターに対し、配列を順序で生成した場合はそもそも$stmtのvar_dumpでfalseになってしまう。

・実行できないコード2のように連想配列にした場合は、$stmtは取得できるが
次のexecuteでfalseになってしまう。

###補足情報(言語/FW/ツール等のバージョンなど)

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

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

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

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

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

guest

回答3

0

<実行できないコード1>と似たようなコードを手元の環境(Windows+PHP5+SQL Server 2012)で実行してみましたが、問題なく動作しました。
ご提示の環境とは異なりますが一応動きましたので、コードに問題は無いのでは?と考えています。

php

1// <実行できないコード1> 2$sql = " SELECT * FROM usrtable WHERE column1 =? AND column2 =?"; 3$param = array('XXXX','YYYY'); 4 5$stmt = odbc_prepare($this->conn, $sql);

$stmtfalseになるということはodbc_prepareに失敗していると思いますが、このときどのようなエラーが出ているか、提示することはできませんか?

投稿2016/10/04 06:22

alg

総合スコア2019

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

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

hako2006084

2016/10/04 11:14

>algさん ご回答ありがとうございます。 $stmt = odbc_prepare($this->conn, $sql); var_dump(odbc_errormsg($this->conn)); を試しました。 [unixODBC][Driver Manager]Driver does not support this function こんなエラーでましたが、この後の文字が文字化けしてよくわからない状況でした。 UNIX_ODBCドライバーのバージョンが悪いのでしょうか ちなみにインストールはyumで行ってます。 実行したコマンド yum -y install unixODBC-devel freetds-devel
guest

0

odbc_execute()の関数リファレンスをご確認ください。

PHP

1bool odbc_execute ( resource $result_id [, array $parameters_array ] )

関数リファレンスには、

parameter_array の中でシングルクォートで括られたデータがある場合、 それはファイル名と解釈されます。そのファイルの内容が、 該当するプレースホルダのデータとしてデータベースサーバーに送信されます。

シングルクォートで括られたデータを純粋に文字列として使用したい場合は、 空白などの別の文字を前後に付加する必要があります。 それにより、パラメータがファイル名とみなされることがなくなります (もしこのオプションが不要なら、別の仕組み、たとえば odbc_exec() で直接クエリを実行するなどを使用する必要があります)。

とあります。
あとちょっと気になるのは
$sql = " SELECT * FROM usrtable WHERE column1 = 'XXXX' AND column2 = 'YYYY'
とありますが、行末はダブルクオートとセミコロンちゃんとついてますよね?

投稿2016/10/03 00:33

imutakaoru

総合スコア356

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

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

hako2006084

2016/10/03 09:34

ご回答ありがとうございます。 まず、ソースご指摘ありがとうございました。投稿時のミスです。修正致しました。 リファレンスに沿って、以下試したましたがだめでした。 ●試したソース1 $sql = " SELECT * FROM usrtable WHERE column1 =? AND column2 =?"; $param = array("XXXX","YYYY"); $stmt = odbc_prepare($this->conn, $sql); var_dump($stmt); $result = odbc_execute($stmt,$param); var_dump($result); $row = odbc_fetch_array($stmt); $stmtがfalseとなりダメでした。param関係ないですね(泣) 次に以下を実行 ●試したソース2 $sql = " SELECT * FROM usrtable WHERE column1 ='?' AND column2 ='?' "; $param = array('XXXX','YYYY'); プレースホルダをシングルクウォートで囲いました。 これは $stms も true $result も true でうまくいったと思ったのですが $row = odbc_fetch_array($stmt); print_r($row,true); 最後のfetchができず。。orz ●試したソース3(連想配列プレースホルダ) $sql = " SELECT * FROM usrtable WHERE column1 =:col1 AND column2 = :col2"; $param = array("col1" => "XXXX","col2" => "YYYY"); $stmt = odbc_prepare($this->conn, $sql); var_dump($stmt); $result = odbc_execute($stmt,$param); var_dump($result); $row = odbc_fetch_array($stmt); print_r($row,true); ---------------- $param内のシングルクォートをダブルに変更 結果はやはり $resultがfalseでうまく動きません。
goute

2016/10/03 11:10

=と?の間にスペースを入れてもダメですかね。
hako2006084

2016/10/03 11:19

>gouteさん それも試しましたがだめでした。
imutakaoru

2016/10/04 01:17

試していないパターンがあるような。 $sql = " SELECT * FROM usrtable WHERE column1 ='?' AND column2 ='?' "; と、プレースホルダをシングルクオートで囲む。 $param = array("XXXX","YYYY"); パラメータで渡す配列はダブルクオートで囲む。 あるいは $x="XXXX"; $y="YYYY"; として、 $result = odbc_execute($stmt,array($x,$y)); としてみるとか。
hako2006084

2016/10/04 02:46 編集

>imutakaoruさん ご回答ありがとうございます。 両方のパターン試しましたが $row = odbc_fetch_array($stmt); で$rowが取れないです。 $stmt,$resultまではtrueで返ってくるのですが。。。 PHPODBCドライバのバグなのでしょうか?(TωT) バージョン的には新しめではあるので。 実装箇所はSQLインジェクションの心配はない箇所ではあるので prepareをやめてしまおうか悩み中です。
guest

0

こうしてみるとどうですか。

php

1$param = array("'XXXX'","'YYYY'");

投稿2016/10/03 00:32

fromageblanc

総合スコア2724

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

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

hako2006084

2016/10/03 09:15

ご回答ありがとうございます。 $param = array("'XXXX'","'YYYY'"); でもだめでした。 $sql = " SELECT * FROM usrtable WHERE column1 =? AND column2 =?"; $param = array('XXXX','YYYY'); $stmt = odbc_prepare($this->conn, $sql); この書き方の場合、ここの時点で$stmtがfalseになるので ?の指定がだめそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問