• ベストアンサー
  • 暇なときにでも

CASEでBETWEEN制約

Oracle9i にて制約をつける際の質問です。 以下のようなテーブル構造の場合に、 NAME列にCASEで分岐してBETWEENでCHECK制約をつけようとしていますが、 エラーとなってしまいます。(ORA-00920: 関係演算子が無効です。) テーブル名:TEST2 ID NUMBER GEND NCHAR(1) NAME NVARCHAR2(100) 制約: ALTER TABLE TEST2 ADD CONSTRAINT NAME_CHK CHECK ( NAME CASE WHEN GEND = '1' THEN BETWEEN 'a' AND 'z' WHEN GEND = '2' THEN BETWEEN 'A' AND 'Z' ELSE BETWEEN '1' AND '9' END ) CASEで上記のような制約をつけることは可能でしょうか?

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

  • Oracle
  • 回答数1
  • 閲覧数5446
  • ありがとう数3

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

  • ベストアンサー
  • 回答No.1

>CASEで上記のような制約をつけることは可能でしょうか? その壊れた構文のCASE式では、エラーになって当たり前かと。 正しい構文であれば、CASEを使ったチェックも可能かと思いますよ。 たとえば、 CHECK ( CASE WHEN (GEND = '1') AND (NAME BETWEEN 'a' AND 'z') then 1 WHEN (GEND = '2') AND (NAME BETWEEN 'A' AND 'Z') then 1 WHEN (NAME BETWEEN '1' AND '9') then 1 ELSE 0 END = 1 ) 綺麗な式ではないけど、構文的&論理的には正しい式なので、通ると思いますよ。

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

質問者からのお礼

なるほど、このような書き方ができるんですね。 THEN の値と、ENDの後の値を比較するという発想がなかったです。 ありがとうございました。勉強になりました。

