• 締切済み

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; /

  • Oracle
  • 回答数2
  • ありがとう数7

みんなの回答

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

>カーソルおよびフェッチ時にダブルクウォートを削除、またはシングルクウォートに変換をすることが可能でしょうか。 なんか違う気がする。 >※※※上記TESTREC.TEST_NAMEに"AAAA"の形でデータが入るため、下記実行時にORAエラーが発生する。 というのを >EXECUTE IMMEDIATE V_EXEC_STRING INTO V_EXEC_COUNT; で実行されるSQL文が、 >V_EXEC_STRING := V_EXEC_STRING || 'SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = '|| TESTREC.TEST_NAME; によって作成された SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = "AAAA" になっているからAAAAという項目がないってエラーになっているようです。 "を除去したところで、 SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = AAAA になるだけ。 やはり、AAAAという項目がないってエラーになるのでは? V_EXEC_STRING := V_EXEC_STRING || 'SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = '''|| TESTREC.TEST_NAME || ''''; にすると、 SELECT COUNT(*) FROM READ_TBL WHERE TEST_NAME = 'AAAA' となるので、TEST_NAMEの値が、AAAAの件数を取得できる ということかなと思いますがいかがでしょう?

  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.1

こんにちわ。 > カーソルおよびフェッチ時にダブルクウォートを削除または > シングルクウォートに変換をすることが可能でしょうか ltrim, rtrim, translate, replace 等を使えば可能だと思います。 この辺のマニュアルを参考にしてみて下さい。 http://docs.oracle.com/cd/E16338_01/server.112/b56299/functions002.htm#CJAEEJFC

参考URL:
http://docs.oracle.com/cd/E16338_01/server.112/b56299/functions002.htm#CJAEEJFC

