• ベストアンサー
  • すぐに回答を!

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 一文で削除できないものかと悩んでおります。 もしくはストアドプロシージャでも構いません。 よろしくお願いします。

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

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

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

OS名、DB2のバージョンは、何でしょうか? >DB2のストアドプロシージャでは動的にDDL文を組み立てて実行することができないよう ちょっと信じがたいのですが、「EXECUTE IMMEDIATEの実行不可」と言ってますか? 別にストアドプロシジャじゃなくても、いいのですよ。 システムカタログを検索して、テキストファイルに書き出すのでもいいのです。 書き出すときに、 'ALTER TABLE TEST DROP CONSTRAINT "' 検索で得た制約名 '";' を文字列で組み立てて、ALTER TABLE文を作ればいいのです。 これを実行すれば、目的は達成できませんか?

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

質問者からのお礼

JAVAプログラムで制約名を取得してから、ALTER TABLE文を作成して実行する方法で解決しました。 どうもありがとうございました。

質問者からの補足

chukenkenkouさん、 回答いただき、ありがとうございます。 環境はDB2/LINUX 8.2.7 です。 前提として、保守用のSQLテキストスクリプト内にSQL文を記述して実行 しているので、制約名を知らべてから動的にSQL文を組み立てて実行、という処理が保守用のSQLテキストスクリプト内で完結できるかどうか調べていました。外部のプログラム言語は使わないというのが前提です。 もし"EXECUTE IMMEDIATE"で動的SQLの実行が、SQLのストアドプロシージャか、BEGIN ATOMIC - END で呼び出しで使用できるなら可能かもしれませんが、ちょっと無理そうだったので。。。 そろそろタイムリミットなので、Javaでシステムカタログを検索してから、ALTER文を実行というように保守用のプログラムを作ろうと思っています。 もしも、そんなことせずに、テキストのSQLスクリプトだけでできる!という方法をご存じでしたらよろしくお願いします。

その他の回答 (1)

  • 回答No.1

DB2に限った話ではないですが、一般的な考え方としては、次のどちらかでは? (1)制約名を明示的に付ける。 (2)制約名を意識したくないなら、システムカタログを検索して名称を得て、ALTER PROGRAM文を文字列で生成し、実行するストアドプロシジャを作る。

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

質問者からの補足

ご指摘のとおり、新規のシステムには制約名を明示的につけているのですが、古いシステムにかなりの数の制約が名前なしで生成されているのです。 DB2のストアドプロシージャでは動的にDDL文を組み立てて実行することができないようなので困っていました。 もし、DB2で動的にDDLを実行できる方法あればご教授いただける助かります。

