[前の記事]« ≪FROM STAFF≫新規発言は新設の3代目掲示板にお願いします。
[次の記事]Win2000: サービスを自動で設定し、レジストリを書き換えたい »

関連オンラインソフト配布サイト:
Vector>ダウンロード(top) |>MS-DOSまたは汎用 | >WindowsVista/XP/2000/NT

▲カテゴリー「FOR .. IN ( ) DO..」索引へ

[NT系]FORループから呼び出したサブルーチンを脱出するには

2.
ファイルを1行ずつREADする
2003年12月20日(土) 12時07分
INU
パラメタファイルに記述したSQL文を逐次実行し、
SQL文の実行エラーがあった場合、処理を中断し呼び元に戻るというバッチを作ろうとしています。

FOR文で1行ずつ読ませて実行させているのですが、エラー発生時にEXIT /B 100としてもループは抜けず、EXITとすると呼び元も終了してしまいます。

そもそもこのようなことが可能なのか、ご存知の方いらっしゃいませんか?

(実機はwindows2000、自分がテストしているマシンはXPです)


呼び元
TEST.BAT

(内容)-----------------------------------------------------
SQL.BAT PARM.TXT
------------------------------------------------------------


SQL.BAT
(内容)-----------------------------------------------------
set PARM1=%1
FOR /F "delims=" %%i in (%PARM1%) do (CALL :execcmd %%i)
goto :end
:execcmd
echo %* > tmp.sql
echo EXIT >> tmp.sql
sqlplus ora/ora@ORACLE @tmp.sql
if ERRORLEVEL 1 goto exec_error 

REM execute error 
:exec_error
echo %ERRORLEVEL%
echo "exec error!"
exit /b 100
goto end
:end
------------------------------------------------------------
3.
Re:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月20日(土) 13時55分
YanaKen
INUさん 3代目掲示板への初書き込み、どうもです(^^)。

>FOR文で1行ずつ読ませて実行させているのですが、エラー発生時にEXIT /B 100としてもループは抜けず、EXITとすると呼び元も終了してしまいます。

 EXIT /B はサブルーチンからの脱出なので、サブルーチンの呼び出し元のFOR文の実行には影響しない(FORから脱出できるわけではない)ですね。

 もうちょっとうまい方法があるかもしれませんが、単純には、次のようにcallの直前でerrorlevelを検査するようにすれば「サブルーチンで呼んだ部分でエラーが発生した場合、以後CALLしない(一応ループはするけれど何もしない)」という動作が得られる……のではないかと思います。検証して ないですけど。

>FOR /F "delims=" %%i in (%PARM1%) do (CALL :execcmd %%i)

>FOR /F "delims=" %%i in (%PARM1%) do IF errorlevel 1 (CALL :execcmd %%i)

 で、FORから抜けたあとであらためてEXIT /B 100すれば、そこで設定したエラーコードは大元のバッチファイル(TEST.BAT)に返るのではないかと思われます。

 もう1つ考えられるのは「別のバッチを実行する(CALLではなく)ことでループを中断させる」方法ですけど、元のTEST.BATにも戻ってこられなくなってしまうので、ご質問の趣旨にはあわなそうです。

