1

大規模な 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 についてです。

アドバイスをありがとう。

4

2 に答える 2

0

次のような単純な Powershell スクリプトを使用します。

Invoke-SqlCommand -query '...' | ExportTo-Csv ...

通常、管理機能については、これをタスク スケジューラに追加して完了できます。必要に応じてこのタスクを実行する必要がある場合は、特定のコンテキストで T-SQL よりも Powershell で自分自身を表現する方が簡単な場合があるため、どちらを使用する方が適しているかをxp_cmdshell使用して実行できます。schtasks.exe run Task_NAME

他に言及されていることはすべて追加のツールが必要です (たとえば、SSIS には VS が必要です)。これは依存関係なく移植可能です。

スクリプトを呼び出さずxp_cmdshellにスクリプトを呼び出すには、powershell ステップでジョブを作成し、t-sql 内から実行する必要があります。

于 2016-04-04T09:20:07.023 に答える
0

データ EXPORT のオプションは次のとおりです。

  • xp_cmdshell を使用して bcp.exe を呼び出す - 一括コピーの古い方法
  • CLR の使用 - 一括コピーの新しい方法
  • SSIS - これを行うための私の好みの方法。ここに例があります
  • INSERT INTO OPENROWSET - text/Jet/その他のドライバがインストールされた 32 ビット環境で作業している場合、または 64 ビット ドライバをインストールできる場合に使用できる興味深い代替手段 (例: 64 ビット ODBC テキスト ドライバ。Microsoft Access データベースを参照)エンジン 2010 再頒布可能)
  • SQL Server のインポート/エクスポート ウィザード - 希望どおりに動作することはめったにない醜い手動の方法
  • 外部 CSV テーブルの使用 - まだサポートされていません (SQL Server 2016 ではサポートされると約束されています...)

HTH

于 2016-04-04T08:40:14.103 に答える