1. 先来了解一下调用外部EXE执行程序的方式
在Sql Server中,调用外部exe程序,通常是通过xp_cmdshell来执行,例如:
EXEC xp_cmdshell 'dir'
上面的代码演示了如何在Sql Server中执行系统命令dir。
2. 外部程序执行时遇到的问题
2.1 外部程序权限不够的问题
有时,外部程序的执行需要更高的权限,但是xp_cmdshell是在Sql Server的权限下运行的,因此可能会因为权限问题而无法执行。
2.2 外部程序执行时间过长的问题
因为Sql Server是一个事务性数据库,所以xp_cmdshell执行的过程会被放到数据库的一个事务中,在执行完毕之前,该事务会一直处于等待状态,如果外部程序执行时间过长,可能会导致事务的阻塞。
2.3 外部程序执行结果不可预测的问题
由于外部程序的执行过程不受Sql Server的控制,因此不可预计外部程序的执行结果。
3. 如何解决这些问题
3.1 在xp_cmdshell中指定账户拥有更高的权限
为了解决外部程序权限不够的问题,可以在xp_cmdshell中指定拥有更高权限的账户来执行外部程序,例如:
EXEC xp_cmdshell 'runas /user:Domain\UserName "c:\path\to\your\exe"'
上面的代码演示了如何使用runas来指定执行外部程序的账户。
3.2 将xp_cmdshell的执行放在单独的线程中
为了解决xp_cmdshell执行过程阻塞的问题,可以将其执行放在单独的线程中,例如:
CREATE PROCEDURE sp_execute_cmd
@cmd varchar(1000)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @result int, @errmsg varchar(1000);
EXEC @result = sp_OACreate 'WScript.Shell', @errmsg OUT;
IF @result = 0
BEGIN
EXEC @result = sp_OAMethod @errmsg, 'Run', NULL, @cmd, 0, 1;
EXEC @result = sp_OADestroy @errmsg;
END
END
GO
EXEC sp_execute_cmd 'c:\path\to\your\exe'
上面的代码演示了如何使用sp_OACreate和sp_OAMethod来在单独的线程中执行外部程序。
3.3 获取外部程序执行结果
为了解决外部程序执行结果不可预测的问题,可以通过xp_cmdshell返回值来获取外部程序执行结果,例如:
DECLARE @result int;
EXEC @result = xp_cmdshell 'c:\path\to\your\exe';
SELECT @result;
上面的代码演示了如何使用xp_cmdshell返回值来获取外部程序执行结果。
4. 结论
在Sql Server中调用外部EXE执行程序的方式虽然简单,但是在执行过程中可能会出现权限不够、执行时间过长、执行结果不可预测等问题。为了解决这些问题,可以使用指定账户拥有更高的权限、将执行放在单独的线程中、获取外部程序执行结果等方法来进行处理。