Help us understand the problem. What is going on with this article?

†闇† テーブル定義(SQLServer)に対する呪いの解呪法、そして蘇生の秘術

More than 1 year has passed since last update.

はじめに

この記事は闇の魔術に対する防衛術 Advent Calendar 2018の24日目の記事です。

近況

現在、主業務でSQLServerを使ってるのですが、
今の会社は中途入社でして、入社する前のシステムに関しては何をやってきたのかはよくわからん状況なのですよ。
特に(自称)DBAっぽい動きをしてた人が入社の6年前に突然の失踪。ノー引き継ぎでフィニッシュしたらしく、
✨技術的負債MAX✨ の状態からそれを切り戻すのが昨今の私のミッションとなっております。

制約

弊社は上がITに無理解なので、システムは原則、
24/365でダウンタイム0で動き続けると思っています。
当然、そんな事ができるわけはないのですが、一応そんな雰囲気は醸し出さないといけません。
いわゆるシュレディンガーの猫みたいなやつです。にゃーん。

✨技術的負債MAX✨ とは?

吉幾三先生の「俺ら東京さ行ぐだ」風にまとめると以下のような状態です。
・概要設計書も無ェ
・基本設計書も無ェ
・当然詳細設計書も無ェ
・テストもそれほど走って無ェ
・担当者も1人しか残って無ェ
・開発からそろそろ20年

要はソースコードとデータしかないです。
入って思ったのは、「すげえ… 良く動いてたなこいつ!」みたいな感じ。

へいしゃのでーたべーす

別に社外公開してるシステムでもないし、一応SELECT @@VERSIONした結果を貼っておきますね。
(あまり意味は無いとは思うけど)

SELECT @@VERSION

  ↓結果↓

Microsoft SQL Server 2014 (SP2-CU11) (KB4077063) - 12.0.5579.0 (X64) 
    Feb 21 2018 12:19:47 
    Copyright (c) Microsoft Corporation
    Standard Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: )

ふういんされた のろいが いま ときはなたれる!

で、テーブルのカラムの定義が今更間違ってたやつがある事がわかり、
カラムの定義を変えたい(int→Varchar2(3))
※注:もともと入ってるのがMAX数字3桁であることは保証されている

という状況になったので、まあサクサクっとAlter Table Alter Column文を流し込んでみたのですよ。
すると…

Alter Table [hogehoge].[hogehogeテーブル] Alter Column hogehogeコード nvarchar(3)

  ↓結果↓

SQL   : Alter Table [hogehoge].[hogehogeテーブル] Alter Column hogehogeコード nvarchar(3)
SQL   : ALTER TABLE ALTER COLUMN hogehogeコード は失敗しました。1 つ以上のオブジェクトがこの列を参照しています。
オブジェクト 'UW_ZeroDefault' は 列 'hogehogeコード' に依存しています。

なんか依存性があって更新に失敗してるようです。
そしていろいろ調べたのですが、どうにもsys.sysobjectsとsys.columnsから情報を引いてもこの依存性が拾えませんでした。
(単純に私の調べ方が下手なのかもしれない)

よくわかんなくなってきたのでA5:SQLさんの力を借りて、テーブル定義を見てみたところ

create table [hogehoge].[hogehogeテーブル] (
  hogehogeID int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0 not null
  , hogehogeID2 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
  , hogehogeID3 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
  , hogehogeID4 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
  , hogehogeID5 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
  , hogehogeID6 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
  , hogehogeID7 int default CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0
(以下略)
  , primary key (hogehogeID)
);

なんか謎の定義がいっぱいおる。
「CREATE DEFAULT hogehoge.UW_ZeroDefault AS 0」って何なん!?
色々調べてみたところ、なんか移行マネージャを使ってAccessからテーブル引越をすると
現代に召喚されてしまう闇の魔術(※もはやよくわからない制約)だそうです。

実際、単純に「default 0」となっていればいいだけのところを何かの定義を嵌めてしまう模様。
もはや実質、のろいですやん… ( ゚д゚)ポカーン

なお、幾度の大戦を超えて生き残った伝説の戦士(※一人だけ残ってる担当者)に
古代の知恵(開発時から残っている属人的な知識みたいな情報がいっぱいあるので…)を伺っても
「よくわからない」というお返事が。

もう、どうしようもないので、解呪をこころみたいとおもいます。

ささやき - いのり - えいしょう - ねんじろ!

いまわたしたちに必要なのは現代におけるカント寺院のアレです。
エクスペクト・パトローナムでもいいかもしれませんが。

今回、私たちは現代におけるカント寺院のアレの部分的な再現に成功しました!
以下、詳細なアレの手順を解説していきましょう。

新しい魂(※データ)の入れものを創る

A5SQLで出てきたCREATE TABLE文を置換してアレしましょう。
(" CREATE DEFAULT hogehoge.UW_ZeroDefault AS " → NULL)します。

すると、普通にテーブル定義がDBで通せるようになりましたね。
テーブル名は仮に後ろにでも_WKとかつけておきましょう。
(移行して問題なかったらそのうち元データは消すので)

create table [hogehoge].[hogehogeテーブル_WK] (
  hogehogeID int default 0 not null
  , hogehogeID2 int default 0
  , hogehogeID3 int default 0
  , hogehogeID4 int default 0
  , hogehogeID5 int default 0
  , hogehogeID6 int default 0
  , hogehogeID7 int default 0
(以下略)
  , primary key (hogehogeID)
);

蘇生の秘術を用いて魂(※データ)を救済(※データ移植)する

アレな秘術を使えば、綺麗な肉体に魂を移植する事ができますね。
(※綺麗すぎてオプティマイザ的にアレかもしれませんが気にせず対応。)
先の制約がある関係で、ここからはアキラ100%顔負けレベルの早業が必要です。
控え目にいって ‡闇‡ を感じますが、気にしてはいけません。

まず(※データ)を移植します。

INSERT INTO hogehogeテーブル_WK
 SELECT * 
 FROM   hogehogeテーブル
;

次に老いた体(※現行テーブル)の名前を変更します。
※この世界線にはsp_renameがあって本当によかった…

sp_rename 'hogehogeDB.hogehogeテーブル', 'hogehogeテーブル_WK';

最後に新しい体(※新テーブル)の名前を老いた体(※現行テーブル)の名前に変更します。

sp_rename 'hogehogeDB.hogehogeテーブル_WK', 'hogehogeテーブル';

これで魂が救済されましたね! 尊い…

おわりに

結局のところ既存の定義がクソすぎてどうしようもない時は
サクッと新テーブル切って移植したほうが早い という話でした。

今日はクリスマス・イブですね。
メリークルシミマス!(言いたかっただけ)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away