为什么Docker中的MSSQL在SQL查询中返回“由于用户按下CTRL + C,所以上次操作已终止”?

Mat*_*air 5 sql linux sql-server docker

我在使用Docker(版本18.06.0-ce,内部版本0ffa8257ec)的Archlinux 64x(4.17.4-1-ARCH)上。我正在使用Microsoft的MSSQL docker容器CU7。每次尝试输入查询或运行SQL文件时,都会收到以下警告消息:

Sqlcmd: Warning: The last operation was terminated because the user pressed CTRL+C.
Run Code Online (Sandbox Code Playgroud)

然后,当我使用Datagrip检入数据库时​​,尚未执行查询!这是我的命令:

docker pull microsoft/mssql-server-linux:2017-CU7
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=GitGood*0987654321" -e "MSSQL_PID=Developer" -p 1433:1433 --name beep_boop_boop -d microsoft/mssql-server-linux:2017-CU7

# THIS

sudo echo "CREATE DATABASE test;" > /test.sql
docker exec beep_boop_boop /opt/mssql-tools/bin/sqlcmd -U SA -P GitGood*0987654321 < test.sql

# OR

docker exec beep_boop_boop /opt/mssql-tools/bin/sqlcmd -U SA -P GitGood*0987654321 -Q "CREATE DATABASE test;"
Run Code Online (Sandbox Code Playgroud)

我的问题是如何避免operation was terminated by user对MSSQL查询发出警告警告?

Gab*_*oux 3

你应该使用docker-compose,我相信它会让你的生活更轻松。我的猜测是您在实际上不知道的情况下收到了错误。第一次尝试时,我使用了不安全的密码,不符合安全要求,并收到此错误:

错误:无法设置系统管理员密码:密码验证失败。该密码不符合 SQL Server 密码策略要求,因为它不够复杂。密码长度必须至少为 8 个字符,并包含以下四组中的三组字符:大写字母、小写字母、基数 10 的数字和符号。

我看到您的密码很强大,但请注意您*的密码中有一个,如果未正确转义,该密码可能会被执行。

或者使用命令行运行时服务器未启动,例如:

# example of a failing attempt
docker run -it --rm -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=GitGood*0987654321' -p 1433:1433 microsoft/mssql-server-linux:2017-CU7 bash
# wait until you're inside the container, then check if server is running
apt-get update && apt-get install -y nmap
nmap -Pn localhost -p 1433
Run Code Online (Sandbox Code Playgroud)

如果它没有运行,您会看到类似的内容:

Starting Nmap 7.01 ( https://nmap.org ) at 2018-08-27 06:12 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000083s latency).
Other addresses for localhost (not scanned): ::1
PORT     STATE  SERVICE
1433/tcp closed ms-sql-s

Nmap done: 1 IP address (1 host up) scanned in 0.38 seconds
Run Code Online (Sandbox Code Playgroud)

介绍已经足够了,这是一个可行的解决方案:

docker-compose.yml

Starting Nmap 7.01 ( https://nmap.org ) at 2018-08-27 06:12 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000083s latency).
Other addresses for localhost (not scanned): ::1
PORT     STATE  SERVICE
1433/tcp closed ms-sql-s

Nmap done: 1 IP address (1 host up) scanned in 0.38 seconds
Run Code Online (Sandbox Code Playgroud)

然后运行以下命令并等待图像准备就绪:

docker-compose up -d
docker-compose logs -f &
Run Code Online (Sandbox Code Playgroud)
  • up -d妖魔化容器,使其继续在后台运行。
  • logs -f将读取日志并遵循(类似于tail -f
  • &在后台运行命令,这样我们就不需要使用新的 shell

现在让 bash 在该容器内运行,如下所示:

docker-compose exec db bash
Run Code Online (Sandbox Code Playgroud)

进入图像后,您可以运行命令

/opt/mssql-tools/bin/sqlcmd -U SA -P $SA_PASSWORD -Q "CREATE DATABASE test;"
/opt/mssql-tools/bin/sqlcmd -U SA -P $SA_PASSWORD -Q "SELECT name FROM master.sys.databases"
Run Code Online (Sandbox Code Playgroud)

请注意我如何SA_PASSWORD在此处重用环境变量,因此不需要重新输入密码。

现在享受结果

name
--------------------------------------------------------------------------------------------------------------------------------
master
tempdb
model
msdb
test

(5 rows affected)
Run Code Online (Sandbox Code Playgroud)

为了正确设置,我建议environment用以下行替换密钥docker-compose.yml

version: '2'
services:
  db:
    image: microsoft/mssql-server-linux:2017-CU7
    container_name: beep-boop-boop
    ports:
      - 1443:1443
    environment:
      ACCEPT_EULA: Y
      SA_PASSWORD: GitGood*0987654321
Run Code Online (Sandbox Code Playgroud)

这样,您可以将机密存储在您的外部docker-compose.yml,并确保您不会.env在版本控制中进行跟踪(您应该添加.env到您的存储库中.gitignore.env.example在存储库中提供适当的文档。

这是一个示例项目,确认它可以在 Travis-CI 中工作:
https://github.com/GabLeRoux/mssql-docker-compose-example

其他改进

可能还有其他一些方法可以使用一个衬垫来完成此任务,但为了可读性,通常最好只使用一些脚本。在存储库中,我采取了一些快捷方式,例如sleep 10run.sh. 这可以通过实际等待数据库以正确的方式启动来改进。初始化脚本也可以是等的一部分entrypoint.sh。希望它能帮助您开始

  • 这个答案虽然被接受,但实际上并没有解决问题。使用 docker-compose 或直接 docker 运行管道输入失败,并出现 OP 发布的错误,但从直接 docker 运行 bash 工作正常。然而,这个答案确实有帮助,因为使用 `-Q 'SELECT * FROM blah'` 作为参数效果很好(使用 docker 或 docker-compose)。 (2认同)