関連するQ&A

  • oracleのUSER_TABLESのNUM_ROWSって?

    USER_TABLESのNUM_ROWについて教えてください。 リファレンスマニュアルを見るとNUM_ROWは表内の行数をあらわすようです。 実行してざっと見てみるとCOUNT(*)で件数を取ったのと同じ値になるケースが多いですが、 (NULL)のケースもあります。 違う数値の場合もあります。 そのNULLの表はデータ0件なのかと思ったら、しっかりと結構なデータ量があったりします。 NUM_ROWは表内の行数=レコード数かと思ったのですがどうも違うようです。 USER_TABLESのNUM_ROWとは何でしょうか? <イメージ> SELECT TABLE_NAME, NUM_ROWS FROM USER_TABLES WHERE TABLE_NAME = 'TBL1' TABLE_NAME NUM_ROWS ---------- -------- TBL1 (NULL) TBL2 35 SELECT COUNT(*) FROM TBL1 count(*) -------- 980 SELECT COUNT(*) FROM TBL2 count(*) -------- 35

  • 集計関数の合計について

    お世話になります。 SQLSever2005を使用しています。 Count(*)で月毎のデータ件数を集計し、またその結果を出力するSQLを考えております。 SELECT  (SELECT Count(*) FROM TBL_TEST T1 WHERE T1.T_DATE>='2005/01/01' AND T1.T_DATE=<'2005/01/31') AS CNT_1,  (SELECT Count(*) FROM TBL_TEST T2 WHERE T2.T_DATE>='2005/02/01' AND T2.T_DATE=<'2005/02/31') AS CNT_2,   (SELECT Count(*) FROM TBL_TEST T3 WHERE T3.T_DATE>='2005/03/01' AND T3.T_DATE=<'2005/03/31') AS CNT_3,   (CNT_1+CNT_2+CNT_3) AS TOTAL_CNT ・・・・・・・・・・・・ (★)  FROM TBL_TEST T  WHERE ・・・・・・・・・ 結果(★)のところで『CNT_1は無効です』というエラーになってしまいます。 ちなみにAccessではエラーにならずに結果を出力していました。 上記のSQL文はどのように修正すればよろしいでしょうか?

  • こういう場合のSQLの書き方。

    はまっています。お知恵を貸してください。 Oracle8i WindowsNT4.0です。 tbl_testというテーブルがあります。 データが以下のように入っています。 col1   col2   col3 --------------------------------- A     B     C      A B     A     A C この時、col1 col2 col3それぞれのカラムの中で、 Aという値が何個あるか数えたいのです。 今は以下のように三つにわけてセレクトしていますが、 これをひとつの式にまとめたいのですが、可能でしょうか? UNIONしても欲しい答えは返ってきません。 =========================== SELECT COUNT(col1) AS col1 FROM tbl_test WHERE col1 = 'A' =========================== SELECT COUNT(col2) AS col2 FROM tbl_test WHERE col2 = 'A' =========================== SELECT COUNT(col3) AS col3 FROM tbl_test WHERE col3 = 'A' 欲しい答えは、 col1   col2   col3 ----------------------- 1     2     1 です。 なお、家に検証環境が無いので、検証&お礼は明日のお昼くらいになると思います。 宜しくお願い致します。

  • WITH句を使用したSQLの結果

    WITH句を使用して総件数と1~20件までのデータを同時に取得するSQLを組んでみたところ、 WITH TMP AS (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO) SELECT T1.ALLCNT, T2.* FROM (SELECT COUNT(*) ALLCNT FROM TMP) T1, TMP T2 WHERE T2.CHECKROWNUM BETWEEN 1 AND 20; Oracle10.2.0.3.0のバージョンで ALLCNTが21になってしまう現象が発生してしまいました。 Oracle10.2.0.4.0や9iでは発生せず正しい総件数が取得できるのですが、 バージョンによる不具合は考えられますでしょうか。 それともSQL自体なにか悪い部分があるのでしょうか。 ちなみに T2.CHECKROWNUM BETWEEN 1 AND 100; と帰るとALLCNTが101と帰ってきます。 また、WITH句を使わず下記のようにTMPの部分をWITH句で使用したSQLに 置き換えると正しくALLCNTが取れます。 SELECT T1.ALLCNT, T2.* FROM (SELECT COUNT(*) ALLCNT FROM (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO)) T1, (SELECT ROW_NUMBER() OVER (ORDER BY NO) AS CHECKROWNUM,NAME FROM TEST_TBL ORDER BY NO) T2 WHERE T2.CHECKROWNUM BETWEEN 1 AND 20;

  • 複雑な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 という結果を得たいのですが方法はありますでしょうか? ご教示お願いいたします。

  • カウント結果を1レコードの中で横に並べたい

    カウント結果を1レコードの中で横に並べたい 以下のテーブルを、 test_table id   group  name 1    100   テスト1 2    100   テスト1 3    100   テスト1 4    200   テスト1 5    200   テスト1 6    200   テスト2 7    200   テスト2 8    200   テスト2 9    200   テスト2 nameごとのカウント、更に100だけのカウント、200だけのカウントといったように、 以下のように横に並べることは可能でしょうか? name   合計  100計   200計 テスト1  5    3      2 テスト2  4    0      4 まず、nameごとの合計を取得するクエリを作って、 それに、100計列、200計列の部分をサブクエリでもってきたのですが、 これで動くには動くんですが、このやり方しかないものでしょうか。 ご教示おねがいします。 SELECT t.name, COUNT(*) as '合計', (SELECT COUNT(*) FROM test_table as t1 WHERE t1.name = t.name AND t1.group = '100' ) as '100計', (SELECT COUNT(*) FROM test_table as t1 WHERE t1.name = t.name AND t1.group = '200' ) as '200計' FROM test_table as t WHERE 1 GROUP BY t.name;

    • ベストアンサー
    • MySQL
  • MySQLでWHEN句のサブクエリ中にて

    MySQL ver.5.0.95です。 PHPからSQL文を作ってDBへインサートしているのですが 重複した値が合った場合はupdateするように書いています。 TBL1には |id   |string   |count 1    aaa    0 2    bbb    3 3    ccc    1 TBL2には |id2    |string2    |count2 1      aaa      0 2      bbb      2 3      ccc      1 実際はもう少し複雑ですが、こういう感じでデータが入ってるとします。 このとき、TBL1のそれぞれをインサート若しくはアップデートするのに TBL2の同一IDのものの、count2の状態によって場合分けしたく 同一IDのcount2が1以上なら変更しない、という風にするため以下のように書いたのですが insert into TBL1 values (1, "aaa", 3), (2, "bbb", 3), (3, "ccc", 3), (4, "ddd", 3) on duplicate key update count = CASE WHEN (select count2 from TBL2 where id2 = values(id)) >=1 THEN count ELSE count + values(count) END; #1064 - You have an error in your SQL syntax;というエラーになって出来ません。 WHENの中のサブクエリで、where id2 = values(id) 恐らくこの文がダメなようです。 例えば決め撃ちで1つ1つ書くと通ります。 insert into TBL1 values(1, "aaa", 3) on duplicate key update count = CASE WHEN (select count2 from TBL2 where id2 = 1) >=1 THEN count ELSE count + values(count) END; insert into TBL1 values(2, "bbb", 3) on duplicate key update count = CASE WHEN (select count2 from TBL2 where id2 = 2) >=1 THEN count ELSE count + values(count) END; insert into TBL1 values(3, "ccc", 3) on duplicate key update count = CASE WHEN (select count2 from TBL2 where id2 = 3) >=1 THEN count ELSE count + values(count) END; insert into TBL1 values(4, "ddd", 3) on duplicate key update count = CASE WHEN (select count2 from TBL2 where id2 = 4) >=1 THEN count ELSE count + values(count) END; これをエラーになったような文に変えて1文にまとめたいのですが、無理でしょうか? あとそもそもこれをまとめたほうが速いと思ってそうしたいのですが、 変わらないのなら1文1文;でつなげて書くやり方でいこうと思っています。 まとめると速くなることはあるでしょうか?

    • ベストアンサー
    • MySQL
  • ????

    以下のクエリを実行しました。 insert into test_tbl(aaa,bbb,ccc) values('xx','yy','△△'); ※====『△』は半角スペース==== それで以下のsqlを実行すると select count(*) from test_tbl where ccc = '△△'; --- 1 --- と出ます。それで今度は以下のSQLを記述すると select count(*) from test_tbl where ccc = '△'; --- 1 --- とでます。 因みにテーブル構成は -------------- aaa char(2) bbb char(2) ccc char(2) -------------- です。 どうしてインサートしたデータが"△△"なのに "△"でひっかかるのでしょうか? しつこいようですが、記述中の'△'は半角スペースです。

  • SQLite C/C++ でのテーブル数の取得

    よろしくお願いします。  テーブル名「TB1332」の有無を確認するSQL 文をこのようにしました select count(*) from sqlite_master where type='table' and name='TB1332'; PupSQLite でのcount(*)の値 当該テーブルが存在する場合 1 当該テーブルが存在しない場合 0 このように正しい結果が得られます。 しかし、Visul Studio 2010 C++ で下記のコードを実行しますと、result の値は、テーブルの有無に関係なく、常に0となります。 int result = sqlite3_exec(pDb, "select count(*) from sqlite_master where type='table' and name='TB1332';", NULL, NULL, &err); C/C++ で該当する、テーブル数を取得するコードの書き方を教えていただけないでしょうか。 環境 C/C++ Visual Studio 2010 Proffesional SQLite3 PupSQLite https://www.eonet.ne.jp/~pup/software.html

  • 2つのテーブルのカウント結果を1行で取得

    以下のようなデータ件数のテーブルが、別々のDBにあります。 SELECT COUNT(*) FROM AA.TBL01 ------ TBL01 ------ 10 SELECT COUNT(*) FROM BB.TBL02 ------ TBL02 ------ 5 それぞれのテーブルのカウント結果を、1行で取得する ことは可能でしょうか? <取得したい結果> ---------------- TBL01 TBL02 ---------------- 10 5 よろしくお願いします。 (SQL Server2005 Standard)