[[20070313153531]] 『SQL文のエラー』(koara) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『SQL文のエラー』(koara)

 表題の件に関して、どなたか教えてください。

 SQL文を作成してOracleに接続し、データを取得しようとしたのですが、

 実行時エラー’-2147217911(80040e09)'
 [Datadirect][ODBC Oracle driver][Oracle]ORA-00923:
 FROMキーワードが指定の位置にありません。

 とのエラーメッセージが出てしまいました。
 実行しているSQLは以下のとおりです。
 どこがおかしいか教えて下さい。

   sSql = "SELECT 在庫.受注番号, 管理.売上担当拠点CD, 在庫.使用者名1, "
    sSql = sSql & " 在庫.登録型式, 在庫.車台番号, '.' & Left(在庫.登録日,6) & '登録済' AS 登録月,"
    sSql = sSql & " 在庫.登録日, 在庫.登録番号, 客.V34顧客名1, Left(在庫.車台番号,2) AS 車型,"
    sSql = sSql & " 拠点.V26拠点名 AS 支店名, 車型M.VIPS車種コード"
    sSql = sSql & " FROM (((車型M INNER JOIN 新車在庫M AS 在庫 "
    sSql = sSql & " ON 車型M.車型コード = 在庫.車型コード)"
    sSql = sSql & " INNER JOIN 注文管理F AS 管理 ON 在庫.受注番号 = 管理.注文番号)"
    sSql = sSql & " INNER JOIN 客 ON 管理.売上担当者番号 = 客.N8顧客番号)"
    sSql = sSql & " INNER JOIN 拠点 ON 管理.売上担当拠点CD = 拠点.C2拠点CD"
    sSql = sSql & " WHERE (((管理.売上担当拠点CD)<'40'))"
    sSql = sSql & " GROUP BY 在庫.受注番号, 管理.売上担当拠点CD, "
    sSql = sSql & " 在庫.使用者名1, 在庫.登録型式, 在庫.車台番号, '.' & Left(在庫.登録日,6) & '登録済',"
    sSql = sSql & " 在庫.登録日, 在庫.登録番号, 客.V34顧客名1, Left(在庫.車台番号,2),"
    sSql = sSql & " 拠点.V26拠点名, 車型M.VIPS車種コード, 在庫.年式, 在庫.FIF車種, 客.C1社員区分"
    sSql = sSql & " HAVING (((在庫.登録日)>=" & gsFrom & "And (在庫.登録日)<=" & gsTo & ") "
    sSql = sSql & " AND ((在庫.年式)<>123) AND ((在庫.FIF車種)<>'2') "
    sSql = sSql & " AND ((客.C1社員区分)='E' Or (客.C1社員区分)='S'));"

    aRs.Open sSql, goOraConnection, adOpenStatic, adLockReadOnly

 よろしくお願いします。

使われているのは、EXCEL2000でしょうか?
 その場合には、下記の対応(SP2適用)が必要です。
http://support.microsoft.com/kb/259347/ja

後、SQL*PLUS等で上記のSQLを実行した場合、正常に処理されますか? by wkj


 wkjさんありとうございます。 
 レスが遅くなって申し訳ありません。

 使用しているエクセルのバージョンは2002です。

 また、SQL*PLUSで実行するとはどういう事でしょうか?


 単にSQL文が間違っています。
さしあたり
    sSql = sSql & " 在庫.登録型式, 在庫.車台番号, '.' & Left(在庫.登録日,6) & '登録済' AS 登録月,"
とかで、SQL文として「&」やらが使われてしまってます。
よく見直してみてください。他にも同様の箇所が多数あります。
 
出来上がったsSqlの中身を一度確認してみるのが良いと思います。
 
ちなみにSQL*PlusとはOracleのツールです。
Excelの問題か、それともSQL文の問題かを切り分けるために、
Oracleに直でSQL文を投げて検証してみてはどうか、と言う提案ですね。
(ご近所PG)

 Oracleから離れて久しいのですが、「Inner Join」ってそもそもSQL Serverの構文で、
 Oracleでは無効ではありませんでしたっけ?

 Oracleのバージョンによって使えない構文が確かあったと記憶しています。
 (HT)

 みなさんありがとうございます。

 違うSQL文で試したところ、きちんと実行できるので
 SQL文が間違っていると思います。

 出来上がったSQL文をアクセスで実行して確認してみました。
 アクセスではきちんと実行できました。

 SQL文は以下のとおりです。

 SELECT 在庫.受注番号,管理.売上担当拠点CD AS 支店, 在庫.使用者名1,  
 在庫.登録型式, 在庫.車台番号, '.' & Left(在庫.登録日,6) & '登録済' AS 登録月, 在庫.登録日, 
 在庫.登録番号, 客.V34顧客名1, Left(在庫.車台番号,2) AS 車型, 拠点.V26拠点名 AS 支店名, 
 車型M.VIPS車種コード 
 FROM (((車型M INNER JOIN 新車在庫M AS 在庫  ON 車型M.車型コード = 在庫.車型コード) 
 INNER JOIN 注文管理F AS 管理 ON 在庫.受注番号 = 管理.注文番号) 
 INNER JOIN 客 ON 管理.売上担当者番号 = 客.N8顧客番号) 
 INNER JOIN 拠点 ON 管理.売上担当拠点CD = 拠点.C2拠点CD 
 WHERE (((管理.売上担当拠点CD)<'40')) GROUP BY 在庫.受注番号, 管理.売上担当拠点CD,  
 在庫.使用者名1, 在庫.登録型式, 在庫.車台番号, '.' & Left(在庫.登録日,6) & '登録済', 在庫.登録日, 
 在庫.登録番号, 客.V34顧客名1, Left(在庫.車台番号,2), 拠点.V26拠点名, 車型M.VIPS車種コード, 
 在庫.年式, 在庫.FIF車種, 客.C1社員区分 
 HAVING (((在庫.登録日)>=20070301
 And (在庫.登録日)<=20070331)  
 AND ((在庫.年式)<>123) 
 AND ((在庫.FIF車種)<>'2')  
 AND ((客.C1社員区分)='E' 
 Or (客.C1社員区分)='S'));

 そもそも、私がSQL文を作成するのに、アクセスを使用してSQL文を作成し
 それをプログラム内に貼り付けているのがいけないのでしょうか?
 アクセスとOracleでは少し違うと聞いたのですが、この方法しか今のところわからなかったので、この方法でSQL文を作成しました。

 SQL文の中に「&」が使われているとエラーになってしまうのでしょうか?
 ためしに出来上がったSQL文の&が使われている部分「'.' & Left(在庫.登録日,6) & '登録済'」
 を削除して実行してみましたが、そうすると『キーワードがありません』となってしまいました。

 INNER JOINは他でも使用しているのですが、その時は特に問題なかったと思います。
 もしこの部分を直すとすると、どのように直せば良いでしょうか?

 お手数ですが、ご教授お願いします。


 Oracle的に書くなら例えば
