- 締切済み
ASP(vbs)でのBCPの実行について
開発言語:ASP(vbs) 使用DB:SQL Server2005(海外版) クライアントPC:WinXP(USA版OS) APサーバー:WinServer2003(日本にあり、USA版OS)[bcp.exeを動作させる為だけにSQLServerを入れています] DBサーバー:WinServer2003(海外サーバー) クライアントからCSVをAPサーバーにUpLoadし、DBサーバーにインポートしたいのですが出来ません。 インポート方法として、BCPとBulkが使用出来る事を調べたのですが Bulkでは、DBServerにCSVファイルがないとインポート出来ないようで DBサーバーにファイルを置いてはいけない仕様となっている為使用出来ません。 なので、bcpを利用しようと思い現在開発を進めていまた。 コマンドプロンプト上ではBCPコマンドは動作するようになったのですが ASP上で動作確認しようとしたところ、正常終了(エラーは帰ってこない)はするのですが 実際にデータがインポートされている様子がありません。 ●basp21を使用した場合(basp21はインストール済) 【ソース】 Set bobj = Server.CreateObject("basp21") rc = bobj.Execute("bcp DB名 IN C:\a.csv -t , -S サーバー名 -U ユーザー名 -P パスワード -E -F 2 -c",1,stdout) select case rc case 0 : response.write("正常終了") case -1 : response.write("コマンドエラー") case -2 : response.write("タイムアウト") end select 【表示結果】 >正常終了 と表示されますが、実際指定したテーブルにデータがインポートはされていません。 ●WScriptを使用した場合 【ソース】 Set objShell = Server.CreateObject("WScript.Shell") objShell.Run "bcp DB名 IN C:\a.csv -t , -S サーバー名 -U ユーザー名 -P パスワード -E -F 2 -c" response.write "エラーナンバー:" & Err.Number & "<br>" 【表示結果】 >エラーナンバー:0 上記も同様に、実際指定したテーブルにデータがインポートはされていません。 ●番外:コマンドをバッチ化してASPから実行 【ソース】 Set objShell = Server.CreateObject("WScript.Shell") objShell.Run "C:\a.bat" 【表示結果】 >Microsoft VBScript runtime error '800a0046' >Permission denied >a.asp, line 2 こちらはただ試してみただけなのですが 普通、権限を割り振らないとASPからバッチファイル実行するのは無理ですね。 コマンドプロンプトで同コマンドを実行するときちんとインポートされている事 ASP上で実行するとエラーで帰ってくるならまだしも戻り値が0なので正常終了しているが、結果が伴わない(インポートされていない)事 が、相成って困っています。 最初の2つのコーディングでマズい所があるかどうか また、どこを直せば正常に動くのか、について 申し訳ないですが、どうかご教授お願いします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
補足ありがとうございました。 頂いた補足情報を元に、私の方でもやってみました。 (同じ環境構成だったので) ひとまず、BCPでデータをインポートするためのASPのソースを公開します。 <%@ LANGUAGE="VBScript" CodePage=932 %> <% ' 必要に応じて変えてください。 Const bcpPath = """C:\Program Files\Microsoft SQL Server\90\Tools\Binn\bcp.exe"" " Const dbName = "[データベース名].[dbo].[インポートする対象のテーブル]" Const serverName = "サーバーのIPアドレスまたはマシン名" Const userName = "SQLServer ログインID" Const passWord = "SQLServer パスワード" Const bcpFormatFile = "C:\work\IMPORT_DATA.fmt " ' ここから先は変えないで下さい Const consoleOption = "cmd.exe /c " Const commandBase = " [0] IN C:\work\IMPORT_DATA.csv -S [1] -U [2] -P [3] -f [4]" Dim bobj Dim rc Dim commandLine Dim stdout commandLine = consoleOption & bcpPath & commandBase commandLine = Replace(commandLine, "[0]", dbName) commandLine = Replace(commandLine, "[1]", serverName) commandLine = Replace(commandLine, "[2]", userName) commandLine = Replace(commandLine, "[3]", passWord) commandLine = Replace(commandLine, "[4]", bcpFormatFile) Set bobj = Server.CreateObject("basp21") rc = bobj.Execute(commandLine, 1, stdout) Select Case rc Case 0 : response.write("正常終了") Case -1 : response.write("コマンドエラー") Case -2 : response.write("タイムアウト") End Select Response.Write "<br />" Response.Write stdout Response.Write commandLine %> まず、faye470さんが上記コードを動かす前にやるべきことがあります。 1点目: BCPでCSVファイルを読み込ませるためのフォーマットファイルを事前に用意する必要があります。 このフォーマットファイルですが、BCPコマンドで下記のようにして作ります。 コマンドプロンプトを開き、 bcp [DB名].[dbo].[インポートするテーブル名] format nul -f c:\work\table.fmt(名前は何でも良い) -S [SQLServerのサーバー名]\[SQLServerインスタンス名(例:SQLEXPRESS等)] -U [ログインID] -P [パスワード] というコマンドをうち、コンソールの指示に従い、 フォーマットファイルを作成します。 するとインポート先のテーブルの書式に合わせたフォーマットファイルが作成されるはずです。 ■フォーマットファイルイメージ 9.0 2 1 SQLCHAR 0 100 "," 1 項目名1 Japanese_CI_AS 2 SQLCHAR 0 100 "\r\n" 2 項目名2 Japanese_CI_AS #フォーマットファイルの作り方については、 http://msdn.microsoft.com/ja-jp/library/ms191516.aspx にも掲載されてますのでご覧下さい。 ここまで準備できると、後は、先ほどのASPを実行すればOKです。 なお、faye470さんが提示したコードの悪かった点は、 cmd.exe /c がなかったのでそれを入れてみたというのと、 BCPコマンドに実行引数がfaye470さんがやりたいこととあっていなかった ことが原因でした。 今回の私のコードを過信するのではなく、今一度、BCPコマンドの使い方も見直されることをお勧めします。 BCPコマンドの書式 http://msdn.microsoft.com/ja-jp/library/ms191516.aspx 最後に今回はBASP21を使って、BCPをシェル実行してますが、 faye470さんがおっしゃる通り、確かにBCPでエラーになっても BASP21では何も通知してくれません。 というのもBASP21がBCPで動かすために監視しているプロセスはあくまで 「CMD.exe」であって、「BCP.exe」ではないからなんです。 そのため「BCP.exe」で起こったエラーをBASP21では拾うことができない と言えば、faye470さんにもご理解頂けますか? また、どうしても、「BCP.exe」で発生したエラーを拾いたいのであれば BCP実行中の様子をログに出力するようにするといいかもしれません。 先ほどのASPソースの Const commandBase = " [0] IN C:\work\IMPORT_DATA.csv -S [1] -U [2] -P [3] -f [4]" の箇所を Const commandBase = " [0] IN C:\work\IMPORT_DATA.csv -S [1] -U [2] -P [3] -f [4]>>bcp.log" とすればログを書き出せます。 このログをASPではなく監視ツールなどを使ってログ監視すれば とりあえずはエラーが発生したかどうか判断はできます。 長文になりましたが、参考になれば幸いです。
質問の趣旨としては、 とにかく、BCPコマンドを使ってASPからデータがインポートできれば なんでもいいということですか? (BASP21を使っても使わなくても構わないってことですか?) それとも、取り込めない時にエラーとか戻り値からだと 判断できなくて困っている、どちらでしょうか? そして、インポートしたいファイルの形式は何でしょうか? タブ区切り?カンマ区切り、スペース区切り?何らかの任意文字? ですか? そして、SQL Server2005とのことですが、使用されている エディションは何でしょうか?Express Editionだと、 BCPコマンドの-S(サーバー名)の指定方法が変わってきますし、 またExpress Edition以外の場合でも 既定のサービスインスタンス名(MSSQLSERVER)で SQL Serverをインストールしていないと -Sで「サーバー名\サービスインスタンス名」と指定する 必要がありますが、その辺りは大丈夫ですか? 質問の趣旨がイマイチつかみづらいので、補足下さい。 宜しくお願いします。
補足
お返事ありがとうございます。 色々説明が足らず申し訳ありません。 >とにかく、BCPコマンドを使ってASPからデータがインポートできれば >なんでもいいということですか? はい、BCPコマンドを使用してASPからデータインポートが出来れば何でも構いません。 BASP21にこだわっているわけではなく、BASP21を使用しても WScriptを使用しても正常終了(BASPだと0が帰って来て、WScriptだとErr.Numberが0です) が帰ってくる事と、コマンドプロンプトから実行するとちゃんとインポート出来ている為 どうしていいか判らず困っています。 >そして、インポートしたいファイルの形式は何でしょうか? >タブ区切り?カンマ区切り、スペース区切り?何らかの任意文字? >ですか? CSV形式のファイルで、カンマ区切りとなっています。 >そして、SQL Server2005とのことですが、使用されている >エディションは何でしょうか? SQL Server2005 Evaluation Editionを使用しています。 >-Sで「サーバー名\サービスインスタンス名」と指定する >必要がありますが、その辺りは大丈夫ですか? はい、サーバー名\サービスインスタンス名で指定できています。 以上、よろしくお願い致します。