※当サイトの記事には、広告・プロモーションが含まれます。

Oracle Databaseで指定の位置にカラムを追加したい

gigazine.net

⇧ 制御できないってなったら怖いですが...

Oracle Databaseで指定の位置にカラムを追加したい

PostgreSQLとかだと、

wiki.postgresql.org

postgresqlの初心者の多くからよく、テーブル内の列の位置を変更することはサポートされているかどうか聞かれます。 今のところサポートされていません。 列の位置を変更したいのであれば、テーブルを再作成するか、新しい列を追加してデータを移動するかのいずれかを行う必要があります。 

https://wiki.postgresql.org/wiki/Alter_column_position/ja

postgresで列位置の変更できたら便利になる理由が大きく2つあります。

  1. テーブルの先頭にサイズが固定の列を置くことで物理的なレイアウトが最適化できること
  2. 視覚効果が高い順序の結果セットを格納、または、テーブルに対する同様な関数に基づいて列をグループ化することにより、 列の順序付けがテーブルへの作業を簡単にすることができること。

https://wiki.postgresql.org/wiki/Alter_column_position/ja

⇧ 位置を指定してカラムを追加するのがサポートされてない旨が周知されてるっぽいのですが、Oracle Databaseだと特にドキュメントが見当たらない...

stackoverflowによると、

stackoverflow.com

Oracle Database 12cからは、テーブル再作成しなくてもカラムの追加位置を指定できるっぽいのだけど、基本的には、テーブル再作成するしかないらしい...

しかも、

forums.oracle.com

Oracle Databaseのコミュニティだと、カラムの追加で位置指定するのは重要じゃない、って意見も出てるんですが、まずは、質問に対しての解決方法を回答して欲しいよね...。

とりあえず、

it.notepad-blog.com

⇧ テーブル再作成するしか無さそうですかね...

Oracleの公式のドキュメントで、指定の位置にカラムを追加するユースケースでの対応方法が見つけられんかったので、正解が分からんのだけども。

試してみました。

ALTER TABLE TS0818.USER_DETAIL RENAME TO USER_DETAIL_BK;

DROP TABLE TS0818.USER_DETAIL;

CREATE TABLE TS0818.USER_DETAIL (
    USER_DETAIL_ID CHAR(13) NOT NULL,
    USER_ID CHAR(13) NOT NULL,
	LAST_NAME VARCHAR2(255) NOT NULL, 
	FIRST_NAME VARCHAR2(255) NOT NULL, 
	GENDER VARCHAR2(50) NOT NULL, 
	BIRTHDAY DATE NOT NULL, 
	ADDRESS_ID CHAR(20), 
	INSERT_USER VARCHAR2(50) NOT NULL, 
	INSERT_DATE TIMESTAMP (6) NOT NULL, 
	UPDATE_USER VARCHAR2(50), 
	UPDATE_DATE TIMESTAMP (6), 
	DELETE_FLG CHAR(1) NOT NULL, 
	DELETE_DATE TIMESTAMP (6), 
	PRIMARY KEY (USER_DETAIL_ID),
	CONSTRAINT FK_USER_DETAIL FOREIGN KEY (USER_ID)
	REFERENCES TS0818.USERS (USER_ID)
);

DROP SEQUENCE TS0818.USER_DETAIL_SEQ;
CREATE SEQUENCE TS0818.USER_DETAIL_SEQ MINVALUE 1 MAXVALUE 9999999999999 INCREMENT BY 1 START WITH 1 CACHE 10 NOORDER NOCYCLE;

CREATE OR REPLACE TRIGGER TS0818.USER_DETAIL_TRIGGER 
BEFORE INSERT ON TS0818.USER_DETAIL 
FOR EACH ROW
DECLARE

BEGIN
  IF :new.USER_DETAIL_ID IS NULL THEN
    :new.USER_DETAIL_ID := to_char(USER_DETAIL_SEQ.nextval);
  END IF;
END;
/

INSERT INTO TS0818.USER_DETAIL (
  USER_DETAIL_ID,
  USER_ID,
  LAST_NAME, 
  FIRST_NAME, 
  GENDER, 
  BIRTHDAY, 
  ADDRESS_ID, 
  INSERT_USER, 
  INSERT_DATE, 
  UPDATE_USER, 
  UPDATE_DATE, 
  DELETE_FLG, 
  DELETE_DATE
)
SELECT 
  TS0818.USER_DETAIL_SEQ.nextval,
  USER_ID,
  LAST_NAME, 
  FIRST_NAME, 
  GENDER, 
  BIRTHDAY, 
  ADDRESS_ID, 
  INSERT_USER, 
  INSERT_DATE, 
  UPDATE_USER, 
  UPDATE_DATE, 
  DELETE_FLG, 
  DELETE_DATE
FROM TS0818.USER_DETAIL_BK
;
/
commit;
/

⇧ 追加したカラムにINSERTするデータは、適当にSequenceの値にしてしまったので、全く実用的でないけども...

で、データとかもINSERTできてるのを確認できたら、退避テーブルを削除。

DROP TABLE USER_DETAIL_BK;    

今回、Sequenceを作り直していますが、Sequenceを作り直す場合は、

ts0818.hatenablog.com

⇧ 上記の記事で取り上げていた、値のズレに気を付けねばですかね。

あとは、Sequenceと紐づけたカラムのデータ型がCHAR型ってのがそもそもイケてない気がする...何か、IDだと数字以外も有り得ると思ってCHAR型にしたんだっけな?

毎度モヤモヤ感が半端ない...

今回はこのへんで。