🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

4回答

2478閲覧

PHPからOracleへの接続について

y-i_a

総合スコア12

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2019/11/06 01:11

編集2019/11/07 06:08

前提・実現したいこと

社内で VB.NET で作られたシステムを使用しており、
データベースは Oracle を使用しています。
今回 Windows を使用していない部署でもデータの検索などができるよう、
php で新しいシステムを作ることになりました。

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

Oracle への接続時やSQL実行時にエラーは出ないのですが、
select すると false が返ってきてしまいます。
※vb.net の方で該当のデータが存在するのは確認済み

該当のソースコード

php

1 try { 2 $dsn = 'oci:dbname=//IPアドレス:1521/データベース'; 3 $options = [ 4 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 5 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC 6 ]; 7 $link = new PDO($dsn, 'ユーザー名', 'パスワード', $options); 8 $sql = "SELECT * FROM テーブル名 WHERE 'コード' = :code"; 9 $stmt = $link->prepare($sql); 10 $stmt->bindValue(':code', 100); 11 $stmt->execute(); 12 $rows = $stmt->fetch(); 13 if($rows !== false) { 14 var_dump($rows); 15 } else { 16 echo '取得失敗'; 17 } 18 } catch(PDOException $e) { 19 header('Content-Type: text/plain; charset=UTF-8', true, 500); 20 echo 'エラー:'.$e->getMessage().PHP_EOL; 21 exit(); 22 }

試したこと

上記ソースはユーザーからの入力を想定しているため
プリペアドステートメントを使用していますが、
テスト的に PDO::query メソッドを使用して select を実行してみましたが、
false が返って来ました。

11/7追記
一番データ量の少ないテーブルで「SELECT * FROM テーブル名」を実行してみたところ値が帰って来ました。
しかし、日本語のカラム名が含まれると false が返ってくるようになります。

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

環境は
Windows 2008 R2
IIS 7.5
php 7.3
Oracle 11g
になります。

よろしくお願いいたします。

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

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

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

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

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

m.ts10806

2019/11/06 01:21

同じSQLを直接DBに対して実行した場合はどうでしょうか fetchAll()にするとどうなりますか?
FKM

2019/11/06 01:24

プレースホルダを使わずにselect文だけを実行しても、同様のエラーが発生しますか?
y-i_a

2019/11/06 01:30

m.ts10806 さん > 同じSQLを直接DBに対して実行した場合はどうでしょうか 私の環境では直接DBに対して実行することができないため、 他の人に試してみてもらいます。 >fetchAll()にするとどうなりますか? array(0) { } が返ってきました。 FKM さん >プレースホルダを使わずにselect文だけを実行しても、同様のエラーが発生しますか? PDO::query メソッドを使用して select を実行してみましたがfalse が返って来ました
FKM

2019/11/06 01:44

var_dump($stmt)とするとどうなっていますか?
y-i_a

2019/11/06 01:55

FKM さん >var_dump($stmt)とするとどうなっていますか? object(PDOStatement)#2 (1) { ["queryString"]=> string(46) "SELECT * FROM テーブル名 WHERE コード = :code" } となります。
guest

回答4

0

自己解決

PDO_OCI の設定周りについて調べてみたところ、
環境変数に
NLS_LANG=Japanese_Japan.AL32UTF8
を設定するという情報を見つけ試したところ
日本語を含んだ SQL でも値が返ってくるようになりました。

ご回答いただいたみなさん、ありがとうございました。

投稿2019/11/07 08:58

y-i_a

総合スコア12

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

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

0

日本語を含むSQL文だと false が返ってきます。

これはとても重要な情報なので質問に記載しましょう。
というか例示するときにわかりやすいように記載しましょう。

項目名やテーブル名などに日本語を使うと邪魔くさいことがいっぱいあるので
可能な限り日本語は使わないようにしましょう。

