地味で地道なはてなブログ

ダイアリー「地味で地道な」から引っ越しました。

BCPをSQLServerクライアントの入ってないクライアントから投げる方法

本稼動2ヶ月前にして
クライアントにはSQLServerクライアントが入らないと
そこからBCPでインポートたたけというステキ仕様がやってきた
#BCP使わないでふつうにINSERTでいいと思うんですーって、それ、ベンチとってからいってね・・・

SQLServerクライアントのないクライアントからサーバにコマンドなげてBCPを実行するには
T-SQLのxp_cmdshellを使って、コマンドを文字列でサーバに投げて実行してもらいます
 
Microsoftのxp_cmdshellについてのページ
http://msdn.microsoft.com/ja-jp/library/ms175046.aspx
ストアドからBCPをたたくやりかた
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=21715&forum=26&6
ASPからBCPをたたくやりかた
http://ziddy.japan.zdnet.com/qa4407959.html
 
xp_cmdshellは、コマンドプロンプトで動くコマンドはセキュリティ上問題なければだいたい実行可能
サーバの所定のフォルダのdir(=ls)かけたりとか
しかし
その接続ユーザにCONTROL SERVER権限を付与したり
xp_cmdshellコマンドをサーバ上で使えるようにするため、ストアドを発行して有効にしたりとか
発行するコマンドに含まれているファイル名
(データファイル、fmtファイル、ログ、エラーファイル)は全部サーバ上のパスを渡さなくてはならない
などなど
 
超めんどくさい上に
セキュリティ厳しいプロジェクトだったらかなりたいへん
 
渡すインポートファイル名はとりあえずネットワークフォルダを想定しているが
ネットワークフォルダだと権限チェック入るみたいで、権限足りないフォルダは処理対象に指定できない
コマンドの戻り値が0ならOK、1なら異常終了
 
発行したコマンドをサーバで実行して結果をリダイレクトするか
エリアナライザ(や、2005では名前かわってるんだけどさ・・・)で叩いてメッセージをみるとエラーの詳細がわかる 
 
単純にコマンドラインくみたててADOでexecで投げてもできるけど、戻り値判定ができないので、
ストアドで投げるのがベスト

recordsetで戻り値もらってもやれるけど
けっこうめんどうだったのでストアドがよいと思う・・・
 
xp_cmdshell 'del C:\*.*'
なんて投げられたら
さすがにたまんないだろうから
できなくしてある
…と思いたい
 
通常はデフォルトで無効になってる