web-dev-qa-db-ja.com

スペースを含むフォルダにどのように書き込みますか?

SQLデータをExcelに出力する単純なSSISパッケージがたくさんあるので、ファイルの名前を変更してエンドユーザーに移動します。

それらの中には、スペースを含むファイルパスを使用するものもあり、新しいフォルダを使用することに興奮していません。これが私が使っているコードです:

    declare @date varchar(25),
    @sql varchar(1000)

    set @date = cast(datepart(month, current_timestamp) as varchar(2)) + '_' +  cast(datepart(day, current_timestamp) as varchar(2)) + '_' +  cast(datepart(year, current_timestamp) as varchar(4))
    print @date

    set @sql = 'copy D:\Data\ED_72.xlsx \\ehsintra3\ED_72_weekly\ED_72_' + @date + '.xlsx';
    print @sql

    exec  xp_cmdshell @sql

ただし、アンダースコアがなければ機能しません。

質問下線なしでこれをどのように機能させることができますか?

5
James

(ほとんどの場合)パスを引用符で囲む必要があります。だから、このように:

declare @date varchar(25),
@sql varchar(1000);

set @date = cast(datepart(month, current_timestamp) as varchar(2)) + ' ' +  cast(datepart(day, current_timestamp) as varchar(2)) + ' ' +  cast(datepart(year, current_timestamp) as varchar(4));
print @date;

set @sql = 'copy "D:\Data\ED_72.xlsx" "\\ehsintra3\ED 72 weekly\ED 72 ' + @date + '.xlsx"';
print @sql;

exec  xp_cmdshell @sql;

パスを引用符で囲むことにより、コマンドプロセッサがパスの開始点と終了点を理解できるようになります。

また、copyを使用する代わりに、robocopyまたはxcopyのいずれかを確認することもできます。 copyコマンドは残酷に弱く、脆弱です。

また、マイナーなメモとして、T-SQLのステートメントの最後にセミコロンを追加します。

8
Max Vernon

もう1つの方法は、SSIS内でファイルシステムタスクを使用することです。これは、複雑なパスとファイル名を扱い、xp_cmdshellエスケープの危険性とリスクを伴いません。

どんなリスク?二重引用符で囲まれた引数には制限があります。

スタックオーバーフローの xp_cmdshellにdtexecに渡されるコマンドパラメーターをエスケープする も参照してください。

6
billinkc