Manager YanaKen
4.
Re2:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月20日(土) 13時57分
YanaKen
NOTが抜けてました(^^;。

>>FOR /F "delims=" %%i in (%PARM1%) do IF errorlevel 1 (CALL :execcmd %%i)
FOR /F "delims=" %%i in (%PARM1%) do IF not errorlevel 1 (CALL :execcmd %%i)
5.
Re3:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月20日(土) 19時21分
INU
YanaKenさん、はじめまして

>NOTが抜けてました(^^;。

>>>FOR /F "delims=" %%i in (%PARM1%) do IF errorlevel 1 (CALL :execcmd %%i)
>FOR /F "delims=" %%i in (%PARM1%) do IF not errorlevel 1 (CALL :execcmd %%i)


早速試しましたところ、無事解決致しました。ありがとうございました!
自分はUNIX系技術者なのですが、ひょんなことからSHELLとBATプログラムを作成することになってしまいました。
6.
Re2:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月21日(日) 11時45分
ふぇむ
>>FOR文で1行ずつ読ませて実行させているのですが、エラー発生時にEXIT /B 100としてもループは抜けず、EXITとすると呼び元も終了してしまいます。
FOR文からの途中脱出は、遅延展開を有効にすると楽です。
以下のような感じ。このサンプルでは A B C D E とループする中、固定的に C でループを打ち切ってます。


@echo off
setlocal ENABLEDELAYEDEXPANSION

set RET=
for %%z in ( A B C D E ) do (
echo now FOR[ %%z ]
call :MAIN %%z
if "!RET!" == "ERROR" goto :EXIT_FOR

)
goto :end

:EXIT_FOR
echo ..... EXIT FOR!
goto :end

:MAIN
set ARG=%~1
echo now MAIN[ %ARG% ]
set RET=OK
if "%ARG%" == "C" set RET=ERROR
goto :eof

:end
endlocal
7.
Re4:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月21日(日) 13時58分
ふぇむ
>自分はUNIX系技術者なのですが、ひょんなことからSHELLとBATプログラムを作成することになってしまいました。

若干助言を。参考にしてくださいませ。

Windowsのフォルダ構成上、名前にデフォルトで空白の混じったものがあるため(Program Files とか  Documents and Settingsとか)、DOSコマンドバッチの世界ではファイルパスには空白が混じる可能性があり、ファイルのフルパス を与える変数は "" でくくったほうが安定的です。また、空白交じりのワードを引数として与えて %n で参照する場合、一応 "" でくくった分を1 つの引数としてフィールド分割してくれますが、%n の形式だと両端の "" もついた形で得られてしまいます。これを避けるために、 %~n という形 の参照があります。

なので、たとえばファイル名を引数として与える場合は "" でくくり、参照する側は %~n で受け取り、それを利用する場合はまた明示的に "% ~n" と "" でくくる、ということを心がけると、変なところで足元をすくわれる可能性が少し減ります。そのように書いておくと、空白が混じらない場 合でも問題なく動きます。

また、ここでは直接関係ないかもしれませんが、UNIXのシェルの感覚で コマンド * みたいにワイルドカード指定でファイル名を与えた場合、UNIX ではワイルドカードはコマンドに与える前に展開されますが、DOSコマンドではそのような事前展開はされません(コマンド側にまかされている)ので、若干 頭の切り替えが必要な場合があります。
26.
Re3:ファイルを1行ずつREADする(というかFORからの脱出方法?)
2003年12月26日(金) 23時18分
INU
ふぇむさん、こんばんは

>>>FOR文で1行ずつ読ませて実行させているのですが、エラー発生時にEXIT /B 100としてもループは抜けず、EXITとすると呼び元も終了してしまいます。
>FOR文からの途中脱出は、遅延展開を有効にすると楽です。
>以下のような感じ。このサンプルでは A B C D E とループする中、固定的に C でループを打ち切ってます。


>@echo off
>setlocal ENABLEDELAYEDEXPANSION

>set RET=
>for %%z in ( A B C D E ) do (
> echo now FOR[ %%z ]
> call :MAIN %%z
> if "!RET!" == "ERROR" goto :EXIT_FOR

>)
>goto :end

>:EXIT_FOR
> echo ..... EXIT FOR!
> goto :end

>:MAIN
> set ARG=%~1
> echo now MAIN[ %ARG% ]
> set RET=OK
> if "%ARG%" == "C" set RET=ERROR
> goto :eof

>:end
>endlocal



ご助言ありがとうございました。
おかげさまでなんとか動かせました



2.ファイルを1行ずつREADする INU 03/12/20(土) 12:07
3.Re:ファイルを1行ずつREADする(というかFORからの脱出方法?) YanaKen 03/12/20(土) 13:55
4.Re2:ファイルを1行ずつREADする(というかFORからの脱出方法?) YanaKen 03/12/20(土) 13:57
5.Re3:ファイルを1行ずつREADする(というかFORからの脱出方法?) INU 03/12/20(土) 19:21
7.Re4:ファイルを1行ずつREADする(というかFORからの脱出方法?) ふぇむ 03/12/21(日) 13:58
6.Re2:ファイルを1行ずつREADする(というかFORからの脱出方法?) ふぇむ 03/12/21(日) 11:45
26.Re3:ファイルを1行ずつREADする(というかFORからの脱出方法?) INU 03/12/26(金) 23:18
 
 
 


カテゴリー「FOR .. IN ( ) DO..」索引へ

 

カテゴリー一覧

FPCU/FPCDIY QUICK LINK online
この上の各ジャンル名をクリックすると、下のウィンドウが切り替わります▼


=リンク集のインデックスはこちら=

資料書籍

About

2003年12月20日 11:42に投稿されたエントリーのページです。

ひとつ前の投稿は「≪FROM STAFF≫新規発言は新設の3代目掲示板にお願いします。」です。

次の投稿は「Win2000: サービスを自動で設定し、レジストリを書き換えたい」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

This site is powered by Six Apart
Movable Type 3.33-ja
このブログについて | 運営:有限会社メディアポート