レコードが追加できない

このQ&Aのポイント
  • SQL-Server2010を使用しています。レコードを追加する際にキー項目が存在する場合は追加しないようなSQL文を作成しました。
  • 追加するテーブルにレコードが1件以上あれば思ったとおりの処理となりますが、1件も存在しない場合は追加できません。
  • 原因と対策方法を教えて頂けませんでしょうか?
回答を見る
  • ベストアンサー

レコードが追加できない

SQL-Server2010を使用しています。 レコードを追加する際にキー項目が存在する場合は追加しないようなSQL文を作成しました。 追加するテーブルにレコードが1件以上あれば思ったとおりの処理となりますが、 1件も存在しない場合は追加できません。 下記がそのSQL文です。 原因と対策方法を教えて頂けませんでしょうか? INSERT INTO foo(商品コード, 商品名) SELECT DISTINCT 'ABC123' , 'りんご' FROM foo WHERE NOT EXISTS( SELECT * FROM foo WHERE 商品コード = 'ABC123' ) 以上です。 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.2

「SELECT 'ABC123' , 'りんご' FROM foo」と書くとfooのレコード数だけの行の('ABC123' , 'りんご')というデータを作成してしまいます。 質問の記述ではDISTINCTを用いてそれを再度一行にまとめようとしています。しかし、fooにそもそも一行もデータがないとまとめる段階でデータが存在しないので挿入できないのです。 また、fooのレコード数だけのレコードを作ってまとめるのは無駄な作業で、fooのレコード数が増加していくとパフォーマンスの劣化が見逃せなくなります。 SQLを記述する時は、「とりあえず、動けばいい」ではなく、どんな動作が裏で行われているかを念頭に置いておくようにしてください。 で、ACCESSですが、ACCESSの場合はFROM句を省略出来ません。 その代わりに何でもいいので一行のレコード(しかも一行のみ)のダミーテーブルを作成し、FROM句を構成すればいいのです。(OracleのDUAL表と一緒です) フィールドも一つでバイト型で構いません。とりあえず「0」の値を入力しておけば結構です。テーブル名も「DUAL」とでもつけてください。 そうすれば INSERT INTO foo(商品コード, 商品名) SELECT DISTINCT 'ABC123' , 'りんご' FROM DUAL WHERE NOT EXISTS( SELECT * FROM foo WHERE 商品コード = 'ABC123' ) でいけるはずです。

greenwave
質問者

お礼

分かりやすい説明ありがとうございます。大変良く理解できました! ACCESSでDUALテーブルを作成し1レコードだけ作成した結果、実現できました! 今日半日以上この件で試行錯誤し悩んでおりましたので感激です。 有難う御座いました。

その他の回答 (1)

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

「SELECT DISTINCT 'ABC123' , 'りんご' FROM foo」の「FROM foo」が悪さしてます。 これを付加した意図はなんでしょう? INSERT INTO foo(商品コード, 商品名) SELECT 'ABC123' , 'りんご' WHERE NOT EXISTS( SELECT * FROM foo WHERE 商品コード = 'ABC123' ) ではダメですか?

greenwave
質問者

補足

回答ありがとうございます。 早速SQL-Serverで試してみたところ思ったとおりの動きになりました。 SELECT句とFROM句はセットで使用するものと思っていたのが間違いでした。 再度質問になるのですが、 同じことをAccess2003でも実現したいのですが、Access2003では「構文エラー」と なってしまいます。 どのような解決方法がありますでしょうか? 宜しくお願い致します。

