項目の重複値を回避する方法とは?

このQ&Aのポイント
  • 2つの項目で重複値を入力させない方法について
  • 地点間の距離を保存するテーブルで逆区間の登録を制約する方法
  • 登録時に自前でチェックする方法の他にはないか
回答を見る
  • ベストアンサー

2つの項目で重複値を入力させない

以下のような地点間の距離を保存するテーブルで、逆区間を登録させたくない場合は どのような制約をかければよいでしょうか。 CREATE TABLE DISTANCE_TBL ( S_POS CHAR(1), -- スタート地点 E_POS CHAR(1), -- ゴール地点 DISTANCE NUMBER(6) -- 距離 ) S_POS='A'、E_POS='B'がすでに登録されていた場合に S_POS='B'、E_POS='A'を登録させたくありません。 「CONSTRAINT CK_DISTANCE CHECK (S_POS < E_POS)」 として、登録時に自前でチェックするぐらいしか思いつきませんでした。 なにかよい方法があればご教授願います。

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

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

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

ファンクション索引を使ってみるとか? http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19248-02/adfns_indexing.htm#494614 例えばこんな感じで。 CREATE UNIQUE INDEX UK_DISTANCE ON DISTANCE_TBL (CASE WHEN S_POS < E_POS THEN S_POS || E_POS ELSE E_POS || S_POS END)

yasulu
質問者

お礼

「CONSTRAINT CK_DISTANCE CHECK (S_POS < E_POS)」 としてS_POS<E_POSとなるようにINSERT文をちゃんと書くことで対応することにしました。 ありがとうございました。

yasulu
質問者

補足

ご提示の内容試してみました。 indexですと重複内容を弾けないので、以下のようにしてみました。 ALTER TABLE DISTANCE_TBL ADD CONSTRAINT UK_DISTANCE UNIQUE (CASE WHEN S_POS<E_POS THEN S_POS||E_POS ELSE E_POS||S_POS END) / そうしたところ、無効な識別子ですとエラーとなってしまいました。