関連するQ&A

  • 正規表現を使用したCHECK制約

    alter tableでカラムにCHECK制約を付けて、エラーとなるようなデータをsqlldrでローディングしたのですが、想定通りにエラーとならなくて困っています。 CHECK制約はこのようなものです。 ALTER TABLE TABLE_XXX ADD( constraint ck_A check (REGEXP_REPLACE(列A, '[0-9]{4}','') = '') ); 列Aの値が半角数字4桁以外のデータはローディングエラー(別ファイルに出力)にしたいのですが、すんなりとテーブルに格納されてしまいます。 ちなみに同様に付けたprimary key制約は正常に機能しているので、正規表現がいけないのでは?と推測しますが。。。 想定通りにするためには、どのように記述したら良いのでしょうか? 正規表現、Oracle共に勉強し始めの為、本など読んでいるのですが、なかなか良い資料が手元になく困っています。 よろしくお願いします。

  • CASEの中でAND を使う事はできますか?

    CASE WHEN (name1 IS NOT NULL AND name1 !="") THEN name1"; CASE WHEN (name2 IS NOT NULL AND name2 !="") THEN name2"; ELSE 'NO NAME' こういう事をしたいんですが、できますでしょうか? 同じ意味で違う方法でも良いのですが…。

  • DB2でUNIQUE制約を削除したい

    DB2で以下のように明示的な名前のないUNIQUE制約を削除したいのですが、よい方法をご存じの方がおられましたらご教授ください。 (例) 1. 表の作成 CREATE TABLE TEST ( COL1 INT NOT NULL) 2. 明示的な名前を作成せずにUNIQUE制約を作成 ALTER TABLE TEST ADD UNIQUE (COL1); 上記のように名前指定しなかったUNIQUE制約を ALTER TABLE文で削除したいのですが、どのように すればよろしいのでしょうか? マニュアルの構文では制約名を指定する必要あるようで、 syscat.tabconstカタログで自動でつけられた制約名を調べた後、 以下のように指定したところ制約は削除されました。 (例) ALTER TABLE TEST DROP CONSTRAINT SQL090123084403480 しかしプログラムの修正が少なくなるよう、制約名を調べずにALTER TABLE 一文で削除できないものかと悩んでおります。 もしくはストアドプロシージャでも構いません。 よろしくお願いします。

  • caseを使った条件分岐の加算がうまくいかない

    SQLで条件によって加算するか、しないかを判定したいと思っています。 ■テーブル:test name,flag,number mike,4,1 mike,4,2 mike,5,3 mike,6,4 mike,7,5 mike,8,6 mike,9,7 ■書いたSQL SELECT test.name AS "name", (CASE WHEN flag = '4' THEN sum(number) ELSE NULL END) AS "4", (CASE WHEN flag = '5' THEN sum(number) ELSE NULL END) AS "5", (CASE WHEN flag = '6' THEN sum(number) ELSE NULL END) AS "6", (CASE WHEN flag = '7' THEN sum(number) ELSE NULL END) AS "7", (CASE WHEN flag = '8' THEN sum(number) ELSE NULL END) AS "8", (CASE WHEN flag = '9' THEN sum(number) ELSE NULL END) AS "9" FROM test GROUP BY test.name ■結果 4,5,6,7,8,9 null,null,null,null,null,28 欲しい結果は、フラグが4ののものの合計。flagが「4」の場合は、「3」という結果が返ってきてもらいたいです。 flagが5の場合は、3が返ってきてもらいたいです。 SQLが間違っているのですが、どこが間違っているのかわかりません。どのように修正すればよろしいでしょうか?よろしくお願いします。 環境はSQLiteを使用しています。

  • SQL Server Where句 Case文

    お世話になります。 Where句のCase文でお尋ねしたいことがあります。 ----------------------------------------------------- WHERE (A = @A) AND (B = @B) AND (C = @C) AND CASE WHEN @D = 0 THEN (dbo.TEST.D = dbo.TEST.D) '全データを WHEN @D = 1 THEN (dbo.TEST.D = 1) '値が1のデータを WHEN @D = 2 THEN (dbo.TEST.D = Is Null) 'データがNull のものを END AND (E = @E) AND (F = @F) AND (G = @G) AND (H = @H) AND CASE WHEN @I = 0 THEN (dbo.TEST.I = dbo.TEST.I) WHEN @I = 1 THEN (dbo.TEST.I = 1) WHEN @I = 2 THEN (dbo.TEST.I = Is Null) END AND (J = @J) ........ ........ ----------------------------------------------------- 上記のように CASE 文で パラメータの値により条件を変えたいのですが、なかなかうまくいきません。こんな記述の仕方ではダメということは薄々わかっているのですが、このようなCASE文をうまく動作させるにはどのように記述すればいいでしょうか? よろしくお願いいたします。

  • Access BetweenとLikeの組み合わせ方

    Access2000(初心者) フォームで Between(指定日~指定日)の中でLike(チェック)を含まないレコードを検索削除したいです。 下記コードの場合 実行時エラー'3061': パラメータが少なすぎます。1を指定してください。 のエラーが出てしまいます。 どこを直せば良いでしょうか?宜しくお願いします。 CurrentDb.Execute "DELETE * FROM テーブル名 WHERE ([テーブル名].[日付] Between #2009/01/01# And #2009/02/02#) AND ((([テーブル名].[チェックボックス]) Like 'No')); "

  • case文のand句について

    1:nの関係にあるヘッダテーブルと明細テーブルを結合後、case文で行列変換し取得しています。 抽出結果が想定外の場合があるのですが(なぜか想定とおりの場合もあります)、 case文で違うフィールドをand条件にすることはできないのでしょうか? やはり、ネストする必要がありますか? ↓このSQLだと、明細.区分=2の場合に、金額が取得できません。 select   ユーザ   ,sum(case when 明細.区分 = 1 and 明細.月 = 1 then 明細.金額 end) as 1月請求金額   ,sum(case when 明細.区分 = 1 and 明細.月 = 2 then 明細.金額 end) as 2月請求金額 , ・・・   ,sum(case when 明細.区分 = 2 and 明細.月 = 1 then 明細.金額 end) as 1月支払金額   ,sum(case when 明細.区分 = 2 and 明細.月 = 2 then 明細.金額 end) as 2月支払金額 , ・・・ from ヘッダ left join 明細 on ヘッダ.キー = 明細.キー group by ユーザ

  • WHERE句でのCASEについて

    WHERE句でのCASEの使い方についてご教授下さい。 以下の3分岐でSELECTしようとしています。 項目A=1なら、 項目B / 1000=10 のデータを。 項目A=2なら、 項目C=C のデータを。 項目A=3なら、 項目B / 1000=10 かつ項目D=D のデータを。 ※しばらくPCに触れないので確認不可ですが以下は試みたい方法です。 ただ心配なのは、例えば項目A=1のときに項目B / 1000 = 10を満たすデータと満たさないデータが存在する場合、 満たすデータまでもが抽出されないのではという心配があります。 SELECT * FROM テーブル WHERE 1 = CASE WHEN 項目A=1 THEN CASE WHEN 項目B / 1000 = 10 THEN 1 ELSE END WHEN 項目A=2 THEN CASE WHEN 項目C = C THEN 1 ELSE END WHEN 項目A=3 THEN CASE WHEN 項目B / 1000 = 10 AND 項目D = D THEN 1 ELSE END ELSE END

  • CASE式を使ったクエリ

    <環境>SQLSERVER2005 件名について教えてください。 テーブル("TBL")にフィールドMONEY1~MONEY12までがあります。 MONEYの後ろの数字は月を表しています。 このテーブルから 1.MONEY12の値≠0円ならMONEY12の値。MONEY12の値=0円ならMONEY11の値を参照。 2.MONEY11の値≠0円ならMONEY11の値。MONEY11の値=0円ならMONEY10の値を参照。 3.MONEY10の値≠0円ならMONEY10の値。MONEY10の値=0円ならMONEY9の値を参照。 と0円でない月までさかのぼってその月の金額を求めたいのですが、 下記のようにCASE式を使うと「Case 式は、10 レベルまでしか入れ子にできません。」と エラーになります。 条件式が11レベル以上の場合抽出する方法はないのでしょうか SELECT CASE WHEN MONEY12>0 THEN MONEY12 ELSE CASE WHEN MONEY11>0 THEN MONEY11 ELSE CASE WHEN MONEY10>0 THEN MONEY10 ELSE CASE WHEN MONEY9>0 THEN MONEY9 ELSE CASE WHEN MONEY8>0 THEN MONEY8 ELSE CASE WHEN MONEY7>0 THEN MONEY7 ELSE CASE WHEN MONEY6>0 THEN MONEY6 ELSE CASE WHEN MONEY5>0 THEN MONEY5 ELSE CASE WHEN MONEY4>0 THEN MONEY4 ELSE CASE WHEN MONEY3>0 THEN MONEY3 ELSE CASE WHEN MONEY2>0 THEN MONEY2 ELSE CASE WHEN MONEY1>0 THEN MONEY1 ELSE 0 END END END END END END END END END END END END FROM TBL

  • SQLのBetween句

    SQL初心者です。 どなたかヒントでもよいのでご教授お願いします。 分からない箇所は以下の2つです。(SQLは下方に示しています) ・where句のbetweenの箇所にカラム指定箇所にTO_CHAR(SYSDATE -2, 'YYYYMMDD') を入れた時、何を評価しているのか? ・where句のbetweenの条件部分のカラム名に(+)をつけた場合何を意味しているのか? この2つがどうしても分かりません。 このSQLについて知識お持ちに方よろしくお願いします。 環境は次の通りです。 ------------------------ ■環境 ・OracleDatabase10.2 ■テーブル構成 テーブルは以下の2つです。 ・sample1 ・sample2 sample1テーブルに以下のカラムがあります。 ・test1 sample2テーブルに以下のカラムがあります。 ・test2 ------------------------ ■SQL SELECT * FROM sample1 s1, sample2 s2 WHERE TO_CHAR(SYSDATE -2, 'YYYYMMDD') BETWEEN s1.STAYMD(+) AND s2.(+)