作業ノート

様々なまとめ、雑感など

Oracleのシーケンスの取得値を所定値に変更する

OracleのDBで、シーケンス値を使用するカラムを持つテーブルのデータを移行するときに起きる問題。

Oracleでは、シーケンスとテーブルは別に扱う。このため、テーブルのデータを移行するときには あわせてシーケンスの値も変更しないと、値が重複してしまうことになる。

主キーの値としてシーケンスを使用することは多く、その値が制約違反により登録できない、といった現象が起きる。

この現象を避けるためには、シーケンスの取得値が移行データとかぶらないようにする必要があるのだが、シーケンスの値を簡単に変更するようなSQL文は存在しない。

そこでいくつかのSQL文を実行して、最終的に取得値を所定値にすることになる。

以下は例として、foo_seqというシーケンスの取得値を11にするための手順。

1. シーケンスを削除する

シーケンスが存在するときは、一旦削除する。

DROP SEQUENCE foo_seq;

2. シーケンスを作成する

シーケンスを作成する。初期値、最小値、増分値を全て1にする。

CREATE SEQUENCE foo_seq START WITH 1 MINVALUE 1 INCREMENT BY 1;

3. 増分値を変更する

ALTER文で増分値を10に変更する。この値は、開始したい値(11)から1を引いたもの。

ALTER SEQUENCE foo_seq INCREMENT BY 10;

4. シーケンス値を取得する

SELECT文で、このシーケンスの値の現在を取得する。

SELECT foo_seq.nextval FROM dual;

   NEXTVAL
----------
        10

これによって、シーケンスの値が10になる。

5. 増分を1にする

増分を1に戻す。

ALTER SEQUENCE foo_seq INCREMENT BY 1;

これで、次回のシーケンスの取得では11になる。

SQL> SELECT foo_seq.nextval FROM dual;

   NEXTVAL
----------
        11

参考

Oracleユーザの有効期限を変更する

会社の開発環境でOracle 12cのDBを構築し、その確認時に作成したユーザに有効期限がついていた。

意識的にそのような設定をした憶えはなく、期限が過ぎて無効になると困るので、設定の確認と無制限にする対応を行った。以下はその手順。

1. sysdbaでログインする

Oracleのサーバにsshでログインし、sqlplusコマンドでsysdbaとしてログインする。

$ sqlplus /nolog

SQL> conn / as sysdba
接続されました。

2. 有効期限に関する設定を確認する

ユーザの有効期限はユーザプロファイルに設定があるので、今の設定内容を確認する。

SQL> set linesize 200
SQL> set tab off
SQL> col profile format a32
SQL> col limit format a32

SQL> select * from dba_profiles where resource_name = 'PASSWORD_LIFE_TIME';

PROFILE                          RESOURCE_NAME                    RESOURCE LIMIT                            COM
-------------------------------- -------------------------------- -------- -------------------------------- ---
DEFAULT                          PASSWORD_LIFE_TIME               PASSWORD 180                              NO

対象の有効期限は180日。

3. 有効期限を無期限にする

alter profileでdefaultプロファイルの有効期限を無期限に変更する。

SQL> alter profile default limit password_life_time unlimited;

プロファイルが変更されました。

変更後、先ほどのSQLを再実行すると、設定が無期限に変更されたことが確認できる。

SQL> select * from dba_profiles where resource_name = 'PASSWORD_LIFE_TIME';

PROFILE                          RESOURCE_NAME                    RESOURCE LIMIT                            COM
-------------------------------- -------------------------------- -------- -------------------------------- ---
DEFAULT                          PASSWORD_LIFE_TIME               PASSWORD UNLIMITED                        NO

参考

コマンドの先頭にバックスラッシュをつける理由

RVMをインストールする機会があり、手順を確認してインストールした。

\curl -sSL https://get.rvm.io | bash -s stable

このときcurlの先頭に\がついているのが気になり、付けない場合と何が違うのか調べた。

\つける理由は、shellのエイリアスの影響を受けないようにするため。

エイリアスはある単語を別の単語に置換するためのリスト。コマンドの先頭の単語がこのリストに一致するときに、別の単語に置換する。ただし、その単語がクォートされているときは置換されない。

一方で、\はそのあとの1文字をクォートするエスケープ文字で、\curlは先頭の一文字のみクォートした単語となる。これがエイリアスの条件を満たさないようで、これを狙った記法のようだ。

前述のとおり、単語がクォートされているときは置換されないので、コマンドを

'curl' -sSL https://get.rvm.io | bash -s stable

シングルクォートや

"curl" -sSL https://get.rvm.io | bash -s stable

ダブルクォートで囲んでも同様で、エイリアスは適用されない。

参考