• 締切済み
  • すぐに回答を!

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

共感・応援の気持ちを伝えよう!

  • 回答数2
  • 閲覧数18553
  • ありがとう数0

みんなの回答

  • 回答No.2
  • root139
  • ベストアンサー率60% (488/809)

> 切り分けのために以下の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」などというカラムを作っても、その中身が自動的に暗号化されることはありません。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • MySQLとJavaでのコードについて。

    JavaBeanを使って、MySQLにデータを追加したいのですが、それがなかなかうまくいかず質問してます。 Statement statement = connection.createStatement(); String sql_str ="INSERT INTO customer VALUES(\"" +name+"','"+email+"','"+password+"\")"; int r=statement.executeUpdate(sql_str); このコードはjavaBeanのなかに入っており、name,email,passwordはjspからjavabeanに送られてきます。多分、VALUESの後のname,emai,passwordを入れるのに”’などの使い方が間違ってると思います。本には載ってなかったので、ウェッブ検索してみよう見真似でやったので、”’の使い方を把握してません。誰か分かる方回答お願いします。 あとこれとは違うmethodにSELECT文を使った時、 String sql_str = "SELECT email, password FROM customer where email='"+email+"'AND password='"+password+"'"; ResultSet rs = stmt.executeQuery(sql_str);とやったときは動きました。最初はこれと同じようにINSERT 文も書いたのですが、動かなかったんですよね。

    • ベストアンサー
    • Java
  • エラー「無効な識別子です」

    ORA-00904: "EMPNO": 無効な識別子です と表示されます。 解決方法知っている方、教えていただければ幸いです。 SELECT EMPNO, ENAME, D.DEPTNO, DNAME FROM DEPT D WHERE EMPNO = (SELECT EMPNO FROM EMP WHERE MGR IS NULL) SQL> DESCRIBE EMP; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2)

  • ORA-00904:無効な識別子の回避策について

    ■やりたいこと フェッチして取得したデータを条件にカウントした結果を取得したい。 ■事象 フェッチして取得したデータにダブルクウォートで囲まれている為、EXECUTE時にORA-00904が発生する。 ■教えて欲しいこと カーソルおよびフェッチ時にダブルクウォートを削除、またはシングルクウォートに変換をすることが可能でしょうか。または、他の方法でカウントを取得する方法がございますでしょうか。 サンプルコードを記載しておりますのでご確認、ご教授のほどよろしくお願いします。 ※※※の箇所が本事象発生箇所となります。 ■サンプルコード DECLARE V_EXEC_STRING VARCHAR2(2000); V_EXEC_COUNT NUMBER; CURSOR TESTCUR IS SELECT TEST_NAME,TEST_ID,TEST_DATE FROM TARGET_TBL WHERE TEST_NAME IN (SELECT tb1.TEST_NAME FROM (SELECT TEST_NAME FROM TARGET_TBL WHERE STATUS = '2') tb1 INNER JOIN READ_TBL tb2 ON(tb1.TEST_NAME = tb2.TEST_NAME)); --取得レコードを格納する変数定義 TESTREC TESTCUR%ROWTYPE; --処理開始 BEGIN --カーソルオープン OPEN TESTCUR; --ループ開始 LOOP --フェッチ 1行ずつデータ取得 FETCH TESTCUR INTO TESTREC; --レコードの最後でループを終了 EXIT WHEN TESTCUR%NOTFOUND; V_EXEC_STRING := ''; V_EXEC_STRING := V_EXEC_STRING || 'SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = '|| TESTREC.TEST_NAME; ※※※上記TESTREC.TEST_NAMEに"AAAA"の形でデータが入るため、下記実行時にORAエラーが発生する。 EXECUTE IMMEDIATE V_EXEC_STRING INTO V_EXEC_COUNT; IF V_EXEC_COUNT = '1' THEN UPDATE TARGET_TBL SET TEST_ID = ( SELECT TEST_ID FROM READ_TBL WHERE TEST_NAME = TESTREC.TEST_NAME), TEST_DATE = ( SELECT TEST_DATE FROM READ_TBL WHERE TEST_NAME = TESTREC.TEST_NAME), STATUS = 10 WHERE TEST_NAME = TESTREC.TEST_NAME; END IF; IF V_EXEC_COUNT != '1' THEN UPDATE TARGET_TBL SET STATUS = 20 WHERE TEST_NAME = TESTREC.TEST_NAME; END IF; END LOOP; CLOSE TESTCUR; COMMIT; END; /

  • 回答No.1
  • root139
  • ベストアンサー率60% (488/809)

まずエラーの意味を確認してみましょう。 「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インジェクションの危険性があり、大変危険です。プレースフォルダを使用する、適切なエスケープ処理を行うなどの対策が必要となります。

