identityテーブルの誤差を修正する方法
identityテーブルの誤差を修正する方法
0.改訂履歴
1.はじめに
このドキュメントでは,Sybase ASEで,大きな誤差が発生したIdentityの値を修正する方法を説明する.
なお,使用しているSybaseは,RedHat Linux 7.2上で稼働しているSybase SQL Server
11.0.3.3である.
2.処理概略
- 誤差の修正作業用に,同じフォーマットのテーブルを2つ作成する.
- TABLE_Bは,identity属性をつけない.
- TABLE_Cは,identity属性をつけるので,TABLE_Aと同じものになる.
- 最初に,insert intoを使ってデータをTABLE_Bに複写する.
- 作業テーブルで,update文を使い,データを変更する.
- 変更したデータを,TABLE_Cに複写する.
- TABLE_AとTABLE_Bのオブジェクト名を変更して,データを入れ替える.
- このような作業を行う事で,修正できる.
- なお,今回はIdentityフィールドを外部キーで使っているような場合の影響範囲については考えていない.
3.準備:誤差の発生したテーブルを作成する
- TABLE_Aを作成して,適当にデータを入れる.
- identity_insertを使って,誤差を作成する.
1> create table TABLE_A
2> (
3> aa numeric(10,0) identity,
4> bb char(10)
5> )
6> go
1> insert into TABLE_A values("iMovie")
2> insert into TABLE_A values("iTunes")
3> insert into TABLE_A values("iPhoto")
4> set identity_insert TABLE_A on
5> insert into TABLE_A (aa,bb) values(2000,"Classic")
6> set identity_insert TABLE_A off
7> insert into TABLE_A values("ClassicII")
8> go
(1 row affected)
(1 row affected)
(1 row affected)
(1 row affected)
(1 row affected)
1> select * from TABLE_A
2> go
aa bb
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
2000 Classic
2001 ClassicII
(5 rows affected)
1>
|
- ここで表示されている,aa>=2000になる条件のレコードのidentity値を修正する.
4.データの変換作業を行う
- 作業用テーブルTABLE_Bを作成する.
- なお,ここではTABLE_Bのフィールド名はわかりやすいように大文字にした.
1> create table TABLE_B
2> (
3> AA numeric(10,0),
4> BB char(10)
5> )
6> go
1>
|
- TABLE_Aのデータを,TABLE_Bに持ってくる.
1> insert into TABLE_B (AA,BB) select aa,bb from TABLE_A
2> go
(5 rows affected)
1>
|
1> select * from TABLE_B
2> go
AA BB
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
2000 Classic
2001 ClassicII
(5 rows affected)
1>
|
- 正しく複写されている.
- identityが2000以上のデータについて,一律1900を引く.
1> update TABLE_B set AA = AA - 1900
2> where AA>=2000
3> go
(2 rows affected)
1>
|
1> select * from TABLE_B
2> go
AA BB
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
100 Classic
101 ClassicII
(5 rows affected)
1>
|
5.修正済みテーブルに格納する
- 修正済みデータを格納する為に,TABLE_Cを作成する.
- テーブル定義はTABLE_Aと同じなので,技!を使う.
1> select * into TABLE_C from TABLE_A where 1=2
2> go
(0 rows affected)
1>
|
- select * intoはテーブルがコピーされるが,where句で条件が一致していないので,テーブル定義だけコピーされている.
- 作成されたTABLE_Cの情報を確認する
1> sp_help TABLE_C
2> go
Name Owner
Type
------------------------------ ------------------------------
----------------------
TABLE_C dbo
user table
Data_located_on_segment When_created
------------------------------ --------------------------
default Aug 14 2002 2:49PM
Column_name Type Length Prec Scale Nulls Default_name
Rule_name Identity
--------------- --------------- ------ ---- ----- ----- ---------------
--------------- --------
aa numeric 6 10 0 0 NULL
NULL 1
bb char 10 NULL NULL 0 NULL
NULL 0
Object does not have any indexes.
No defined keys for this object.
Object is not partitioned.
(return status = 0)
1>
|
- ちゃんとIdentity属性もコピーされている.
- TABLE_Bに入っている修正済みのデータを,TABLE_Cに格納する.
- TABLE_Cのidentity_insertを設定しておく.
1> set identity_insert TABLE_C on
2> go
1> insert into TABLE_C (aa,bb) select AA,BB from TABLE_B
2> go
(5 rows affected)
1>
1> select * from TABLE_C
2> go
aa bb
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
100 Classic
101 ClassicII
(5 rows affected)
1>
1> set identity_insert TABLE_C off
2> go
1>
|
1> insert into TABLE_C values("Performa")
2> go
(1 row affected)
1> select * from TABLE_C
2> go
aa bb
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
100 Classic
101 ClassicII
102 Performa
(6 rows affected)
1>
|
6.テーブルをすり替える
- データ編集後の整ったデータがTABLE_Bに格納されているので,それとTABLE_Aを入れ替える.
1> sp_rename TABLE_A,TABLE_A_OLD
2> go
Object name has been changed.
(return status = 0)
1> sp_rename TABLE_C,TABLE_A
2> go
Object name has been changed.
(return status = 0)
1> select * from TABLE_A
2> go
aa bb
------------- ----------
1 iMovie
2 iTunes
3 iPhoto
100 Classic
101 ClassicII
102 Performa
(6 rows affected)
1>
|