大規模な 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 についてです。
アドバイスをありがとう。