こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

ORACLEの無効な識別子ですのエラーについて

Oracle+Javaアプリケーション開発(ソフトバンクパブリッシング)に
載っているサンプルを実行しようとしているのですが、
下記実行結果により、エラーが出現して困っている次第です。
回答のほどよろしくお願い致します。
<エラー内容>
java.sql.SQLException: ORA-00904: "TIGER": 無効な識別子です。という例外が発生しました


<準備>
CREATE TABLE MANAGER
(
個人コード CHAR(10),
パスワード CHAR(10),
名前 VARCHAR2(40)
)
PCTFREE 10
MAXTRANS 255
TABLESPACE USERS
STORAGE(INITIAL 64K MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)
NOCACHE
LOGGING
/


1.
<LoginJSP1.jsp>でuseridとpasswordを設定しています
<form method="POST" name="login" action="/Sample/servlet/LoginSvlt2">
個人コード
<input type="text" name="userid" value="<%=userid%>"><br>
パスワード
<input type="password" name="password" value="<%=password%>"><br>

2.
<LoginSvlt2>
String userid = request.getParameter("userid");
String password = request.getParameter("password");
try{
connection = DriverManager.getConnection
//↓利用するデータベースの設定により変更を行う
("jdbc:oracle:thin:@localhost:1521:XE","scott","tiger");
Statement statement = connection.createStatement();
String query = "select EMPNO,PASSWORD,ENAME from EMP where ENPNO = " + userid + " and PASSWORD = " + password;

<objectbrowserで実行した結果>
ORA-01740 識別子に二重引用符がありません
select 個人コード,パスワード,名前 from MANAGER where 個人コード = " + userid + " and パスワード = " + password


以下のSQLを単体で実行するとうまくいきます。
select 個人コード,パスワード,名前 from MANAGER where 個人コード =1 and パスワード = 1

投稿日時 - 2009-03-24 07:23:11

QNo.4822606

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

> 切り分けのために以下のSQLを実行してみました。
> select 個人コード,パスワード,名前 from MANAGER where 個人コード = ' + 1 + '
> select 個人コード,パスワード,名前 from MANAGER where パスワード = ' + tiger+ ';

おそらくobjectbrowserで実行したのだと思いますが、これは[個人コード]が「 + 1 + 」のものを検索するSQLと[パスワード]が「 + tiger+ 」のものを検索するSQLになっています。[個人コード]が1のものを検索するSQLと[パスワード]が「tiger」のものを検索するSQLは下記の様になります。
--------------------------------------------------------------
SELECT 個人コード,パスワード,名前 FROM MANAGER WHERE 個人コード = 1;
SELECT 個人コード,パスワード,名前 FROM MANAGER WHERE パスワード = 'tiger';
--------------------------------------------------------------

Javaのソースコードで、
String query = "select ・・・ " + userid + " ・・・ " + password;
などとなっているのは、Javaがその部分で文字列連結演算子(+)によって文字列結合処理を行う様にするためです。
例えば、useridが「1」、passwordが「tiger」の時、
------------------------------------------------------------------
String query = "select EMPNO,PASSWORD,ENAME from EMP where ENPNO = " + userid + " and PASSWORD = '" + password + "'";
-------------------------------------------------------------------
の処理で、変数queryには
------------------------------------------------------------------
select EMPNO,PASSWORD,ENAME from EMP where ENPNO = 1 and PASSWORD = 'tiger'
-------------------------------------------------------------------
が格納されます。

> PostgresSQLの場合はデフォルトでMD5でパスワードは暗号化されてしまいますが、
> Oracleの場合はパスワードは暗号化されて保存されるのでしょうか?

PostgreSQLの場合のお話は、システムテーブル(pg_authid)に格納されるデータベースのアカウントのパスワードのことだと思います。
PostgreSQLでもOracleでも、通常のテーブルに「パスワード」「password」などというカラムを作っても、その中身が自動的に暗号化されることはありません。

投稿日時 - 2009-03-25 21:44:26

ANo.1

まずエラーの意味を確認してみましょう。
「ORA-00904」でWeb検索すると下記のページがヒットしました。
http://www.shift-the-oracle.com/oerrs/ora-00904.html

このページの2番目の原因に該当するかと。

> String query = "select EMPNO,PASSWORD,ENAME from EMP where ENPNO = " + userid + " and PASSWORD = " + password;

の部分ですが、仮にuseridに「11」、passwordに「TEST_PW」が入力されたとした場合、
「select EMPNO,PASSWORD,ENAME from EMP where ENPNO = 11 and PASSWORD = TEST_PW」
という文字列がqueryに設定され、それをSQLとして実行することになりますよね。

オラクルのSQLでは文字列型の値はシングルクウォート(')で囲まなければならないので、エラーが出ているのだと思います。
ですので、文字列型の値の部分をシングルクウォート(')で囲う様な文字列をJavaで生成すれば良いかと。
例) ---------------------------------------------------------------
String query = "select EMPNO,PASSWORD,ENAME from EMP where ENPNO = " + userid + " and PASSWORD = '" + password + "'";
-------------------------------------------------------------------

ちなみに objectbrowser で実行した場合は、
「select 個人コード,パスワード,名前 from MANAGER where 個人コード = " + userid + " and パスワード = " + password」
という文字列をそのままSQLとして実行しているので、エラーになっているのだと思います。
「" + userid + "」と「" + password」は、Javaのコードなので、objectbrowser で実行する場合にはその部分を人の手で置き換えてやる必要が有ります。
なので、「select 個人コード,パスワード,名前 from MANAGER where 個人コード =1 and パスワード = 1」はうまくいったのです。

蛇足ですが、このケースはサンプルなので問題無いのですが、実際のプロダクトコードなどでは、入力値をそのままSQLの中に組み込むことはSQLインジェクションの危険性があり、大変危険です。プレースフォルダを使用する、適切なエスケープ処理を行うなどの対策が必要となります。

投稿日時 - 2009-03-24 13:00:16

補足

root139さんご回答ありがとうございます。
いかのSQLでエラーは出なくなりましたが、問題があります。
select 個人コード,パスワード,名前 from MANAGER where 個人コード = ' + 1 + ' and パスワード = '" + tiger+ "'

切り分けのために以下のSQLを実行してみました。
select 個人コード,パスワード,名前 from MANAGER where 個人コード = ' + 1 + '
select 個人コード,パスワード,名前 from MANAGER where パスワード = ' + tiger+ ';

すべてのSQLでNULLが返ってきます。
データは個人コード=1、 パスワード=tiger、名前=scottと
登録しています。
設定しているSQLは以下です。
CREATE TABLE SCOTT.MANAGER
(
個人コード CHAR(10),
パスワード CHAR(10),
名前 VARCHAR2(40)
)
PCTFREE 10
MAXTRANS 255
TABLESPACE USERS
STORAGE(INITIAL 64K MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)
NOCACHE
LOGGING
/
PostgresSQLの場合はデフォルトでMD5でパスワードは暗号化されて
しまいますが、
Oracleの場合はパスワードは暗号化されて保存されるのでしょうか?

ご教授よろしくおねがいします。

投稿日時 - 2009-03-25 21:01:03

あなたにオススメの質問