関連するQ&A

  • 複数カンマの位置を保存するためには

    いろいろと試したのですが、うまくいかず質問させて頂ければと思います。 現在、以下のようなテーブルとデータがあります。 テーブル名: sample_tbl ID string_char 1 a<d<b<aa<dd<<b<87<hg< 2 1f3f<3rtf<33e<rf<dd<rf<rf<ed<rf<rf 3 f<44fg<rf< これをCHARINDEXなどで分割し、以下のようなテーブルを作りたいのです。'<'の場所の位置、最大9個まで保存したいのです。IDはすべてユニークです。 ID string_char                    pos_1 pos_2 pos_3(pos_9まで) 1 a<d<b<aa<dd<<b<87<hg<             2   4   6 2 1f3f<3f<e<rf<d<rf<<d<rf<rf            5   8   10 3 f<44fg<rf                        2   7   0 私が取った方法は単純なもので、最初にCHARINDEXでpos_1を出したあとにその位置から'<'の場所を数えて足していく非効率で、ディスクの容量を取ってしまい、時間がかかる方法でした。Pos_9までいくのは大変でした。もし効率的な方法があればどうかよろしくご教授ください。

  • 外部結合

    外部結合でどうしても理解できないパターンがあるので どなたか詳しい人がいたら教えてください。 ・まず、テーブルは下記のa_tblとb_tblの2テーブルです。  SQL> desc a_tbl;  名前 型  ------ ---------------  A1 CHAR(4)  A2 CHAR(4)  A3 CHAR(1)  SQL> desc b_tbl;  名前 型  ------ -----------  B1 CHAR(4)  B2 CHAR(4)  B3 CHAR(1) ・それぞれの内容は、  SQL> select * from a_tbl;  A1 A2 A3  ---- ---- -  1001 A001 1  1002 A002 0  1003 A003 1  1004 A004 0  1005 A005 1  SQL> select * from b_tbl;  B1 B2 B3  ---- ---- -  1001 B001 1  1002 B002 0  1003 B003 1  1004 B004 0 ・この2つのテーブルに対して、下記のselectを行います。  SQL> select * from a_tbl, b_tbl where b1(+)=a1 and b3(+)='1';  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1002 A002 0  1003 A003 1 1003 B003 1  1004 A004 0  1005 A005 1 ・私の予想では、下記の様になると思ったのですが、結果は  上記の様になります。  どのような考え方をすれば上記の結果になるのか教えてください。  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1003 A003 1 1003 B003 1

  • PL/SQLのCREATE文でCHAR型で項目ができない

    PL/SQLで以下のようにCREATE文を発行しました。 Bテーブルの項目 項目1,'1'を持つテーブルを作成したいのです。 DECLARE  KBN CHAR(1);  WK_SQL VARCHAR2(4000); BEGIN  KBN := '1';  WK_SQL := 'CREATE TABLE A_TBL AS    SELECT B.項目1 , ' || KBN || ' AS A項目    FROM B_TBL B ' ;  EXECUTE IMMEDIATE WK_SQL; END; 結果はA_TBLの項目、A項目がどうしてもNUMBER型になるのです。初心者で、質問に不備なところもあるかもしれませんが、どうすればよいか、ご教授ください。

  • 高校物理Iの電位です。

    画像のA地点での電位と、B地点での電位はそれぞれE地点とF地点からの距離が等しいから全く同じで、A地点での電位とC地点での電位はそれぞれE地点とF地点からの距離が等しくないから、 同じではなく、 A地点での電位とD地点での電位も同じですが、なぜそうなるのかがわかりません。 ご回答よろしくお願いいたします。

  • アマゾンで新しい商品を登録する方法

    あたらしい商品を登録したいのですが、どうやったらいいのでしょうか? また、同じ商品なのに、別の商品として多数登録されている事がありますが、これはどういった事なのでしょう?? http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&url=search-alias%3Daps&field-keywords=%E9%A6%99%E6%B0%B4%E3%80%80%E3%83%91%E3%83%B3%E3%83%89%E3%83%A9&rh=i%3Aaps%2Ck%3A%E9%A6%99%E6%B0%B4%E3%80%80%E3%83%91%E3%83%B3%E3%83%89%E3%83%A9

  • 図に示すように,A 地点とB 地点の間に幅100m の川がある。A 地

    図に示すように,A 地点とB 地点の間に幅100m の川がある。A 地点からC 地 点までの距離は500m,B 地点からD 地点までの距離は300m,A 地点とB 地 点の間の距離は1200m である。この川に直交する橋EF を,経路AEFB が最短 となるようにつくりたい。C 地点からE 地点までの距離を求めよ。

  • test.csvの内容

    test.csvの内容 "a","b","c","d" "e","f","g","h" "i","j","k","l" "m","n","o","p" "q","r","s","t" "u","v","w","x" "あ","い","う","え" "か","き","く","け" "さ","し","す","せ" "た","ち","つ","て" とし、真ん中のq,r,s,t以降の内容を表示させたく、下のようなプログラムを作成しました しかし、コンパイル後実行しようとするとエラーになってしまいます。どう直したらよいか教えて頂けますでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME "test.csv" #define SIZE 32 struct tb{ char a[SIZE]; char b[SIZE]; char c[SIZE]; char d[SIZE]; }; int main(void) { struct tb test; FILE *fp; char buff[SIZE]; long pos; pos=ftell(fp); fseek(fp,pos,SEEK_SET); while(fgets(buff,SIZE,fp) != NULL){ //各項目の設定 strcpy(test.a,strtok(buff,",\"")); strcpy(test.b,strtok(NULL,",\"")); strcpy(test.c,strtok(NULL,",\"")); strcpy(test.d,strtok(NULL,",\"")); printf("%s %s %s %s \n",test.a,test.b,test.c,test.d); } }

  • 最大値が入力されている列見出しを返す関数

    Excelで表を↓のような表を作成し、    A地点 B地点 C地点 D地点 距離 100  200  300  400 「距離が最長の"地点名"を返す」ための関数がありましたら教えてください。 ↑の場合は、"400"が入力されている"D地点"が返ってくるような…。 よろしくお願いいたします。

  • カーソルで値取得

    あるテーブルから頭から10件分 カーソルで値を取得するようにしていましたが、 元々下記のようだったものを… CURSOR cursor_name IS SELECT TBL_A.E_ID,TBL_A.C_ID FROM (SELECT E_ID,C_ID,ROW_NUMBER() OVER( ORDER BY E_ID ) RN  FROM TBL_A) TBL_A WHERE RN BETWEEN 1 AND 10;     ↓ CURSOR cursor_name IS SELECT TBL_A.E_ID, TBL_M.S_ID, TBL_M.S_NAME, TBL_U.USER_ID FROM ((TBL_A INNER JOIN TBL_EU ON TBL_A.E_ID = TBL_EU.E_ID) INNER JOIN TBL_U ON TBL_EU.S_ID = TBL_U.S_ID) INNER JOIN TBL_M ON TBL_EU.S_ID = TBL_M.S_ID WHERE (((TBL_EU.DIVISION)="2")); というように取得する値をふやしたいのですが、元にあった (SELECT E_ID,C_ID,ROW_NUMBER() OVER( ORDER BY E_ID ) RN  FROM TBL_A) TBL_A WHERE RN BETWEEN 1 AND 10; をどこに組み込んでいいのかわらず困っております。 どなかた教えて頂けないでしょうか?お願いいたします。

  • 拡散方程式について

    拡散方程式について、問題を解いているのですが、理解できないところがあります。 A地点からB地点まで物質を流したとき(水中に)B地点での濃度はいくらになるか、という問題です。 U,E,S,W,xの値はわかっていますが、tの値が与えられていません。tはどのようにして求めればいいのでしょうか。移流と拡散なのでAからBまでの距離を速度で割るという考え方は違いますよね? 拡散方程式は C=W/S√4πEt×exp[-(x-Ut)^2/4Et] どなたかわかる方教えてください。よろしくお願いします。