select * from tablea inner join tableb on tablea.key1 = tableb.key1 and tablea.key2 = tableb.key2
は
select * from tablea,tableb where tablea.key1 = tableb.key1 and tablea.key2 = tableb.key2
です。

 一応、ODBCがSQLの方言については吸収してくれるとは思います。
あと最近のバージョンのOracleってInner Joinも通してくれたような?気のせいかも。
このところSqlServerばかり触ってるもので忘れました。

 ただ流石に&で繋いでいるのは、Access特有すぎる書き方なので、ダメでしょう。
Accessでも許されるのかわからないですが……Accessをまともに触ったのも7〜8年前なので……

 とりあえず
'.' & Left(在庫.登録日,6) & '登録済' AS 登録月
について、Oracle的に書き換えるなら
'.' || substr(在庫.登録日,1,6) || '登録済' AS 登録月
ですかね?
実際に実行して検証できる環境が無いので、嘘ついてるかも。
簡単な構文で文字列連結(||)とsubstr関数を試してみてください。

 あと、漢字のテーブル名やら列名を使うのには注意が必要です。
http://otn.oracle.co.jp/forum/message.jspa?messageID=8041417
使えなくは無いけど、何らかの問題で動かない事が起きてもしらんよと。

 推奨は、まず本番ぶっつけのSQLをそのまま通そうとするんじゃなくて、単純なもの
例えば
select * from 車型M INNER JOIN 新車在庫M AS 在庫 ON 車型M.車型コード = 在庫.車型コード
とかのSelect文がちゃんと通るの?って所から調べて行くのがよいのかと。

 最後に、
Accessのコードをそのまま移植すれば動くだろと思うのはとても安易過ぎる考えです。
まだSqlServerに移植なら同じMS製って事で敷居は低いでしょうが……
Oracleに関しての基本的な情報収集からはじめるのをお勧めします。
あとSQLのいわゆる方言だとかも。

 >アクセスとOracleでは少し違うと聞いたのですが
少しなんてもんじゃないですよ、きっと。
その「少し」と言う表現の持つ意味が人によって相当違います。
AccessでのSQL文を、自力で自由に組み立てられると言う前提の上で、
Oracleではどう書くの?と言う事を調べながら出来る人なら、
「少し違うけど」と言う表現をするかも知れません。
(ご近所PG)

 ご近所PGさん。確かOracle8iまではinner joinは使えなかったと記憶しています。
 今の職場の別チームで、複数テーブルを結合してOracleDBを読み込む際に、inner join使用してエラーになったのを
 思い出しました。その時はOracle8.1.7でした。
 Oracle9i以降なら使えた気がします。

 koaraさん。これはあくまでも私の好みの問題で、今回のエラーの解決にはならないと思いますが、
「and」「or」を多用するSQLは条件として如何かと思います。私なら、せめて最後のHAVING部分だけでも

 HAVING (((在庫.登録日)>=20070301
  And (在庫.登録日)<=20070331)  
  AND ((在庫.年式)<>123) 
  AND ((在庫.FIF車種)<>'2')  
  AND ((客.C1社員区分)='E' 
  Or (客.C1社員区分)='S'));

 でなく

 HAVING (在庫.登録日 BETWEEN 20070301 AND 20070331)
    AND (在庫.年式<>123) 
    AND (在庫.FIF車種<>'2')  
    AND (客.C1社員区分 IN ('E', 'S')); 

 くらいに簡略化します。
 (HT)

 レスが遅くなり申し訳ありませんでした。

 ご解答ありがとうございます。
 この件に関しましては、まだまだ当方の勉強不足もあり、
 なかなか難しいと実感致しました。

 とりあえず、
 アクセスでOracleのテーブルにリンクさせてデータの抽出を行っているのですが、
 このリンクを外したかったので、直接Oracleに接続して
 データの抽出をしようと考えました。

 が、そんな簡単にはいきませんでしたね・・・。

 勉強して出来たら改良する事にします。

 助言いただいた皆様、ありがとうございました。


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.