日本語の部分を引用識別子(")で囲みましょう。
※文字コード関連の整合性は取れていることが前提です。

SQL

1SELECT * FROM テーブル名 WHERE "コード" = :code

投稿2019/11/07 05:55

Y.H.

総合スコア7918

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

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

y-i_a

2019/11/07 06:06

>これはとても重要な情報なので質問に記載しましょう。 先程質問の「試したこと」に追記しました。 >項目名やテーブル名などに日本語を使うと邪魔くさいことがいっぱいあるので可能な限り日本語は使わないようにしましょう。 VB.NET のシステムを作った人がデータベースも設計したので・・・ 私個人としては項目名に日本語は使わない派です。 >日本語の部分を引用識別子(")で囲みましょう。 ちょうど試していたのですが、 OCIStmtExecute: ORA-01722 のエラーが出ます。
Y.H.

2019/11/07 06:09

> OCIStmtExecute: ORA-01722 エラーメッセージはこれだけですか?どの項目とか情報はありませんか? というやり取りが発生し時間がかかるだけなので、エラーメッセージは全文記載しましょう。
y-i_a

2019/11/07 06:13

>エラーメッセージは全文記載しましょう。 失礼しました、エラー文は下記で全部です。 SQLSTATE[HY000]: General error: 1722 OCIStmtExecute: ORA-01722: ???????? (ext\pdo_oci\oci_statement.c:157) >※文字コード関連の整合性は取れていることが前提です。 試しに文字コードを指定してみたところ SQLSTATE[HY000]: General error: 1756 OCIStmtPrepare: ORA-01756: quoted string not properly terminated (ext\pdo_oci\oci_driver.c:288) のエラーが出ました。
Y.H.

2019/11/07 07:16

DBの文字コードもphpの文字コード設定群の設定もどう設定されているのか、試しに文字コードを何処でどのように指定されたのか、私には分からないのでお手伝いできるのはここまでのようです。 もし何か原因や解決方法を思いついたら回答に追記します。
FKM

2019/11/07 08:42 編集

ORA1722は型が無効、ORA1756は引用符付き文字列の終了がおかしいというエラーです。 そして、このDBにおけるSQL文はあくまでPHPで処理している以上、SQLは文字列となります。 ですのでダブルクォートを使用する場合はエスケープが必要です。 したがってシングルクォートで囲むことで、エスケープ処理を省略させる記法で記述するか、 ``` $sql = 'SELECT * FROM テーブル名 WHERE "コード" = :code'; ``` あるいはエスケープ処理を行ってダブルクォートで文字列を囲む方法で記述します。 ``` $sql = "SELECT * FROM テーブル名 WHERE \"コード\" = :code"; ``` こうしないとPHPのルールにもカラムにバイト文字を使う場合はダブルクォートで囲むというOracleのルールにも違反してしまいます。 なお、シングルクォートで用いる場合はq演算子を使えばいけるみたいですが、PDOでも対応しているかはわかりません。 ● [ Oracle ] q 演算子 シングルクォーテーションを文字として扱うhttp://hensa40.cutegirl.jp/archives/1169
y-i_a

2019/11/07 09:01

Y.H. さん FKM さん 自己解決に記載したのですが、私の設定抜けが問題だったようです。 色々とご回答いただきありがとうございました。
FKM

2019/11/07 09:03

自分も勉強になりました。気になる点が一点、 文字バイトのカラム(行)の指定はシングルクォートでも通ったってことでしょうか?
y-i_a

2019/11/07 09:10 編集

>文字バイトのカラム(行)の指定はシングルクォートでも通ったってことでしょうか? いえ、シングルクォートで囲むと SQLSTATE[HY000]: General error: 1722 OCIStmtExecute: ORA-01722: 数値が無効です。 (ext\pdo_oci\oci_statement.c:157) が返ってきてしまうため、 SELECT * FROM INOPLATE WHERE コード = :code の状態で実行しています。
FKM

2019/11/07 09:15

そうなんですね、クォートを囲まなくても通るのは初めて知りました。 なお、シングルクォートやダブルクォートを使いたい場合は上記の通りでいけるはずです。 参考までに。
y-i_a

2019/11/07 09:27

>クォートを囲まなくても通るのは初めて知りました。 もしかすると Oracle 側の設定が関係しているかもしれません。 (oracle の設定は自分が行ってないので詳細はわかりません) >なお、シングルクォートやダブルクォートを使いたい場合は上記の通りでいけるはずです。 ありがとうございます。
guest

0

PDOはデフォルト設定だと、エラーを持っていても素通りしてしまうので、より厳格に調べた方がいいかも知れないですね。

上の人と同じように、
$err = $link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
として
var_dump($err);
でもっと詳細を確認してみると、なにか別のエラーが見えていないでしょうか。

●参考サイト
PDOはデフォルトではエラー出力をしないです

投稿2019/11/06 09:43

FKM

総合スコア3647

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

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

y-i_a

2019/11/06 09:46

やってみましたが結果は変わりませんでした。
FKM

2019/11/06 10:07

そもそもPDOにOracleは対応していますでしょうか echo phpinfo(); でPDOの項目にOracleがあるか確認してみてください。
y-i_a

2019/11/07 05:21

phpinfo()の項目に「oci」があるのは確認済みです。
FKM

2019/11/07 08:36

他の方の情報をヒントに、思い当たる部分があったので、その方のレスに追記しています。 where文以降が通らないことと、カラム名をシングルクォートで囲んでいるのが気になりました。
guest

0

おす!

PHP

1$link = new PDO($dsn, 'ユーザー名', 'パスワード', $options); 2$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

ってやったら、何かException投げてくれねぇか?

投稿2019/11/06 02:27

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

y-i_a

2019/11/06 09:46

やってみましたが結果は変わりませんでした。
退会済みユーザー

退会済みユーザー

2019/11/06 10:05

わりぃわりぃ、 $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; してあったんだな。 そしたら、`コード`フィールドの型をスキーマ通りに明示してみたら何か変わるんじゃねぇか? 例えばよぅ、 $stmt->bindValue(':code', 100, PDO::PARAM_STR); みてぇに。
FKM

2019/11/06 10:08 編集

where文を使用しないでテストしてみるように質問に投げた結果でも変わらないので、そもそもの問題の気がする…
y-i_a

2019/11/07 05:40

FKM さん >where文を使用しないでテストしてみるように質問に投げた結果でも変わらないので 上記内容の質問が見つかりませんでしたが、 「SELECT * FROM テーブル名」 で実行したところ値が帰って来ました。 しかし、 「SELECT * FROM テーブル名 WHERE コード = :code」 の様に日本語を含むSQL文だと false が返ってきます。 ※テーブル名は英字です
y-i_a

2019/11/07 05:43

goku59 さん >$stmt->bindValue(':code', 100, PDO::PARAM_STR); 試してみましたが結果は変わりませんでした。
y-i_a

2019/11/07 09:02

goku59 さん 自己解決に記載したのですが、私の設定抜けが問題だったようです。 色々とご回答いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問