MicrosoftSQL Server 2016 Express LocalDB で気軽に DB を試す

[ブログからの転載](http://1bed.allright.life/?p=2257)

PowerShell を使って DB にあんなことやこんなことを試してみたかった。ちょっとだけだよ。

Visual Studio 2015 を試している時に「LocalDB」とかいう文字列を見た覚えがあったので、調べて実際に試してみた備忘録。

# MicrosoftSQL Server 2016 Express LocalDB とは

公式より引用

> Microsoft SQL Server 2016 Express LocalDB の実行モードは、開発者を対象とした SQL Server Express の実行モードです。
> 
> LocalDB インストールによって、 SQL Server データベース エンジンの開始に最低限必要なファイルがコピーされます。 LocalDB のインストール後に、特殊な接続文字列を使用して接続を開始できます。 接続時に、必要な SQL Server インフラストラクチャが自動的に作成および開始されるため、複雑な構成タスクを行わなくてもアプリケーションでデータベースを使用できます。 開発者ツールによって、開発者は SQL Server データベース エンジンを使用して Transact-SQL コードを記述してテストすることができ、SQL Server の完全なサーバー インスタンスを管理する必要はありません。

乱暴に要約すると、開発者向けで必要最小限の SQL Server ということかな。
便利っぽい気がする。

インストール等は参考サイトに載っているので割愛。Visual Studio をインストールしている人は気がついたらインストールされていたりしないかな？ 自分がこのパターンです ＾＾；

SqlLocalDB を扱うには、SqlLocalDB ユーティリティ (SqlLocalDB.exe) を利用します。


# SqlLocalDB とは

> MicrosoftSQL Server 2016 Express LocalDB のインスタンスを作成するには、SqlLocalDB ユーティリティを使用します。 SqlLocalDB ユーティリティ (SqlLocalDB.exe) は、ユーザーおよび開発者が SQL Server Express LocalDB のインスタンスを作成および管理できるようにするシンプルなコマンド ライン ツールです。


# SqlLocalDB を使用して LocalDB を利用する

## PowerShell を起動

まずは PowerShell を管理者モードで起動します。

## インスタンスを作成する

新しいインスタンス `misono` を作成してみます。

```ps1
PS> SqlLocalDB.exe create "misono"
LocalDB インスタンス "misono" はバージョン 13.0.1100.286 で作成されました。
```

## インスタンス情報を取得する

ユーザー所有のインスタンス情報を取得します。

```ps1
PS> SqlLocalDB.exe info
misono
MSSQLLocalDB
```

作成されているだけで嬉しくなる名前にして良かったです。

詳細な情報を取得するときには、引数にインスタンス名を指定します。

```ps1
PS> SqlLocalDB.exe info misono
名前:               misono
バージョン:         13.0.1100.286
共有名:
所有者:             マシン名\ユーザー名
自動作成:        いいえ
状態:              停止
前回の開始時刻:    2016/09/18 0:48:42
インスタンス パイプ名:
```

## インスタンスを起動する

状態が停止しているので起動します。

```ps1
PS> SqlLocalDB.exe start misono
LocalDB インスタンス "misono" が開始されました。
```

状態を確認してみます。

```ps1
PS> SqlLocalDB.exe info misono
名前:               misono
バージョン:         13.0.1100.286
共有名:
所有者:             マシン名\ユーザー名
自動作成:        いいえ
状態:              実行中
前回の開始時刻:    2016/09/18 1:03:18
インスタンス パイプ名: np:\\.\pipe\LOCALDB#パイプ名\tsql\query
```

状態が実行中に変わりました。

## sqlcmd で接続してみる

私の環境では `sqlcmd` へパスが通っていませんでしたので、次のコマンドでとりあえずパスを通しました。

```ps1
PS> $Env:Path += "C:\Program Files\Microsoft SQL Server\110\Tools\Binn;"
```

sqlcmd で LocalDB へ接続してみます。

```ps1
PS> sqlcmd -S np:\\.\pipe\LOCALDB#パイプ名\tsql\query
1> 
```

データベース一覧を取得するコマンドを流してみます

```sql
1> select name, create_date from sys.databases
2> GO
name
         create_date
--------------------------------
-------- -----------------------
master
         2003-04-08 09:13:36.390
tempdb
         2016-09-18 01:43:38.743
model
         2003-04-08 09:13:36.390
msdb
         2016-02-27 13:31:02.847

(4 行処理されました)
```

## データベースを作成する

データファイルやトランザクションログファイルを指定せずにデータベース miyamiya を作成します。

```sql
1> CREATE DATABASE miyamiya
2> GO
```

再度データベース一覧を取得してみます。

データベース一覧を取得するコマンドを流してみます

```sql
1> select name, create_date from sys.databases
2> GO
name
         create_date
--------------------------------
-------- -----------------------
master
         2003-04-08 09:13:36.390
tempdb
         2016-09-18 01:43:38.743
model
         2003-04-08 09:13:36.390
msdb
         2016-02-27 13:31:02.847
miyamiya
         2016-09-18 02:03:18.887

(5 行処理されました)
```

## sqlcmd から抜ける

```sql
1> quit
```

# PowerShell で Create Table を流してみる

インスタンス misono のデータベース miyamiya に PowerShell から接続する

```ps1
$con = New-Object -TypeName System.Data.SqlClient.SqlConnection
$con.ConnectionString = "Server=(localdb)\misono;Initial Catalog=miyamiya;Integrated Security=true"

$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = "CREATE TABLE test (id INT PRIMARY KEY, name VARCHAR(MAX))"
$cmd.ExecuteNonQuery()

$con.Close()
$cmd.Dispose()
$con.Dispose()
```

# PowerShell で Insert を流してみる

```ps1
$con = New-Object -TypeName System.Data.SqlClient.SqlConnection
$con.ConnectionString = "Server=(localdb)\misono;Initial Catalog=miyamiya;Integrated Security=true"

$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = "INSERT INTO test(id, name) VALUES(1, 'hoge')"
$cmd.ExecuteNonQuery()
$cmd.CommandText = "INSERT INTO test(id, name) VALUES(2, 'fuga')"
$cmd.ExecuteNonQuery()

$con.Close()
$cmd.Dispose()
$con.Dispose()
```

# PowerShell で select を流してみる

```ps1
$con = New-Object -TypeName System.Data.SqlClient.SqlConnection
$con.ConnectionString = "Server=(localdb)\misono;Initial Catalog=miyamiya;Integrated Security=true"

$con.Open()
$cmd = $con.CreateCommand()
$command.CommandText = "SELECT * FROM test"
$adapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter $command
$dataset = New-Object -TypeName System.Data.DataSet
$adapter.Fill($dataset)
$dataset.Tables[0]

$dataset.Dispose()
$adapter.Dispose()
$con.Close()
$cmd.Dispose()
$con.Dispose()
```


# 考察

少し試したい時に手軽で良さそうな感じがする

# 参考

* [Developer Network: SQL Server 2016 Express LocalDB](https://msdn.microsoft.com/ja-jp/library/hh510202.aspx)
* [Developer Network: SqlLocalDB ユーティリティ](https://msdn.microsoft.com/ja-jp/library/hh212961.aspx?f=255&MSPPError=-2147217396)
* [Developer Network: CREATE DATABASE (SQL Server Transact-SQL) - 使用例](https://msdn.microsoft.com/ja-jp/library/ms176061.aspx?f=255&mspperror=-2147217396#Anchor_9)