シーケンスの値を更新したい【DB2】

DBのシーケンスの値の更新でかなり苦戦したので、メモしておきます。

# シーケンスを作る
とりあえず、こんな感じで作っておきます。

<pre>
db2 => CREATE OR REPLACE SEQUENCE TEST.SQ_aaaa AS DECIMAL(11) START WITH 1 INCREMENT BY 1 MINVALUE 0 MAXVALUE 99999999999
</pre>

# シーケンス作成した人がシーケンスを更新する場合
例として、次にシーケンスを取得したときに「100」がとれるようにしたいとします。
①と②のどっちがいいかは時と場合によるのかなぁと思います。

## ① CREATE OR REPLACE で作り直す。
<pre>
db2 => CREATE OR REPLACE SEQUENCE TEST.SQ_aaaa AS DECIMAL(11) START WITH 100 INCREMENT BY 1 MINVALUE 0 MAXVALUE 99999999999
DB20000I  SQL コマンドが正常に完了しました。
db2 => SELECT SEQNAME, START FROM SYSCAT.SEQUENCES WHERE SEQNAME = 'SQ_AAAA'

SEQNAME                                                                                                                          START
-------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
SQ_AAAA                                                                                                                                                       100.

  1 レコードが選択されました。

db2 => select NEXT VALUE FOR TEST.SQ_aaaa from sysibm.dual

1
-------------
         100.

  1 レコードが選択されました。
</pre>

これを行うとSTARTの値が変わり、次回にとるシーケンスの値も変わります。

## ② ALTER文を流す。

(7/10編集：SVC34さんのコメントを参考にNEXTCACHEFIRSTVALUEもSELECT文に入れてみました。)

<pre>
db2 => ALTER SEQUENCE TEST.SQ_aaaa RESTART WITH 100
DB20000I  SQL コマンドが正常に完了しました。
db2 => SELECT SEQNAME, START, NEXTCACHEFIRSTVALUE FROM SYSCAT.SEQUENCES WHERE SEQNAME = 'SQ_AAAA'

SEQNAME                                                                                                                          START                             NEXTCACHEFIRSTVALUE
-------------------------------------------------------------------------------------------------------------------------------- --------------------------------- ---------------------------------
SQ_AAAA                                                                                                                                                         1.                                1.

  1 レコードが選択されました。

db2 => select NEXT VALUE FOR TEST.SQ_aaaa from sysibm.dual

1
-------------
         100.

  1 レコードが選択されました。

db2 => SELECT SEQNAME, START, NEXTCACHEFIRSTVALUE FROM SYSCAT.SEQUENCES WHERE SEQNAME = 'SQ_AAAA'

SEQNAME                                                                                                                          START                             NEXTCACHEFIRSTVALUE
-------------------------------------------------------------------------------------------------------------------------------- --------------------------------- ---------------------------------
SQ_AAAA                                                                                                                                                         1.                              120.

  1 レコードが選択されました。

</pre>

①とは違い、STARTの値は変わりませんが、次に取得するシーケンスの値が変わります。

(7/10追記 SVC34さんのコメントより)
ALTER実行直後のNEXTCACHEFIRSTVALUEは一時的にSTARTの値に戻りますが、NEXT VALUEが要求されるとALTERで指定した値（+ CACHE）に変更されます。


# シーケンス作った人以外の人がシーケンスの値を変更したい場合
## ①をやろうとすると・・・

<pre>
db2 => CREATE OR REPLACE SEQUENCE TEST.SQ_aaaa AS DECIMAL(11) START WITH 100 INCREMENT BY 1 MINVALUE 0 MAXVALUE 99999999999
DB21034E  コマンドが、有効なコマンド行プロセッサー・コマンドでないため、 SQL
ステートメントとして処理されました。  SQL 処理中に、次のエラーが返されました。
SQL0551N  許可 ID
に必要な許可がない、または操作を実行する特権がないため、ステートメントが失敗しま
した。許可 ID: "TEST"。操作: "REPLACE SEQUENCE"。オブジェクト:
"TEST.SQ_AAAA"。  SQLSTATE=42501
</pre>

エラーが発生します。
[IBMのホームページ](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_10.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0004202.html)を見ながら、「ALTER権限」とか「USAGE権限」とか与えてみましたが、エラーは変わりませんでした。
もし、わかる方がいたら教えていただきたいです。
とりあえず、私の環境で試した限りではうまくいきません。

## ②をやろうとすると・・・

<pre>
db2 => ALTER SEQUENCE TEST.SQ_aaaa RESTART WITH 100
DB20000I  SQL コマンドが正常に完了しました。
db2 => select NEXT VALUE FOR TEST.SQ_aaaa from sysibm.dual

1
-------------
         100.

  1 レコードが選択されました。
</pre>

成功しました。
もし権限系のエラーが出たら、「ALTER権限」を与えればいいかと思います。
今のところ、作成者以外でシーケンスの値を更新するとしたら②しかなさそうな感じです。

# 感想
②もSTARTの値が変更されるものだと思いこみ、しばらく悩みました。
せっかくだから、投稿してみました。
※スキーマ名とユーザー名は一応実際のものと変えてあります。