

格納するデータの性質上、主キーや一意キーを設定できないテーブル(testtable)に、ある条件を満たすデータが既にあればデータを登録しない、というINSERT文(下記)を実行したいと考えています。
---------------------------
IF NOT EXISTS (
SELECT * FROM testtable
WHERE Entity1='entity1'
AND Entity2='entity2'
AND localId='myid'
AND subsysId='subsysid'
AND deactivationDate is NULL
)
INSERT INTO shibpid (Entity1, Entity2, localId, subsysId)
VALUES ('entity1', 'entity2', 'myid', 'subsysid)
ELSE PRINT 'already exist.';
---------------------------
しかし、このSQL文を以下のように実行するとエラーがでてしまいます。
---------------------------
>mysql -u root -p testdb
Enter password: ******(パスワードを入力)
mysql> IF NOT EXISTS (
-> SELECT * FROM testtable
-> WHERE Entity1='entity1'
-> AND Entity2='entity2'
-> AND localId='myid'
-> AND subsysId='subsysid'
-> AND deactivationDate is NULL
-> )
-> INSERT INTO shibpid (Entity1, Entity2, localId, subsysId)
-> VALUES ('entity1', 'entity2', 'myid', 'subsysid)
-> ELSE PRINT '111';
ERROR 1064 (42000): 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 'IF NOT EXISTS (SELECT * FROM testtable WHERE Entity1='entity1' at line 1
mysql>
---------------------------
文法エラー、といわれても、どこが違うのか全くわからず、非常に困っています。
もしや、IF NOT EXISTS は使えない、あるいはこのような使い方はできないのでしょうか?
No.4ベストアンサー
- 回答日時:
IF EXISTS などという文は、SQLにはありません。
これは、条件に書くものです。
SQL文は集合演算的な言語ですので、こういった手続き型の記述はストアードプロシージャなどで行います。
ただ。こういった手はあります。
まず、1行だけのテーブルを作ります。これはOracleで言えばdualのようなものです。FROM句にダミーで使います。
CREATE TABLE onerow(x int);
INSERT INTO onerow values(0);
そして次のようなSQL文を発行します。
INSERT INTO shibpid (Entity1, Entity2, localId, subsysId)
(SELECT 'entity1', 'entity2', 'myid', 'subsysid' FROM onerow
WHERE NOT EXISTS (
SELECT * FROM testtable
WHERE Entity1='entity1'
AND Entity2='entity2'
AND localId='myid'
AND subsysId='subsysid'
AND deactivationDate is NULL))
この回答への補足
これを試してみたところ、期待する動作を得ることができました!
ダミーのテーブルに問い合わせる分、資源消費や処理速度が心配ですが・・・それにしても、こんな方法もあったとは。
勉強になりました。
No.6
- 回答日時:
#4です。
補足です。
MySQLでは、FROM句のないSELECT文が書けます。
SELECT 1,2,3;
を実行すると、1,2,3からなる1行が返されます。
しかし、WHERE句を書く時にはFROM句がないとシンタックスエラーと怒られます・・・
で、このような無害なテーブルを使ってます。
この解は、ほとんどのRDBMSで動きます。Oracleの場合は、onerowと同じ役割を果たすdualというテーブルが最初からありますので、そちらを使えます。
No.5
- 回答日時:
この場合、適当なフィールドにUNIQUE属性をつけておいて
INSERT IGNORE INTOでインサートしてやるのが現実的かと
この回答への補足
最初、一意のデータを表現できる、最低限の複数のフィールドでUNIQUEキーを設定することを考えました。
(データの性質上、単独のフィールドで一意にならないのです。)
しかし、その最低限の複数のフィールドのなかにNULLが入るものがあり、NULLが入ると一意性の判定をしてくれないらしく、そのフィールドの値がNULLであれば同じデータが幾らでも登録できてしまいました。
このような事情から、キー制約以外の方法を探していました。
No.3
- 回答日時:
記憶によると IF NOT EXIST は、CREATE TABLE などにしか使えなかったと思います。
英文ですが、代替手段はあるようです。
http://bogdan.org.ua/2007/10/18/mysql-insert-if- …
フロー制御を駆使すれば出来るような気もするのですが。
http://dev.mysql.com/doc/refman/5.1/ja/control-f …
(過去にやったことがあると思ったので自分のソースを見てみたところ
アプリケーション側で処理してました)
5.0だとストアドも使えるようです。
この回答への補足
> 英文ですが、代替手段はあるようです。
ここに挙げられた方法の動作は私の希望とちょっと違うようです。
(私のテーブルには主キーなどが無いので、ここで紹介されている方法のどちらでも、どんどん登録データが増えてしまうのです。)
ただ、文中にあげられている、ダミー操作(多分、#4の方が述べているのと同じ感じだと思います)は検討の価値がありそうです。
> フロー制御を駆使すれば出来るような気もするのですが。
こちらは、現状、「そんな気がするけど、いまいち使い方がわからないなぁ」状態です。
もう少し自分で調べてみて、必要なら改めて質問したいと思います。
> 5.0だとストアドも使えるようです。
ストアドプロシージャの使用は検討したのですが、できるだけDBの種類に依存しない方法を採りたい、との思いから、これは最終手段ということにしています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 戦争・テロ・デモ ウクライナ、メル友に五千円要求されてさ 1 2022/04/02 09:38
- 英語 できるだけ直訳で英語の翻訳をお願いします。(英語→日本語) 1 2022/10/15 20:59
- MySQL テーブル作成です。どこかのスペルが間違っているか記号など スペースかな? 1 2022/10/01 05:08
- 英語 この英文は格調高いのでしょうか? 3 2022/06/03 18:55
- その他(SNS・コミュニケーションサービス) 自分のpcがハッキングされたようなメールが来たのですがどうすればいいですか? 4 2022/10/02 16:14
- 英語 These lesions are unlikely to respond to antibioti 1 2023/03/29 21:17
- 英語 この英文は平易な反面格調高いですか? 1 2023/01/15 12:04
- MySQL 参考書に従って入力したつもりでしたが、最後はエラーがでました。 1 2022/09/28 03:45
- その他(プログラミング・Web制作) python fbprophetについて 1 2022/09/29 19:44
- PHP php エラー 2 2022/10/23 16:43
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessでデータシートに同じデ...
-
このISAMでは、リンクテーブル・・
-
マテリアライズドビューとスナ...
-
Accessでの稼働日数計算の方法
-
アクセス レコードセットを更...
-
テーブルで一番古いレコードだ...
-
Access昇順レコードを、5分割...
-
VBAでSQLServerへのODBC接続
-
1つのSQL文で文字列を置換する...
-
ビューのソートについて
-
テーブル作成時の行数の設定
-
SQLでの前検索・後検索
-
PostgreSQLでテーブル構成を変える
-
Access VBAからエクセルに出力...
-
MySQLの容量の削減の仕方
-
テーブルの設計はとりあえず文...
-
住所のDBテーブル、マスターの...
-
Excel→Access→Oracleでインポー...
-
MYSQLでコード番号を自動でつけ...
-
access 特定のレコード数までエ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessでデータシートに同じデ...
-
Oracleで上書きImportはできま...
-
ビューのソートについて
-
Accessのテーブルデータを一気...
-
テーブルで一番古いレコードだ...
-
アクセス レコードセットを更...
-
マテリアライズドビューとスナ...
-
ORA-01401が表示され、データが...
-
このISAMでは、リンクテーブル・・
-
accessでレコード更新直後の反...
-
結合テーブルでINSERTする方法...
-
ERROR1062:Duplicate entry.......
-
IF NOT EXISTを使用するINSERT文
-
削除したテーブルを元に戻すこ...
-
「クリップボードにコピーされ...
-
left joinなどで結合対象のレコ...
-
ACCESS2010の最適化が中断される
-
ODBC接続で新しいレコードを追...
-
構文エラー : 演算子がありませ...
-
処理の途中で停止させ、再開さ...
おすすめ情報