文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

【驚愕】SQLServer2008は指定位置にカラムを追加できない【ツール強要】

ええ・・・


f:id:treeapps:20180418131549p:plain

普段MySQLを使っているのですが、今回SQLServerを触りました。

(;^ω^)<待て待て待て!!

と思う事に遭遇しました。このSQLServerですが、なんと・・・

指定位置にカラムが追加できない

のです。

正確にはできるのですが、MySQLのようにコマンド1発ではできません。
基本的にSQLServerはほとんどの操作をGUIで行う事を想定しているようで、ManagementStudioというWindows専用ツール上でしか操作できないものもあります。

ManagementStudio上では、一旦新規カラムを追加して、マウスでドラッグドロップして自由に位置を変更する事ができます。GUI使いたくない・・
そもそも私はMacなので、いちいちWindowsを起動しないといけないのが本当に嫌です。

では、ManagementStudioがどうやってカラム位置を変更しているのか、
MySQLとどれくらいSQLが違うのか、についてまとめてみます。

サンプルケース

以下のcreate文を使います。

create table test (
    col1 varchar(10),
    col2 varchar(10),
    col4 varchar(10)
);

この状態で、カラム2とカラム4の間に、新規にカラム3を追加します。
これだけです。

MySQL

mysqlの場合は以下のように簡単に追加できます。

alter table test add col3 varchar(10) after col2;

普通のRDBではこれくらい簡単に指定位置にカラムを追加できます。

SQLServer2008

SQLServer2008の場合は以下のように追加できます。

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_test
	(
	col1 varchar(10) NULL,
	col2 varchar(10) NULL,
	col3 varchar(10) NULL,
	col4 varchar(10) NULL
	)  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_test SET (LOCK_ESCALATION = TABLE)
GO
IF EXISTS(SELECT * FROM dbo.test)
	 EXEC('INSERT INTO dbo.Tmp_test (col1, col2, col4)
		SELECT col1, col2, col4 FROM dbo.test WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.test
GO
EXECUTE sp_rename N'dbo.Tmp_test', N'test', 'OBJECT' 
GO
COMMIT

(;^ω^)<何この長さ!?

このSQLは、ManagementStudioでGUI上で自動生成されたSQLです。
やっていることは、一旦最終形のテーブルを新規に作成し、現行テーブルから新テーブルにデータをinsertし、最後にテーブル名を入れ替えることで、カラム追加を擬似的に再現しています。
わざわざこんな長いコマンドを実行しないといけないのです

改善して欲しい点

前述の自動生成されたSQLは特に問題ありません。
MySQLでも、新旧テーブルを入れ替える手法はよく使われます。
ここで問題なのは、

コマンド1発で実行できない点にある

のです。例えば前述の

alter table test add col3 varchar(10) after col2;

これを実行すると、内部的に先ほどの長いSQLに変換して実行してくれるならOKです。
それができなからダメなんです。こんな長いコマンドを逐一入力させちゃダメです。

まあ実はその長いSQLにも問題があって、「Tmp_test」という名前が自動で振られてますが、既にその名前のテーブルがあったらどうなるのかな、と思います。
もしかしたら空気呼んでTmp2_testとかしてくれるのでしょうかね。
2とか3とかでなく、完全にユニークなテーブル名になるように配慮するべきだと私は思いますが。

総評

私はあらゆる操作をコマンドラインのみで操作したい派です。
しかし、SQLServerはMSの意向??で、GUIを使って欲しいようです。
RDBに慣れている人ほどコマンドラインの操作を好む傾向がありますが、MSは全く逆方向を目指しているのでしょうか・・・・

GUI上で操作するとオペレーションに時間が掛かり過ぎるし、
バッチ処理も気軽にできません・・・
なんとかして下さいよMSさん・・・・