【無料配信♪】Renta !全タテコミ作品第1話

開発言語: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つのコーディングでマズい所があるかどうか
また、どこを直せば正常に動くのか、について
申し訳ないですが、どうかご教授お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (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 …
にも掲載されてますのでご覧下さい。

ここまで準備できると、後は、先ほどのASPを実行すればOKです。
なお、faye470さんが提示したコードの悪かった点は、
cmd.exe /c がなかったのでそれを入れてみたというのと、
BCPコマンドに実行引数がfaye470さんがやりたいこととあっていなかった
ことが原因でした。

今回の私のコードを過信するのではなく、今一度、BCPコマンドの使い方も見直されることをお勧めします。

BCPコマンドの書式
http://msdn.microsoft.com/ja-jp/library/ms191516 …

最後に今回は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ではなく監視ツールなどを使ってログ監視すれば
とりあえずはエラーが発生したかどうか判断はできます。

長文になりましたが、参考になれば幸いです。
    • good
    • 0

質問の趣旨としては、


とにかく、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で「サーバー名\サービスインスタンス名」と指定する
>必要がありますが、その辺りは大丈夫ですか?

はい、サーバー名\サービスインスタンス名で指定できています。


以上、よろしくお願い致します。

補足日時:2008/10/17 14:54
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QBASP21 で 外部プログラムが実行できない

BASP21 をインストールしました。
Execute を使って、外部プログラム(例 notepad.exe) を実行したいのですが、一向に起動しません。
何が間違っているのでしょうか。


<%

Set bobj = CreateObject("basp21")

(1)
rc = bobj.Execute("notepad.exe", 0, stdout)

(2)
rc = bobj.Execute("notepad.exe", 1, stdout)



(1)はページ表示後、すぐに帰ってきます。
rc の中身は 0 です。 しかし、起動しません。

(2)はページを読み込み中のまま、10分待っても
20分待っても帰ってきません。
rc の中身は不明です。

以上、会社で困ってますのでよろしくお願いします。

Aベストアンサー

私の記憶が正しければ、
このExecuteはサーバ上でプログラムを実行する為の
物ですので、クライアント側には何も表示されません。
試しにサーバ側のタスクマネージャでプロセスを確認
されれば「notepad.exe」が溜まっているのでは
と思いますが。

Qbcpインサートでのフォーマットファイルの書き方

bcpコマンドでインサートをしたいと考えています。
テーブルの形式は
1 datetime 日時
2 filed_1 varchar(10)
3 filed_2 varchar(10)
4 filed_3 varchar(10)
です。
フォーマットファイルに
8.0
4
1SQLDATETIME08","1日時""
2SQLCHAR03","2filed_1""
3SQLCHAR03","3filed_2""
4SQLCHAR03"\r\n"4filed_3""
書きました。
データは、
2009/04/01 0:00:00,11.0,11.0,11.0
2009/04/01 0:01:00,11.0,11.0,11.0
です。
SQLServerは2005のExpressです。
実行すると
コピーを開始中です...
SQLState = 37000, NativeError = 7339
Error = [Microsoft][ODBC SQL Server Driver][SQL Server]リンク サーバー '(null)'
の OLE DB プロバイダ 'STREAM' から、列 '[!BulkInsert].日時' に無効なデータが返さ
れました。

BCP コピー in が失敗しました
が返されます。
成功させるにはどこを直せばよいでしょうか。
よろしくお願いします。

bcpコマンドでインサートをしたいと考えています。
テーブルの形式は
1 datetime 日時
2 filed_1 varchar(10)
3 filed_2 varchar(10)
4 filed_3 varchar(10)
です。
フォーマットファイルに
8.0
4
1SQLDATETIME08","1日時""
2SQLCHAR03","2filed_1""
3SQLCHAR03","3filed_2""
4SQLCHAR03"\r\n"4filed_3""
書きました。
データは、
2009/04/01 0:00:00,11.0,11.0,11.0
2009/04/01 0:01:00,11.0,11.0,11.0
です。
SQLServerは2005のExpressです。
実行すると
コピーを開始中です...
SQLState ...続きを読む

Aベストアンサー

うーん、複数の端末で試してみましたが、こちらではうまくいきます。
同様のケースでyyyy/MM/ddがうまくいかないという話はあるみたいですね。

ExpressもSP3にしてみるとか、2008Expressにしてみるとかという手もあるかもしれませんが、
実際ロケールに頼るのもどうかと思うので、別の方法も試してみてはどうでしょうか。
(ファイルは同じPC内でしたよね)

BCPの代わりにSQLCMDとOPENROWSETを使う方法です。
SQLCMD -Sサーバ -Uユーザ -Pパスワード -dデータベース -Q"INSERT INTO TEST SELECT * FROM OPENROWSET(BULK 'C:\Test.csv', FORMATFILE='C:\Test.fmt') x"
フォーマットファイルは同じのを使いますが、
8.0
4
1 SQLCHAR 0 20 "," 1 日時 ""
2 SQLCHAR 0 10 "," 2 field_1 ""
3 SQLCHAR 0 10 "," 3 field_2 ""
4 SQLCHAR 0 10 "\r\n" 4 field_3 ""

という風に長さを十分にします。

何が違うかというと、一旦ファイルをすべて文字列でテーブルのように読みだして、テーブルにはINSERTすることにより、
文字列から日付への変換をMDACではなく、SQL Serverに行わせるというものです。
yyyy/MM/dd hh:mm:ssは、SQL Serverではデフォルトで暗黙変換ができます。
この方法だと仮に変換がうまくいかなくても、

INSERT INTO TEST SELECT CONVERT(datetime,日時),field_1,field_2,field_3 FROM OPENROWSET(BULK 'C:\Temp\TestData.csv', FORMATFILE='C:\Temp\Test.fmt') x
という風に変換を明示的に指定してあげることもできるので、柔軟性があります。
(リモートサーバだとBCPのようにはいきませんが)

もちろん、yyyyMMddはうまくいくのだったら、最初にVBで日付形式を変換してからBCP実行するとか、そういう考え方もあるでしょう。

うーん、複数の端末で試してみましたが、こちらではうまくいきます。
同様のケースでyyyy/MM/ddがうまくいかないという話はあるみたいですね。

ExpressもSP3にしてみるとか、2008Expressにしてみるとかという手もあるかもしれませんが、
実際ロケールに頼るのもどうかと思うので、別の方法も試してみてはどうでしょうか。
(ファイルは同じPC内でしたよね)

BCPの代わりにSQLCMDとOPENROWSETを使う方法です。
SQLCMD -Sサーバ -Uユーザ -Pパスワード -dデータベース -Q"INSERT INTO TEST SELECT * FROM ...続きを読む

Qasp.netからbcpコマンドの実行

asp.netからbcpコマンドを実行し、CSVをエクスポートする方法はありますか?

bcpは普通は、コマンドプロンプトから実行しますが、「プログラムからボタンをクリックしたらcsvが吐き出される。」というようなことができますでしょうか?

Aベストアンサー

何度もすみません。

コードの最後に以下の一行がないとプロセスが開始されませんでした。。。

◆C#
proc.Start();
◆VB.NET
proc.Start()

QCSVファイルをBULK INSERTでSQLserverに読み込むことは可能?

BULK INSERT というものを使って
SQLServer2000上のテーブルに読込みたいのですが可能でしょうか?

その場合どうやって記述すればよいのでしょうか?
終端文字とかいうのは何になるのでしょう?

Windows2000
RDOで接続です。

Aベストアンサー

””で区切られたファイルのインポートですが、BULK INSERTでは、”を含んでロードしてしまいます。ですので、BULK INSERT を使用する場合は”を削除してからロードしないと駄目です。

ところで、<www7.big.or.jp/~pinball/discus/sqls/index.html>でも質問をしているようですが、どのような環境で何がしたいのか状況がつかめません。

詳しく教えていただけませんか?

QBCPでCSV内の文字列をテーブルのDatetime型カラムに取り込む方法

BCPを使用してCSVをテーブルに取込みたいのですが、
CSV内に日付形式の文字列(YYYY/MM/DD)があり、
取込先のテーブルの型はDatetimeになっています。
フォーマットファイルのデータ型は「SYBCHAR」
で設定しているのですが、いざ取込もうとすると、
以下のようなエラーが出てうまく取込めません。

SQLState = 22008, NativeError = 0
Error = [Microsoft][ODBC SQL Server Driver]日付の形式が正しくありません。

フォーマットファイルの設定が悪いのでしょうか?
なんとか回避する方法はないでしょうか。

Aベストアンサー

日付形式がYYYY-MM-DDなら取り込めます。
事前に/を-に置換しないといけませんが・・
<フォーマットファイル>
7.0
1
1 SQLCHAR 0 10 "\r\n" 1 dt

置換しない方法だと
日付フィールドがvarcharとしたテンポラリー用のテーブルを用意してそこにBCPでインポートする。
インポート完了後、本番テーブルに日付フィールドをコンバートしてインサートすればいけると思います。

Q型 varchar から型 numeric への変換エラー。

SQLクエリアナライザを使って、あるデータベースからLEFT JOINなどを駆使し、条件にそってデータを抽出しようと必死でやっております。
今まではうまく取得できていたのに、”型 varchar から型 numeric への変換エラー。”というエラーがでるようになりました。
前回とテーブルのデータを比較してみると、IsNULL(chrShokuhinCD,'') as chrShokuhinCDで引っ掛かっているようです。
この項目には空白(スペース)が入ったデータが最近存在しているのが原因だと思うのですが。。。
空白だったとき、IsNULL(chrShokuhinCD,'') as chrShokuhinCDはどのように修正すればよいでしょうか?教えてください。

Aベストアンサー

>空白だったとき、IsNULL(chrShokuhinCD,'') as chrShokuhinCDはどのように修正すればよいでしょうか?

では質問です。
空白だったとき、どんな数値として扱えばいいでしょうか?

これで何を入れればいいかわかると思いますが。

QBCPユーティリティの使用法_ヘッダー情報の取得_

どなたかご存知の方教えてください。
bcp ユーティリティから、SQLサーバーのテーブルのファイルエクスポート(.txt)は出力できたのですが、データ列名が取得できていませんでした。
列名を取得することは可能なのでしょうか?
可能な場合、.fmt のファイルで設定するのでしょうか?
よろしくお願いします。

Aベストアンサー

キーワード「bcp 列名」でGoogle検索すると4番目に次のページがヒットしました,ご参考まで。
http://d.hatena.ne.jp/w650/20080215/p2

QASPからのEXEファイル起動

VBScriptで作ったASPからVisualBasicで作ったEXEファイルを起動するプログラムを作りました。
そこでEXEファイルを起動する際にASPで持ってる情報(ユーザID)を
起動をかけるEXEに渡したいのですがうまくいきません。

DOS画面より
>C:\abc.exe 10
とうつとパラメータ 10が引きわたり正常に起動します。

ところがWEBから
Response.Redirect("C:\abc.exe 10")とやると
ページが見つかりませんとなります。

ちなみに
Response.Redirect("C:\abc.exe")だと
パラメータの受け渡しはありませんが起動はできます。

何がいけないんでしょうか・・・?
ご教授願います。

Aベストアンサー

>もしよろしければこの処理のどのへんが危険か
>教えてもらえると参考になります。

警告画面なしに実行できるのであればの話でした。


>パラメータを渡さなければ普通にダウンロード画面が
>出て起動できます。

"開く"を選択した場合ですね。(その後警告が出てOKして)
ブラウザはローカルのc:\abc.exeをコピーして、実行しているだけです。

>サーバー側に格納されているEXEを
>クライアントがダウンロードして使用する

と違うでしょう。

>他の起動方法を考えないといけないですね。

(1)VB6でActiveXを作る。
パラメータはプロパティで渡す。

(2)VB.NETで作る。(ノータッチ・デプロイメント)

Windows FormプロジェクトでEXEを作って、wwwrootの下に置けば、

Response.Redirect("abc.exe?id=1")

で、クライアント側にダウンロードしてEXEが動きます。
警告画面は出ません。

条件は
EXEがファイル操作など、セキュリティに違反しないこと。
クライアント側に.NET Frameworkが必要、ブラウザはIE限定。

サーバ側の条件はありません。(Linux+ApacheでもOK)

>もしよろしければこの処理のどのへんが危険か
>教えてもらえると参考になります。

警告画面なしに実行できるのであればの話でした。


>パラメータを渡さなければ普通にダウンロード画面が
>出て起動できます。

"開く"を選択した場合ですね。(その後警告が出てOKして)
ブラウザはローカルのc:\abc.exeをコピーして、実行しているだけです。

>サーバー側に格納されているEXEを
>クライアントがダウンロードして使用する

と違うでしょう。

>他の起動方法を考えないといけないですね。...続きを読む

Qbcp in でエラー

初めて投稿致します。

過去ログや他サイトでもいくつかみかけた事象ですが、
どこにもはっきりとした回答がないため質問させて頂きました。
知っている方がいたら、ご教授お願いします。

環境は、Win2003Server + SQL Server2000 です。

外部サーバからisqlで取得したデータをPerlでタブ区切りに加工し、
そのファイルをbcpでDBにインサートする処理でエラーが発生します。
エラー内容は、過去ログにもあったとおり
『文字列データの右側が切り捨てられました』というものです。
1行目からエラーが発生し、10回のエラー発生で異常終了します。

ただ、3万行あるデータを2万行と1万行にしてインサートすれば
問題なくDBに登録されます。
この事象はMicrosoftのバグなんでしょうか?
サイト上には、そのようなバグが報告されていないようですが。
それともどこかに仕様として紹介されているのでしょうか。
データのサイズ、レコード数に関わらず
bcpでインポートできるようにしたいのです。
ちなみに、現行は7.0で問題なく上記処理が稼動しています。

本サイト上に示されていた解決法のODBCバージョンですが、
ODBCは最新版が入ってるので、それ以外でこの事象の解決法を
知っている方がいましたらぜひとも教えてください。

以上、よろしくお願い致します。

初めて投稿致します。

過去ログや他サイトでもいくつかみかけた事象ですが、
どこにもはっきりとした回答がないため質問させて頂きました。
知っている方がいたら、ご教授お願いします。

環境は、Win2003Server + SQL Server2000 です。

外部サーバからisqlで取得したデータをPerlでタブ区切りに加工し、
そのファイルをbcpでDBにインサートする処理でエラーが発生します。
エラー内容は、過去ログにもあったとおり
『文字列データの右側が切り捨てられました』というものです。
1行目からエラー...続きを読む

Aベストアンサー

・件数次第で成功
・旧SQL-Serverでは成功

という2点で、やはりログファイル的にOKということなので、環境しか考えられないかと・・・


もちろんディスクはFATでフォーマットしてませんよね?
BCPIN最中に、セグメントがギュウギュウになってしまっているとか?



本当にログのフォーマットのせいではないですよね?
>外部サーバからisqlで取得したデータをPerlでタブ区切りに加工し、そのファイルをbcpでDBにインサートする処理でエラー
でも2万と1万に切り分けて成功する。。。
ならば、分割して入れたデータをTAB区切りでBCPOUTしてtruncate、さらにBCPINしても同じところでエラーが出ると思うのですがいかがでしょう?

同じところで出ているのであれば、
3万件のデータがどれほどのサイズであるかを知りたいです。

QVBScriptでSQLファイルの実行

WSHShell.Runにて、SQL*Plus経由でXXX.sql(内部でストアドプロシージャをコールします)を実行し、ログも出力したいのですが、以下のコマンドをRunに指定すると、sqlplusより返ってこなくなってしまいます。
コマンドプロンプトで実行する分には、正常に終了するのですが・・・。
何が悪いのかわかりません。。

sqlplus -s ユーザー/パスワード@ホスト名 @C:\temp\XXX.sql > C:\temp\XXX.log

代替案として、VBSにてOracleのProcedureをコールする方法でも構いません。

わかる方いらっしゃいましたらご教授願います。

ちなみに、コマンド部分をbatファイルにしてそのbatファイルをVBSでコールすることは可能でした。

Aベストアンサー

うろおぼえですみません。
WSHShell.Run (文字列) は、
コマンドラインからの実行とイコールではありません。
コマンド Start "" と同じ
というか、「ファイル名を指定して実行」と同等なはずです。
(なので WSHShell.Run は実行ファイル以外も指定できる)
なので、CMD /C (文字列) で実行する必要があったはずです。

とはいえ、ADOで問題ないならそのほうがいいかも。


人気Q&Aランキング