共感・感謝の気持ちを伝えよう!

質問者からの補足

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の場合はパスワードは暗号化されて保存されるのでしょうか? ご教授よろしくおねがいします。

関連するQ&A

  • jspのプログラムについて

    jspについて質問です。 現在入力されたパスワードとデータベースに保存してあるパスワードを比較して一緒であれば idを削除するというプログラムを組んでいます。 削除することはできないのですが、 比較がうまくいきません。 <% //postされたもの String id = request.getParameter("id"); String password =request.getParameter("password") Class.forName("com.mysql.jdbc.Driver"); Connection conn=DriverManager.getConnection(urlやpassword、userが書いてある); request.setCharacterEncoding("utf8"); Statement st=conn.createStatement(); Statement stmt=conn.createStatement(); ResultSet res = st.executeQuery("select * from data where id ="+id); while(res.next()){ String pass =res.getString("pass"); //データベースからパスワードを取得 out.println("<td>" + password + "</td>"); out.println("<td>" + pass + "</td>"); if(password==pass){ //入力されたパスワードと比較 //ここにはidを削除する文が書かれている } } st.close(); conn.close(); やっているのですが、if文に入って削除してくれません。 out.printlnはいりませんがちゃんと値があっているか確かめたところ 入力された文字とデータベースに入っている文字がちゃんと表示されました。 教えてください。よろしくお願いします。

  • エラー2「無効な識別子です」

    ORA-00904: "D"."DEPT": 無効な識別子です。 先ほども似たような質問をしましたが原因がよく分からないなのでご存知の方教えていただければ幸いです。 SELECT D.DEPTNO, E.ENAME, E.SAL FROM EMP E, DEPT D WHERE E.SAL >ANY (SELECT MAX(E.SAL) FROM DEPT D, EMP E GROUP BY D.DEPT) SQL> DESCRIBE EMP; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2) SQL> DESCRIBE DEPT; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13)

  • SQLインジェクション

    教えてください。 よろしくお願いいたします。 SELECT * FROM table WHERE user='$uid' AND password='$pass' のエスケープ処理をしていない場合に、 ID=aaa パスワード='or'a'='a と入力されると、 SELECT * FROM table WHERE user='aaa' AND password="or 'a'='a' が実行されてしまいますが、 「password=」と「or」の間のダブルクォーティションは、 どのような意味を持つのでしょうか。

  • ExcelでBookを開くPasswordにエラーを出さないには

    Sub Dim FileName As String FileName = "D:\集計表.xls" Dim Sheet_Name As String Dim Book_Name As String Workbooks.Open FileName:=FileName Sheet_Name = "Sheet1" Book_Name = ActiveWorkbook.Name Workbooks(Book_Name).Sheets(Sheet_Name).Select Range("A1").Select End Sub 上記の構文でBookを開く時に「Password」を要求して開くようにしています。 ただ、Passwordを間違えた時は「実行時エラー1004」とな、「デバック」するか「終了」するしかありません。 デバック」・「終了」をせずに再度Password入力に戻るにはどの様にすれば良いでしょうか。

  • Perl上でのMySQL文について

    ユーザー名とパスワードを入力してもらい、パスワードが一致していればOK、違っていればNGがでてくるプログラムを作りました。 if ( $password eq &sub_db( "SELECT password FROM login WHERE user LIKE '" . $user . "'") ) { print "OK!"; } else { print "NG!"; } ちなみに &sub_db というのはSQL文を実行するだけのサブルーチンです。 想定通りに動きましたが、SQL文の "SELECT password FROM login WHERE user LIKE '" . $user . "'" の '" . $user . "'" なんですが、最初はこうしてました "SELECT password FROM login WHERE user LIKE $user" これだと動きませんでした。多分シングルコーテーションで囲まなければいけない決まりがあるんだと思います。変数を文字列比較するときはこうしなければいけないのでしょうか?

    • ベストアンサー
    • Perl
  • javaの掲示板について

    サーブレットの削除機能の抜粋なのですが public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { MessageDao dao = new MessageDao(); String sendMessage = request.getParameter("sendMessage"); String deleteMessage = request.getParameter("deleteMessage"); //削除 if(deleteMessage != null){ String sql = "SELECT * FROM MESSAGE_TABLE where ID ="; String rsPassword = request.getParameter("rsPassword"); String deleteid = request.getParameter("id"); String deletepassword = request.getParameter("deletepassword"); if (deletepassword.equals(sql) || deleteid.equals(sql)){ dao.deleteMessage(delete); success = "削除しました。"; request.setAttribute("success", success); } if (!deletepassword.equals(sql) || deleteid.equals(sql)){ errorpass = "パスワードが違います。"; request.setAttribute("errorpass", errorpass); } } ------------------------------------------------------------------------------------ jsp部分 <input type="deletepassword" size="20"> <input type="hidden" name="id" value="<%= message.getId() %>"> <input type="hidden" name="rsPassword" value="<%= message.getPassword() %>"> <input type="submit" name="deleteMessage" value="削除"> それぞれをこの様な書き方で記述した場合、削除ボタンを押された際に削除フォームに入力されたパスワードとidをデータベース内に格納されているパスワードとidと比較して削除、もしくはエラーという様にできているでしょうか?できていなければ変更点の御指摘をお願いします。 ------------------------------------------------------------------------------------ <% String errorpass = (String)request.getAttribute("errorpass"); if(errorpass != null){ out.println(errorpass); } %> またjspの表示部分を上記のようにしているのですが、out.printlnを使わないで記述する場合どのように書けばよいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • 複雑なcountについて

    val | num ----------- 9984 | 1 1234 | 1 9876 | 1 4567 | 1 9984 | 1 1234 | 1 9984 | 1 以上のようなテーブルで SELECT COUNT(*) FROM table_name WHERE val = 9984 SELECT COUNT(*) FROM table_name WHERE val = 1234 SELECT COUNT(*) FROM table_name WHERE val = 9876 SELECT COUNT(*) FROM table_name WHERE val = 4567 のように4つ実行することなく1度に 9984 => 3 1234 => 2 9876 => 1 4567 => 1 という結果を得たいのですが方法はありますでしょうか? ご教示お願いいたします。

  • JDBCを使ってdate型へのINSERTはできますか?

    JDBCを使ってOracleへ接続し、DBへデータを挿入したいのですが、 日付型のデータがどうしてもうまく挿入できません。 jsp + Servlet + Bean で開発しています。 使っているテーブルは CREATE TABLE USERS (     USERID     VARCHAR2(10) NOT NULL,     PASSWORD  VARCHAR2(10) NOT NULL,     NAME      VARCHAR2(50) NULL,     SEX       VARCHAR2(5)  NULL,     BIRTHDAY   DATE       NULL,     PRIMARY KEY (USERID, PASSWORD) ) という風な型で、定義しています。 DBへのINSERT処理は、Beanで行っています。 以下のINSERT文を実行したのですが、うまくINSERTできませんでした。 String sqlQuery = "INSERT INTO USERS (USERID, PASSWORD, NAME, SEX, BIRTHDAY)" + "VALUES ('use', 'pass', 'ナマエ', '女性', '1980/06/05')" int numOfUpdate = statement.executeUpdate(sqlQuery); ちなみに、この中のdate型で定義している「BIRTHDAY」を除いたINSERT文 String sqlQuery = "INSERT INTO USERS (USERID, PASSWORD, NAME, SEX)" + "VALUES ('use', 'pass', 'ナマエ', '女性')" int numOfUpdate = statement.executeUpdate(sqlQuery); だとうまくINSERTできます。 sql*plusを使って直に書くと、両方うまくINSERTできました。 ●その後に、「BIRTHDAY」をdate型からVARCHAR2(10)へ定義し直し、  DBを作り直して実行した所、うまくINSERTできるようになりました。 なぜ「date型」だとINSERTできず、「VARCHAR2型」だとINSERTできるのか、 知っている方がおられましたら、ぜひ教えて頂きたいです。

    • ベストアンサー
    • Java
  • Oracle TNSプロトコルエラーについて

    新たに作成したbbsユーザーでSQLPlusでログインしようとするとTNSプロトコルエラーが 発生します。system、scottユーザーではログインできます 以下はユーザー作成に実行したSQLです。 SQL> create user bbs 2 identified by bbs; ユーザーが作成されました。 SQL> col username format a18 SQL> col password format a18 SQL> select username,password 2 from dba_users 3 where username = 'bbs'; レコードが選択されませんでした。 ご教授よろしくお願いします。

  • like文の書き方を教えてください。

    テキストボックスを作成して入力した値がデータベースに 格納されている場合表示されるSQL文を書いていますが syntaxエラーになってしまい原因がわかりません。 String name = request.getParameter("name"); //入力された名前 String sql = new String(); <%-- SQL文 --%> sql += " select * from data "; sql += " where name "; sql += " like" + "('%" + s_name + "%')"; sql += " ) "; <input type="text" name="name" value=""> //textBox エラー表示 8番目: SQL = select * from data where name like('%i%') ) 9番目: ResultSetに格納失敗 : java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1  となってしまいます。 コマンドプロンプト上で select * from data where name like('%itou%'); この場合はちゃんと表示されます。 お分かりになる方よろしくお願い致します。

    • ベストアンサー
    • MySQL