
CentOS 7.9 → Windows SQL Server 2012 企业版 → 命令行执行存储过程的完整可用方案,按“装客户端 → 连库 → 执行存储过程 → 排错”四步来,都是生产环境验证过的写法。
一、CentOS 7.9 安装 sqlcmd 客户端
修改源为阿里云:
cd /etc/yum.repos.d/
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -O http://mirrors.aliyun.com/repo/Centos-7.repo
mv Centos-7.repo CentOS-Base.repo
SQL Server 2012 很老,用 mssql-tools17 或 18 都可以连(18 默认强制加密,连 2012 要关加密或信任证书,下面会处理)。
# 1. 加微软 yum 源(RHEL7/CentOS7 专用)
curl -o /etc/yum.repos.d/mssql-release.repo https://packages.microsoft.com/config/rhel/7/prod.repo
# 2. 清掉老版本冲突包
yum remove -y mssql-tools unixODBC-utf16 unixODBC-utf16-devel
# 3. 装 sqlcmd + bcp + unixODBC
ACCEPT_EULA=Y yum install -y mssql-tools18 unixODBC-devel
# 4. 加 PATH
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# 5. 验证
sqlcmd -?
看到版本号即成功(路径也可能是 /opt/mssql-tools/bin,取决于装的是 17 还是 18)。
在SQLSERVER数据库中,创建一个测试用的存储过程:
在SQLSERVER 2012的 test数据库中创建一个存储过程,这个存储过程只返回当前数据库的日期
USE test;
GO
IF OBJECT_ID('dbo.usp_GetCurrentDate', 'P') IS NOT NULL
DROP PROCEDURE dbo.usp_GetCurrentDate;
GO
CREATE PROCEDURE dbo.usp_GetCurrentDate
AS
BEGIN
SET NOCOUNT ON;
SELECT GETDATE() AS CurrentDateTime;
END;
GO
在数据库在验证:
EXEC dbo.usp_GetCurrentDate;
二、Windows 侧前置条件(必须确认)
SQL Server 2012 已启用 TCP/IP(配置管理器 → 协议 → TCP/IP → 端口 1433)
已开启 SQL Server 身份验证(混合模式),sa 或业务账号可登
Windows 防火墙放行 1433
Linux 侧先测连通:
[root@centos7 ~]# nmap -p 1433 172.16.1.1
Starting Nmap 6.40 ( http://nmap.org ) at 2026-07-24 10:13 CST
Nmap scan report for 172.16.1.1
Host is up (0.00030s latency).
PORT STATE SERVICE
1433/tcp open ms-sql-s
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 0.55 seconds
三、在 CentOS 7.9 命令行执行存储过程
假设:
Windows IP:172.16.1.1
端口:1433
用户:sa / 密码:Pass@123
数据库:TestDB
存储过程:dbo.usp_MyProc
1)无参存储过程
sqlcmd -S 172.16.1.1,1433 -U sa -P '123456' -C -d test -Q "EXEC dbo.usp_GetCurrentDate;"
SQL Server 2012 不支持新版本默认的强制 TLS,用 mssql-tools18 时需加 -C 信任自签证书,或用 mssql-tools17 免加密参数。
mssql-tools18 连 2012 推荐写法:
sqlcmd -S 172.16.1.1,1433 -U sa -P '123456' -d TestDB -C -Q "EXEC dbo.usp_MyProc;"
2)带输入参数
sqlcmd -S 172.16.1.1,1433 -U sa -P 'Pass@123' -d TestDB -C -Q "EXEC dbo.usp_MyProc @StartDate='2026-01-01', @EndDate='2026-01-31';"
3)带 OUTPUT 参数 / 取返回码
sqlcmd -S 172.16.1.1,1433 -U sa -P 'Pass@123' -d TestDB -C -Q " DECLARE @Ret INT; EXEC dbo.usp_MyProc @Param1='abc', @ReturnCode=@Ret OUTPUT; SELECT 'ReturnCode=' + ISNULL(CAST(@Ret AS VARCHAR),'NULL'); "
4)用 SQL 文件执行(生产推荐)
cat /home/user/run_proc.sql
USE TestDB;
GO
EXEC dbo.usp_MyProc
@StartDate = '2026-01-01',
@EndDate = '2026-01-31';
GO
执行:
sqlcmd -S 172.16.1.1,1433 -U sa -P 'Pass@123' -d TestDB -C -i /home/user/run_proc.sql
5)中文乱码处理(CentOS 7 常见)
脚本含中文时加 -f 65001:
sqlcmd -S 172.16.1.1,1433 -U sa -P 'Pass@123' -d TestDB -C -f 65001 -i run_proc.sql
或者把 .sql 文件存成 UTF-8 with BOM。
四、Shell 脚本里判断执行成功/失败(crontab 可用)
#!/bin/bash
sqlcmd -S 172.16.1.1,1433 -U sa -P 'Pass@123' -d TestDB -C -b -Q "EXEC dbo.usp_MyProc;" >> /var/log/run_proc.log 2>&1
if [ $? -eq 0 ]; then
echo "$(date) OK" >> /var/log/run_proc.log
else
echo "$(date) FAILED" >> /var/log/run_proc.log
fi
-b 表示 SQL 报错时 sqlcmd 返回非 0,方便脚本判断。
五、域账号登录(如果 2012 用域控)
sqlcmd -S 172.16.1.1,1433 -U 'DOMAIN\\sqluser' -P 'DomainPass' -d TestDB -C -Q "EXEC dbo.usp_MyProc;"
(Linux shell 里反斜杠必须转义成 \\)



SQLSERVER:通过CentOS7.9命令行调用windows操作系统下SQLSERVER的存储过程