最近因為正在進行【ASP․NET Core 3 開發實戰:從入門到進階】課程,上課的學員中使用 macOS 來學習 .NET Core 的人越來越多,當練習到 ASP․NET Core 搭配 Entity Framework Core 的時候,因為會用到 SQL Server 進行練習,所以本篇文章將分享如何利用 Docker 執行 SQL Server on Linux 容器,並分享幾個常用的工具命令與使用範例。
下載 SQL Server 2019 容器映像 (docker pull)
從 SQL Server 2019 CU3 開始,已經支援 Ubuntu 18.04 版本。
從 SQL Server 2019 CU10 開始,已經支援 Ubuntu 20.04 版本。
你可以透過以下命令下載容器映像:
sudo docker pull mcr.microsoft.com/mssql/server:2019-latest
目前從 Microsoft SQL Server - Docker Hub 可以查到的 image tag 比較舊,反而從 Quickstart: Run SQL Server container images with Docker 官方文件可以查到最新版本。
如果想下載 RHEL-based 容器映像,可以查閱這份文件說明。
sudo docker pull mcr.microsoft.com/mssql/rhel/server:2019-CU1-rhel-8
執行 SQL Server 2019 容器 (docker run)
以下是 docker run
使用範例:
sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Ver7CompleXPW" \
-p 1433:1433 --name sql1 \
-d mcr.microsoft.com/mssql/server:2019-latest
設定 SA_PASSWORD
的時候必須符合密碼複雜性要求:
- 密碼不包含使用者的帳戶名稱,也就是不能包含
sa
這個字。
- 密碼長度至少為 8 個字元,密碼長度最多可達 128 個字元。
- 密碼包含下列四種類別的其中三種:
- 拉丁文大寫字母 (A 到 Z)
- 拉丁文小寫字母 (a 到 z)
- 以 10 為基底的數字 (0 到 9)
- 非英數字元,例如:驚嘆號 (!)、錢幣符號 ($)、數字符號 (#) 或百分比符號 (%)
執行容器實際範例
sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Ver7CompleXPW" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2019-latest
進入容器執行
-
進入容器 bash 環境
sudo docker exec -it sql1 "bash"
容器中 sqlcmd
工具的路徑為 /opt/mssql-tools/bin/sqlcmd
-
變更 SA 帳號密碼
由於預設的 SA 帳戶密碼是透過環境變數 SA_PASSWORD
傳入的,你只要進入 bash
執行 ps -eax | cat
或 set
就可以看到密碼。基於安全理由,你可以透過以下命令變更 SA 密碼:
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd \
-S localhost -U SA -P "Ver7CompleXPW" \
-Q 'ALTER LOGIN SA WITH PASSWORD="YourNewStrong@Passw0rd"'
-
進入 sqlcmd
互動模式
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -U SA -P Ver7CompleXPW -W
上述命令的 -W
(大寫 W 字母) 選項會從資料行中移除尾端的空格,否則通常執行結果很難閱讀。
在 SQLCMD 中執行 T-SQL 最後要輸入 GO
命令才會執行。
例如你想查詢當前執行的 SQL Server 版本,就要輸入以下命令:
SELECT @@VERSION
GO
如果要退出 sqlcmd
互動模式,請輸入以下命令:
QUIT
-
直接從本機連接 SQL Server 容器
由於我們執行 SQL Server 容器時,已經加上 -p 1433:1433
參數,因此你可以從本機的 localhost:1433
連接容器中的 SQL Server 服務。
如果你的本機已經有安裝 SQL Server 任意版本,通常會包含 sqlcmd
用戶端工具,當你使用 -S
參數指定伺服器名稱時,要加上 Port 埠號必須用 localhost,1433
這種格式,主機名稱與埠號之間是用「逗號」分隔喔!
sqlcmd -S localhost,1433 -U SA -P "Ver7CompleXPW" -W
常見 T-SQL 查詢
-
列出資料庫清單
sudo docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -W -Q "SELECT name FROM sys.databases"
-
批次執行 T-SQL 命令 (例如:匯入資料庫)
# 下載 ContosoUniversity.sql 檔案
curl -o ContosoUniversity.sql https://gist.githubusercontent.com/doggy8088/2a2f7075d49b3814d19513426ede3549/raw/ab95b323425ff98e99b901793d0361d90439fb0b/ContosoUniversity.sql
# 複製檔案進 sql1 容器
sudo docker cp ContosoUniversity.sql sql1:/
# 批次執行指定的 T-SQL 檔案
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -i ContosoUniversity.sql
-
建立資料庫
假設資料庫名稱為 test1
,你可以用以下命令建立一個空資料庫:
sudo docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -W -Q "CREATE DATABASE [test1]"
-
啟動容器並還原資料庫
以下命令可以在 WSL 2 環境執行:
# 準備還原指令碼
cat <<EOF > restore.sql
-- 請記得先修改備份檔實體路徑
USE [master]
RESTORE DATABASE [mydb] FROM DISK = N'/var/opt/mssql/backup/mydb.bak' WITH FILE = 1,
MOVE N'mydb' TO N'/var/opt/mssql/data/mydb_Primary.mdf',
MOVE N'mydb_log' TO N'/var/opt/mssql/data/mydb_Primary.ldf', NOUNLOAD, STATS = 5
GO
-- 清空交易記錄 (開發環境不需要)
ALTER DATABASE [mydb] SET RECOVERY SIMPLE WITH NO_WAIT
GO
-- 壓縮資料庫
DBCC SHRINKDATABASE(N'mydb')
GO
EOF
# 啟動容器並將 /mnt/c/TEMP/DB 掛載到容器的 /var/opt/mssql/backup 目錄下
sudo docker run --name sql1 -p 1433:1433 \
-e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Ver7CompleXPW' \
-v '/mnt/c/TEMP/DB:/var/opt/mssql/backup' \
-d mcr.microsoft.com/mssql/server:2019-latest
# 查看容器啟動紀錄 (確保服務已正常啟動)
sudo docker logs sql1 -f
# 還原資料庫 (其中包含截斷交易記錄與壓縮資料庫)
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Ver7CompleXPW' -i '/var/opt/mssql/backup/restore.sql' -e
# 查看資料檔大小
sudo docker exec -it sql1 bash -c 'ls -l /var/opt/mssql/data/mydb*'
-
備份資料庫
以下命令可以在 WSL 2 環境執行:
# 準備備份指令碼
cat <<EOF > backup.sql
BACKUP DATABASE [mydb]
TO DISK = N'/var/opt/mssql/backup/mydb.bak' WITH COPY_ONLY, FORMAT, INIT,
NAME = N'mydb-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,
COMPRESSION, STATS = 10
GO
EOF
# 備份資料庫 (包含壓縮備份檔)
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Ver7CompleXPW' -i '/var/opt/mssql/backup/backup.sql' -e
-
刪除資料庫
假設資料庫名稱為 test1
,你可以用以下命令刪除資料庫:
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -Q "DROP DATABASE [test1]"
如果資料庫因為還有既有連線而無法刪除,可以改用以下命令:
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -Q "ALTER DATABASE [test1] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [test1]"
相關連結