関連するQ&A

  • Oracleの制約構文に関して

    Oracleの外部キー(参照整合性)制約に関して質問です。 定義済みの列制約に対して、追加の定義方法がわかりません。 CREATE TABLE TMP (T_COL1 NUMBER(4) CONSTRAINT PK_COL1 PRIMARY KEY, T_COL2 VARCHAR2(10) CONSTRAINT U_COL2 UNIQUE, T_COL3 NUMBER(2) CONSTRAINT FK_COL3 REFERENCES EMP(E_COL1) ); 上記のSQL文を実行した後にT_COL3の制約に"ON DELETE CASCADE" を追加する方法を教えて頂けますでしょうか?

  • MYSQLのフィールドにユニークキーを設定する。

    すでに作ってしまったテーブルにユニークキーを付けたいと考えています。最悪の場合、新しくカラムを作っての追加でもかまわないのですが、いろいろ試してもエラーが返されてしまいます。 codeというカラムにユニークキーを設定したいのですが、 alter table テーブル名 modify unique code; alter table テーブル名 add unique code2; alter table テーブル名 modify code unique; alter table テーブル名 add code2 unique; alter table テーブル名 modify code test unique; alter table テーブル名 add code2 test unique; alter table テーブル名 modify unique code test; alter table テーブル名 add unique code2 test; alter table テーブル名 modify (code unique); alter table テーブル名 add (code2 unique); alter table テーブル名 modify (code text unique); alter table テーブル名 add (code2 text unique); など、思いつく限り試し、グーグルで調べる限り調べたのですが、出てきたものをためしてもダメでした。 テーブルを作成した後、カラムにユニークキーを設定した経験のある方、どのように変更をしたのでしょうか?

    • ベストアンサー
    • MySQL
  • alter table で text が midiumtext になってしまう

    当初作ったテーブル(テーブル名=test)では col1 char(10) unique not null, col2 text not null, col3 text not null, col4 text not null だったのですが、col1だけをchar→varcharに変えたくて alter table test modify col1 varchar(10) unique not null としたところ、他のtext型項目が全てmidiumtextになってしまいました。 ひとつずつtextに直そうと alter table test modify col2 text not null を実行し次に alter table test modify col3 text not null とするとcol3はtextになるがcol2がまたmidiumtextになってしまいます。 midiumtextほどの容量は必要ないのでcol2~col4をtextに戻したいのですが、 どのようにすればよいのでしょうか。 ご教示願います。 宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • NOT NULL 制約の削除

    MSSQL(SQLServer2000)にて、NOT NULLの列制約をはずすにはどうしたらよいのでしょうか。 ALTER TABLE <テーブル名> ALTER COLUMN <列名> DROP NOT NULL をやってみたのですが、構文エラーになってしまいます。 よろしくお願いします。

  • PostgreSQLの「not null」制約の追加

    こんにちは。いつもお世話になります。 PostgreSQLのversion7.2.8で、「not null」制約の追加、削除の方法をおたずねします。よろしくお願いします。 ALTER TABLE テーブル名 ALTER COLUMN カラム名 SET NOT NULL; で試したところ、syntaxエラー(構文エラー)で失敗。 ALTER TABLE テーブル名 ALTER COLUMN カラム名 DROP NOT NULL; で試してみても、同じくsyntaxエラーです。 version7.2.8が原因でしょうか? また、version7.2.8でも「not null」制約の追加、削除が できる他の方法はありますでしょうか? テーブルを作り直さずに、 既存のテーブルのカラムへの制約の追加、削除をしようとしています。 よろしくお願いします。

  • Mysqlのconstraintについて教えてください (難題)

    回答者がつかなかったので再度。 Q1.単順にKEY指定するのとどこが違うのですか? show indexで見た限り、下記の(1)と(3)の違いが分かりません。 Q2.constraint_nameはどこに行ってしまったのですか? show indexで見ると、unique(it1)で指定した項目it1がそのままインデックス名になります。 constraint_nameで指定した名前はどこに行ったのでしょうか? (1)constraintで定義、インデックス名を指定。 mysql> create table t1 (it1 tinyint(1),constraint constraint_name unique(it1)); (2)UNIQUE KEYで定義、インデックス名を指定。 mysql> create table t2 (it1 tinyint(1),UNIQUE KEY UNIQUE_KEY_NAME (it1)); (3)UNIQUE KEYで定義、インデックス名=Key項目名。 mysql> create table t3 (it1 tinyint(1),UNIQUE KEY it1 (it1));

  • 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で上記のような制約をつけることは可能でしょうか?

  • 複数のカラムを対象にしたプライマリキー制約の設定

    テーブル作成後に複数のカラムを対象にしたプライマリーキー制約を設定することはできるのでしょうか。 テーブル作成時であれば、次の方法により設定することができます。 ※col_name1及びcol_name2に設定したい場合 CREATE TABLE tbl_name (col_name1 int NOT NULL, col_name2 int, col_name3 varchar(255), PRIMARY KEY(col_name1, col_name2)); しかし、一旦テーブルを作成した後に、プライマリーキー制約を設定し忘れたことに気が付き、設定したい場合は、いかなる方法によりできるのでしょうか。 次の方法にて試みたものの、エラーが生じました。 【SQL文】 ALTER TABLE tbl_name MODIFY col_name1 int, col_name2 int, PRIMARY KEY(col_name1, col_name2); 【エラー内容】 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 'col_name2 int, PRIMARY KEY(col_name1, col_name2)' at line 1 テーブルを削除し、再作成時にプライマリーキー制約を設定する方法によっても対応できますが、削除しなくてもこれを行える方法があるのか否かを知りたく、質問させていただきました。

    • ベストアンサー
    • MySQL
  • 複数テーブルで ID の一意性を保つ

    Debian GNU/Linux 3.1 で psql 8.1.2 を使用しています。 下記の要領でテーブルを作成し、2つのテーブルでIDが重ならないようにしようと意図しました。 CREATE TABLE t1 ( t1_id int2 UNIQUE NOT NULL, t1_name text NOT NULL ); NOTICE: CREATE TABLE / UNIQUE will create implicit index "t1_t1_id_key" for table "t1" CREATE TABLE CREATE TABLE t2 ( t2_id int2 UNIQUE NOT NULL, t2_name text NOT NULL ); NOTICE: CREATE TABLE / UNIQUE will create implicit index "t2_t2_id_key" for table "t2" CREATE TABLE CREATE FUNCTION unique_t12_id(int2) RETURNS BOOLEAN AS 'SELECT NOT ( EXISTS(SELECT * FROM t1 WHERE t1_id = $1) AND EXISTS(SELECT * FROM t2 WHERE t2_id = $1) );' LANGUAGE SQL; CREATE FUNCTION ALTER TABLE t1 ADD CONSTRAINT con_unique_t12 CHECK (unique_t12_id(t1_id)); ALTER TABLE ALTER TABLE t2 ADD CONSTRAINT con_unique_t12 CHECK (unique_t12_id(t2_id)); ALTER TABLE ところが実際は上手くいきませんでした。 INSERT INTO t1 VALUES(1, 'test1'); INSERT 0 1 INSERT INTO t2 VALUES(2, 'test2'); INSERT 0 1 INSERT INTO t2 VALUES(2, 'test3'); ERROR: duplicate key violates unique constraint "t2_t2_id_key" # ここまでは期待通りの挙動です INSERT INTO t2 VALUES(1, 'test4'); INSERT 0 1 ここで制約が働いて欲しかったのですが、素通りでINSERTされています。 下記のように、操作後の関数の戻り値は「偽」なのでこの操作は制約に引っかかると思うのですが 何故意図したように動かないのでしょうか。 SELECT *,unique_t12_id(t2_id) FROM t2; t2_id | t2_name | unique_t12_id -------+---------+--------------- 2 | test2 | t 1 | test4 | f (2 rows) スペースが詰まって読みづらい箇所もありますが、よろしくお願いします。

  • 正規表現を使用した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共に勉強し始めの為、本など読んでいるのですが、なかなか良い資料が手元になく困っています。 よろしくお願いします。