我正在维护基于大型 t-sql 的应用程序。它有很多通过 xp_cmdshell 调用的 bcp 用法。
这是有问题的,因为 xp_cmdshell 具有与 SQL Server 服务帐户相同的安全上下文,而且它对于工作来说是非常必要的。
我摆脱这个缺点的第一个想法是使用 CLR 代码。CLR 以调用代码的用户的权限运行。我创建了以下程序,它工作正常。我可以看到它正在使用运行此代码的帐户的权限:
public static void RunBCP(SqlString arguments, out SqlString output_msg, out SqlString error_msg, out SqlInt32 return_val) {
output_msg = string.Empty;
error_msg = string.Empty;
try {
var proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "bcp",
Arguments = arguments.ToString(),
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
while (!proc.StandardOutput.EndOfStream) {
output_msg += proc.StandardOutput.ReadLine();
}
return_val = proc.ExitCode;
}
catch (Exception e) {
error_msg = e.Message;
return_val = 1;
}
}
这是一个很好的解决方案,因为我不会在 BCP 调用中搞砸(参数相同)。逻辑没有重大变化,因此没有出错的风险。
因此,以前在 T-SQL 中调用 BCP 是这样的:
declare @ReturnCode int;
declare @cmd varchar(1000);
SELECT @CMD = 'bcp "select FirstName, LastName, DateOfBirth" queryout "c:\temp\OutputFile.csv" -c -t -T -S"(local)"'
EXEC @ReturnCode=xp_cmdshell @CMD,no_output
现在我这样称呼它:
declare @ReturnCode int;
declare @cmd varchar(1000);
SELECT @CMD = '"select FirstName, LastName, DateOfBirth" queryout "c:\temp\OutputFile.csv" -c -t -T -S"(local)"'
exec DataBase.dbo.up_RunBCP @arguments = @cmd;
所以,问题是:有没有其他方法可以摆脱 xp_cmdshell bcp 代码?我听说我可以使用 PowerShell(sqlps)。但我发现的示例建议创建一个 powershell 脚本。我可以从 t-sql 代码中调用这样的脚本吗?应该如何存储此代码(powershell 脚本)?作为数据库对象?或者也许还有其他方法?不需要 SSIS。我最想知道的是关于powershell。
感谢您的任何建议。