関連するQ&A

  • 重複するレコードを調べるSQL

    重複するレコードを調べるSQL 初歩的な質問ですみません! 重複するレコードを調べるために以下のようなSQLを作ったのですが、 遅くて困っています。 もっと速くする方法があれば教えてください! 異なるカテゴリーでも商品コードが重複しているものがないかを探すSQLです。 SELECT A.商品コード, A.X, B.カテゴリー FROM (SELECT COUNT(商品コード) X, 商品コード FROM テーブルA WHERE 追加年月 = 201008 GROUP BY 商品コード) A, (SELECT 商品コード, カテゴリー FROM テーブルA WHERE 追加年月 = 201008 ) B " WHERE A.X >= 2 AND B.商品コード = A.商品コード

  • SQLiteで最も古いレコードのみの削除

    AndoroidでDBを使うのですが、考える動作のSQL文が作成できません。 テーブルTESTは以下のカラムを持ちます  ・ID - primary key not null  ・VALUE - not null テーブルTESTは最大で10件のレコードを保持します、11件目のレコードが発生したら 最も古い1件目のレコードを削除してから、11件目のデータを新しい10件目のデータとして テーブルに保存します。 そのために「最も古いレコード1件のみを削除する」というSQLを作成したいのですが、 考えたSQL文が正しくないと怒られてしまいます。 delete from TEST as A, (select * from TEST LIMIT 1)as B where A.ID=B.ID; この動作を1つのSQL文で行うのは不可能なのでしょうか?

  • EXSIST述語を使った副問合わせについて

    SELECT HINMOKU_NAME FROM HINMOKU WHERE HINMOKU_CODE IN (SELECT HINMOKU_CODE FROM URIAGE WHERE URIAGE_DATE = '2004-11-10'); 上記をSQL文をEXISTS述語を使って書き換えると エラーが出てしまい、うまく書き換えがすることが できません。下記にエラーがでるSQL文を記載いたします。 SELECT HINMOKU_NAME FROM HINMOKU WHERE EXISTS (SELECT HINMOKU_CODE FROM URIAGE WHERE URIAGE_DATE ='2004-11-10' WHERE HINMOKU.HINMOKU_CODE=URIAGE.HINMOKU_CODE); 上記SQL文についてどこに問題があるのか、ご教授お願い致します。

  • レコードの抽出

    PerlCGIでSQL-ENGINE.plというライブラリを使ってSQLを実行しています。最も結構ローカルなフリーのライブラリだから(作った人におこられるか)それの使い方を教えてくださいという訳ではありません。 一般的な形で結構ですので、SQL文を教えてもらいたいのです。 例えば select * from テーブル where 抽出条件 order by 何かの基準で降順並替え; として、さらにこの抽出結果の上から11番目のレコードから20番目のレコードだけを抽出したいとすると、これにどのようなSQL文を追加したらよいのでしょう。

  • distinct句を使わずレコード総計を求めたい

    DB初心者です。 DISTINCT句を使わずに、group by句を使って 重複データを除いたレコード総計を求めたいと思い、 下記の用にSQL文を書いたのですがうまくいきません。 oracleではなく、DB2を使っているのですがSQL文として 可能なのか教えていただければと思い質問を致しました。 <例> テーブル名:商品DB 商品名 a a b b c だったら、重複を除いたレコード数は3になりますが、 select count(*) from 商品DB group by 商品名 とすると 2 2 1 となり、それぞれの商品の合計数が出てしまうので select count(*) from ( select 商品名 from 商品DB group by 商品名) と副問合せ(でよいのでしょうか?)をしてみると 入力が予想されるトークンには "AS" が含まれている可能性があります。とエラーになってしまいました。

  • LIKEを使用したレコード抽出について

    OracleでLIKEを使用したレコード抽出で困っています。 あるテーブル(TAB_A)が以下のような属性だとします。 ------------- COL1 CHAR(5) COL2 CHAR(5) このとき、このテーブルに次のようにデータが格納されています。 COL1  COL2 -------------- ABC==  12345 [=]は便宜上1バイトスペースを表す このテーブルを対象として (1) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC%'; (2) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC==';   ([=]は便宜上1バイトスペースを表す) (3) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC'; というSQLを発行した場合に、いずれもレコードが抽出されてしまいます。(1)(2)の場合は当然だとは思うのですが、(3)でもレコードが抽出されることが理解できません。このようなことが起こり得るのでしょうか。

  • DAOレコードセットから更に絞込みしたい

    VBAで質問です。あるレコードセットXをsqlで取得しました。さらにこのレコードセットにSQLを投げて絞り込みたいと思っています。例えばSQLでA,B,C列を取得しました。このA、B、C列があるレコードセットにwhereで絞り込みたいと思ってます。レコードセットXに向けて、select * from X where...というコードは投げれるのでしょうか?

  • 該当レコードなしでエラーを発生させない方法

    レコードなし、もしくは該当レコードなしでエラーを発生させない方法を教えてください データベース初心者です レコードなしもしくは該当レコードなしの状態で検索を行うとエラーが発生します。 エラーを発生させずに検索を行う方法があれば教えてください。 MySQL 5.0.67 レコードは下記のようになります。 desc table; +----------+----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+----------------------+------+-----+---------+-------+ | val1 | smallint(6) | NO | PRI | 0 | | | val2 | smallint(6) | NO | PRI | 0 | | | val3 | smallint(6) | NO | PRI | 0 | | | date_y | char(4) | NO | PRI | | | | date_m | char(2) | NO | PRI | | | | pre | bigint(19) | NO | | 0 | | | now | bigint(19) | NO | | 0 | | +----------+----------------------+------+-----+---------+-------+ 下記のSQL文で検索を行いました。 SELECT t.date_y, t.date_m FROM table t, ( SELECT date_y,max(date_m*1) as date_m FROM table WHERE date_y= ( SELECT max(date_y*1) as date_y FROM table WHERE (now - pre) > 0 ) ) s WHERE t.date_y=s.date_y and t.date_m=s.date_m; レコードなし、もしくは該当レコードがないとWHERE文のdata_yにnullが代入され、 本SQL文でエラーが発生します。 いろいろ調べて「EXISTS」「NOT EXISTS」「NULLIF」を利用するのかな? と思ったのだけど、下記URLを参照しても、うまくSQL文が書けませんでしたので、ご教授頂ければ幸いです。 6.4.2.6. EXISTS と NOT EXISTS http://dev.mysql.com/doc/refman/4.1/ja/exists-and-not-exists-subque... 6.3.1.4. フロー制御関数 http://dev.mysql.com/doc/refman/4.1/ja/control-flow-functions.html

    • ベストアンサー
    • MySQL
  • DELETE 文とEXISTSの使い方について(Oracle10g)

    DELETE 文とEXISTSの使い方について(Oracle10g) 2つのテーブル(A、B)を外部結合して、B側がNULLとなったレコードを A側から削除する、というDELETE文が作りたいのですが、 EXISTS句を使ってみたもののどうも使い方がわからず苦戦しています。 目的は2つのテーブルを同期させる事で このSQLを実行する時点で、常にA>Bになっています。 目的を達成できるSQLを教えてください。 <削除対象レコードをSELECTするSQL> SELECT * FROM A, B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ; <上をDELETE文にしてみたつもりが、削除0件になってしまうSQL> DELETE FROM A WHERE EXISTS( SELECT 1 FROM B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ) ;

  • VB2010のSQLを使ったレコードカウント方法

    VB2010にて他のシステムから出力したCSVファイルにアクセスして集計を行おうとしています。 重複を排除したカウントを得たいのですがうまくいきません。 (1) SQL = "SELECT DISTINCT 物品ID FROM …" だと目的のレコードを抽出できるのですがCOUNTを使って (2) SQL = "SELECT COUNT(DISTINCT 物品ID) AS 物品数 FROM …" とする『演算子がありません』とエラーが出て (3) SQL = "SELECT DISTINCT COUNT(物品ID) AS 物品数 FROM …" とすると値はですのですが(1)のレコード数と違う数が出てきます??? 素人の手探りでプログラミングをしているので動きの違いが分かりません ご教授お願いします。