プログラム言語 メール送信

use Cake\Mailer\Email;

設定ファイルにおけるdefault設定を使用
$email = new Email('default');
CakePHP インストール・設定」参照
$email
  ->setFrom(['me@example.com' => 'title'])
  ->setTo('yone@office-yone.com')
  ->setSubject('題名')
  ->send('本文');

デザインパターン Proxy:必要になってから作る

概要

Proxy:代理人
本来の処理オブジェクトとは別の代理人オブジェクトに処理を代理させる手法
負荷の高い処理に使用する。

クラス図


本例

-:private

サービス側

Subject(主体)

public interface Printable {
 public abstract void setPrinterName(String name);
 public abstract String getPrinterName();
 public abstract void print(String name);
}

Proxy(代理人)

public class PrintProxy implements Printable {

 private String name;
 private Printer real;

 public PrintProxy(String name) {
  this.name = name;
 }

 @Override
 public synchronized void setPrinterName(String name) {
  if (this.real != null) {
   this.real.setPrinterName(name);
  }
 }

 @Override
 public String getPrinterName() {
  return this.name;
 }

 @Override
 public void print(String string) {
  realize();
  real.print(string);
 }

 private void realize() {
  if (this.real == null) {
   ここで初めて本来の処理オブジェクトに処理を渡す
   this.real = new Printer(this.name);
  }
 }
}

RealSubject(実際の主体)

public class Printer implements Printable {
 private String name;

 public Printer() {
  heavyJob("Printerのインスタンス作成中");
 }

 public Printer(String name) {
  this.name = name;
  heavyJob(String.format("Printerのインスタンス(%s)作成中", this.name));
 }

 @Override
 public void setPrinterName(String name) {
  this.name = name;
 }

 @Override
 public String getPrinterName() {
  return this.name;
 }

 @Override
 public void print(String string) {
  System.out.println(String.format("===%s===", this.name));
  System.out.println(string);
 }

 private void heavyJob(String string) {
  System.out.println(string);
  for (int i = 0; i < 5; i++) {
   try {
    Thread.sleep(1000);
   }catch(InterruptedException e) {
    // 何もしない
   }
   System.out.println(".");
  }
  System.out.println("完了");
 }
}

利用者側

public class Main {
 public static void main(String[] args) {
  Printable p = new PrintProxy("Java");
  System.out.println(String.format("名前は現在%sです。", p.getPrinterName()));
  p.setPrinterName("PHP");
  System.out.println(String.format("名前は現在%sです。", p.getPrinterName()));
  ここで初めてPrinterインスタンスが作成される
  p.print("Hello World.");
  
  p.setPrinterName("PHP");
  p.print("Hello World.");
 }
}


結果
名前は現在Javaです。
名前は現在Javaです。
Printerのインスタンス(Java)作成中
.
.
.
.
.
完了
===Java===
Hello World.
===PHP===
Hello World.

デザインパターン Facade:シンプルな窓口

概要

複雑な処理に対して、最小限のAPI(公開メソッド)のみを提供する

クラス図


本例

※下線=static

システム

Facade(正面)

public class PageMaker {
 複雑な部品の複雑な使用方法をまとめる
 public static void makeWelcomePage(String mailaddr, String filename) {
  Properties mailprop = Database.getProperties("maildata");
  String username = mailprop.getProperty(mailaddr);
  try {
   HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
   writer.title("Welcome to " + username + "'s page!");
   writer.paragraph(username + "のページへようこそ。");
   writer.paragraph("社員募集中");
   writer.mailto(mailaddr, username);
   writer.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

その他複雑な部品

public class HtmlWriter {
 private Writer writer;

 public HtmlWriter(Writer writer) {
  this.writer = writer;
 }

 public void title(String title) throws IOException {
  this.writer.write("<html>\n");
  this.writer.write("<head><title>" + title + "</title></head>\n");
  this.writer.write("<body>\n");
  this.writer.write("<h1>" + title + "</h1>\n");
 }

 public void paragraph(String msg) throws IOException {
  this.writer.write("<p>" + msg + "</p>");
 }

 public void link(String href, String caption) throws IOException {
  this.paragraph("<a href=\"" + href + "\">" + caption + "</a>");
 }

 public void mailto(String mailaddr, String username) throws IOException {
  this.link("mailto:" + mailaddr, username);
 }

 public void close() throws IOException {
  this.writer.write("</body>\n");
  this.writer.write("</html>\n");
  this.writer.close();
 }
}


public class Database {

 private Database() {}

 public static Properties getProperties(String dbname) {
  String filename = dbname + ".txt";
  Properties prop = new Properties();
  try {
   prop.load(new FileInputStream(filename));
  } catch (IOException e) {
   e.printStackTrace();
  }
  return prop;
 }
}

Client(利用者)

public class Main {
 public static void main(String[] args) {
  利用者は複雑なシステムに対してこのメソッドしか使用していない
  PageMaker.makeWelcomePage("yone@office-yone.com", "welcome.html");
 }
}

デザインパターン Composite:容器と中身の同一視

概要

Composite=混合物
ディレクトリとファイルの様な再帰的な構造からなるオブジェクトを生成するパターン

クラス図


本例

抽象

Leaf(葉)

public class File extends Entry {
 private String name;
 private int size;

 public File(String name, int size) {
  this.name = name;
  this.size = size;
 }

 @Override
 public String getName() {
  return this.name;
 }

 @Override
 public int getSize() {
  return this.size;
 }

 @Override
 protected void printList(String prefix) {}
}

Composite(複合体)

public class Directory extends Entry {
 private String name;
 private ArrayList<Entry> directory = new ArrayList<Entry>();

 public Directory(String name) {
  this.name = name;
 }

 public Entry add(Entry entry) {
  this.directory.add(entry);
  return this.toStrong();
 }

 @Override
 public String getName() {
  return this.name;
 }

 @Override
 public int getSize() {
  int size = 0;
  ディレクトリ(ディレクトリ、ファイル)を全件Loop
  Iterator<?> it = this.directory.iterator();
  while (it.hasNext()) {
   Entry entry = (Entry)it.next();
   size += entry.getSize();
  }
  return size;
 }

 @Override
 protected void printList(String prefix) {
  System.out.println(prefix + "/" + this.toString());
  ディレクトリ(ディレクトリorファイル)を全件Loop
  Iterator<?> it = this.directory.iterator();
  while (it.hasNext()) {
   Entry entry = (Entry) it.next();
   entry==ファイル時:親ディレクトリ名と自身の名前を出力
   ※FileクラスのprintList()呼び出し
   entry==ディレクトリ時:親ディレクトリ名と自身の名前を出力
   ※親ディレクトリ名と自身の名前を引数にDirectoryクラスの本メソッドを再帰的に呼び出し

   entry.printList(prefix + "/" + this.name);
  }
 }
}

Component

public class FileTreatmentException extends Exception {

 public FileTreatmentException() {}

 public FileTreatmentException(String msg) {
  super(msg);
 }
}


public abstract class Entry {
 public Entry add(Entry entry) throws FileTreatmentException {
  throw new FileTreatmentException();
 }
 公開メソッド
 public void printList() {
  非公開メソッドを呼び出し
  this.printList("");
 };
 public String toString() {
  return this.getName() + "(" + this.getSize() + ")";
 }
 public abstract String getName();
 public abstract int getSize();
 protected abstract void printList(String prefix);
}

Client(利用者)

public class Main {

 public static void main(String[] args) {
  Directory rootdir = new Directory("root");
  Directory bindir = new Directory("bin");
  Directory tmpdir = new Directory("tmp");
  Directory usrdir = new Directory("usr");
  rootdir.add(bindir);
  rootdir.add(tmpdir);
  rootdir.add(usrdir);
  bindir.add(new File("vi", 10000));
  bindir.add(new File("latex", 20000));
  rootdir.printList();

  System.out.println("");
  Directory java = new Directory("JAVA");
  Directory php = new Directory("PHP");
  Directory c = new Directory("C#");
  usrdir.add(java);
  usrdir.add(php);
  usrdir.add(c);
  java.add(new File("java1.html", 100));
  java.add(new File("java2.java", 200));
  php.add(new File("php1.html", 300));
  php.add(new File("php2.php", 400));
  c.add(new File("c1.c", 500));
  c.add(new File("c2.c", 600));
  rootdir.printList();
 }
}

ディレクトリ構成
root
└bin
 └vi
 └latex
└tmp
└usr
 └JAVA
  └java1.html
  └java2.java
 └PHP
  └php1.html
  └php2.php
 └C#
  └c1.c
  └c2.c

結果
/root(30000)
/root/bin(30000)
/root/tmp(0)
/root/usr(0)

/root(32100)
/root/bin(30000)
/root/tmp(0)
/root/usr(2100)
/root/usr/JAVA(300)
/root/usr/PHP(700)
/root/usr/C#(1100)

デザインパターン AbstractFactory:関連する部品を組み合わせる

概要

関連オブジェクト群の生成方法を抽象クラスだけで指定するパターン
具象側のオブジェクト群を入れ替える事でグループ単位での追加/修正が容易になる

クラス図


本例

抽象

AbstractProduct(製品)

package abstractFactory.factory;

public abstract class Item {
 protected String caption;
 public Item(String caption) {
  this.caption = caption;
 }
 public abstract String makeHTML();
}


package abstractFactory.factory;

public abstract class Tray extends Item {
 protected ArrayList<Item> tray = new ArrayList<Item>();

 public Tray(String caption) {
  super(caption);
 }

 public void add(Item item) {
  this.tray.add(item);
 }
}


package abstractFactory.factory;

public abstract class Link extends Item {
 public Link(String caption, String url) {
  super(caption);
  this.url = url;
 }
}


package abstractFactory.factory;

public abstract class Page {
 protected String title;
 protected String author;
 protected ArrayList<Item> content = new ArrayList<Item>();
 public Page(String title, String author) {
  this.title = title;
  this.author = author;
 }

 public void add(Item item) {
  this.content.add(item);
 }

 public void output() {
  try {
   String filename = this.title + ".html";
   Writer writer = new FileWriter(filename);
   writer.write(this.makeHTML());
   writer.close();
   System.out.println(filename + "を作成");
  } catch (IOException e) {
   e.printStackTrace();
  }

 }
 public abstract String makeHTML();
}

AbstractFactory(工場)

package abstractFactory.factory;

public abstract class Factory {
 public static Factory getFactory(String classname) {
  Factory factory = null;
  try {
   利用者から引数で指定されたクラス名(listfactory/ListFactory)をインスタンス化する
   factory = (Factory) Class.forName(classname).newInstance();
  } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
   e.printStackTrace();
  }

  return factory;
 }
 public abstract Link createLink(String caption, String url);
 public abstract Tray createTray(String caption);
 public abstract Page createPage(String title, String author);
}

Client(依頼者)

Main起動時に引数で「listfactory/ListFactory」を指定する

package abstractFactory;

public class Main {
 public static void main(String[] args) {
  if (args.length != 1) {
   System.exit(0);
  }
  listfactory/ListFactoryのインスタンスを取得
  Factory factory = Factory.getFactory(args[0]);

  Link sankei = factory.createLink("産経新聞", "https://www.sankei.com/");
  Link yomiuri = factory.createLink("読売新聞", "http://www.yomiuri.co.jp/");
  Link yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");
  Link google = factory.createLink("Google", "http://www.google.com;");

  Tray traynews = factory.createTray("新聞");
  traynews.add(sankei);
  traynews.add(yomiuri);

  Tray trayweb = factory.createTray("WEB");
  trayweb.add(yahoo);
  trayweb.add(google);

  Page page = factory.createPage("LinkPage", "株式会社米良太事務所");
  page.add(traynews);
  page.add(trayweb);
  page.output();
 }
}

結果
※ListPage部分
<html><head><title>LinkPage</title></head>
<body>
 <h1>LinkPage</h1>
 <ul>
  ※ListTray部分
  <li>
   新聞
   <ul>
    ※ListLink部分
    <li><a href="https://~">産経新聞</a></li>
    <li><a href="http://~">読売新聞</a></li>
   </ul>
  </li>
  ※ListTray部分
  <li>
   WEB
   <ul>
    ※ListLink部分
    <li><a href="http://~">Yahoo!</a></li>
    <li><a href="http://~;">Google</a></li>
   </ul>
  </li>
 </ul>
 <hr>
 <address>株式会社米良太事務所</address>
</body>
</html>

具象

ConcreteProduct(製品)

依頼者は具象クラスしか参照しない
具象クラスは別途コンパイルが必要

package abstractFactory.listfactory;

public class ListLink extends Link {
 public ListLink(String caption, String url) {
  super(caption, url);
 }

 @Override
 public String makeHTML() {
  return "<li><a href=\"" + this.url + "\">" + this.caption + "</a></li>";
  // <li><a href="this.url">this.caption</a></li>
 }
}


package abstractFactory.listfactory;

public class ListTray extends Tray {
 public ListTray(String caption) {
  super(caption);
 }

 @Override
 public String makeHTML() {
  StringBuffer buffer = new StringBuffer();
  buffer.append("<li>\n");
  buffer.append(this.caption + "\n");
  buffer.append("<ul>\n");
  Iterator<Item> it = tray.iterator();
  while (it.hasNext()) {
   Item item = (Item) it.next();
   buffer.append(item.makeHTML());
  }
  buffer.append("</ul>\n");
  buffer.append("</li>\n");
  return buffer.toString();
 }
}


package abstractFactory.listfactory;

public class ListPage extends Page {
 public ListPage(String title, String author) {
  super(title, author);
 }

 @Override
 public String makeHTML() {
  StringBuffer buffer = new StringBuffer();
  buffer.append("<html><head><title>" + this.title + "</title></head>\n");
  buffer.append("<body>\n");
  buffer.append("<h1>" + this.title + "</h1>\n");
  buffer.append("<ul>\n");;
  Iterator<Item> it = this.content.iterator();
  while (it.hasNext()) {
   Item item = (Item) it.next();
   buffer.append(item.makeHTML());
   Page、Tray、ListはmakeHTMLメソッドを実装しているのでどのオブジェクトでもHTMLが生成される
  }
  buffer.append("</ul>\n");
  buffer.append("<hr><address>" + this.author + "</address>\n");
  buffer.append("</body></html>\n");
  return buffer.toString();
 }
}

ConcreteFactory(工場)

package abstractFactory.listfactory;

public class ListFactory extends Factory {
 @Override
 public Link createLink(String caption, String url) {
  return new ListLink(caption, url);
 }

 @Override
 public Tray createTray(String caption) {
  return new ListTray(caption);
 }

 @Override
 public Page createPage(String title, String author) {
  return new ListPage(title, author);
 }
}

デザインパターン Prototype:コピーしてインスタンスを作る

概要

クラスをnewしてインスタンスを作成せず、
インスタンスをコピーしてインスタンスを作成するパターン

クラス図


フレームワーク側

Prototype(原型)

public interface IProduct extends Cloneable {
 public abstract void use(String s);
 public abstract IProduct createClone();
}

Cloneableを継承したクラス(サブクラス)において、
clone()が実行されるとそのクラスのインスタンスがコピーされる
※本例ではMessageBox、UnderLinePenクラスにおけるcreateClone()メソッド実行時

Client(利用者)

public class Manager {
 private HashMap<String, IProduct> showcase = new HashMap<String, IProduct>();
 public void register(String name, IProduct proto) {
  IProductのインスタンスをKey毎に保持
  this.showcase.put(name, proto);
 }
 public IProduct create(String protoname) {
  指定KeyのIProductのインスタンスを取り出し
  IProduct p = (IProduct)showcase.get(protoname);
  指定KeyのIProductインスタンスを複製
  return p.createClone();
  
  実例ではMessageBox、UnderLinePenクラスのインスタンスが複製される
  このクラス内にMessageBox、UnderLinePenというクラス名はハードコーディンされておらず再利用性が高い

 }
}

具象側

ConcretePrototype(具体的な原型)

public class MessageBox implements IProduct {

 private char decochar;
 public MessageBox(char decochar) {
  this.decochar = decochar;
 }

 @Override
 public void use(String s) {
  int length = s.getBytes().length;
  for (int i = 0; i < length + 4; i++) {
   System.out.print(this.decochar);
  }
  System.out.println("");
  System.out.println(this.decochar + " " + s + " " + this.decochar);
  for (int i = 0; i < length + 4; i++) {
   System.out.print(this.decochar);
  }
  System.out.println("");
 }

 @Override
 public IProduct createClone() {
  IProduct p = null;
  try {
   p = (IProduct)clone();
  } catch(CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return p;
 }
}

public class UnderLinePen implements IProduct {

 private char ulchar;
 public UnderLinePen(char ulchar) {
  this.ulchar = ulchar;
 }

 @Override
 public void use(String s) {
  int length = s.getBytes().length;
  System.out.println("\"" + s + "\"");
  for (int i = 0; i < length; i++) {
   System.out.print(this.ulchar);
  }
  System.out.println("");
 }

 @Override
 public IProduct createClone() {
  IProduct p = null;
  try {
   p = (IProduct)clone();
  } catch(CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return p;
 }
}

利用

public class Program {
 public static void main(String[] args) {
  Manager manager = new Manager();
  UnderLinePen pen = new UnderLinePen('~');
  MessageBox mbox = new MessageBox('*');
  MessageBox sbox = new MessageBox('/');

  manager.register("strong message", pen);
  manager.register("warning box", mbox);
  manager.register("slash box", sbox);

  IProduct p1 = manager.create("strong message");
  p1.use("Hello, world.");
  IProduct p2 = manager.create("warning box");
  p2.use("Hello, world.");
  IProduct p3 = manager.create("slash box");
  p3.use("Hello, world.");
 }
}

結果
"Hello, world."
~~~~~~~~~~~~~
*****************
* Hello, world. *
*****************
/////////////////
/ Hello, world. /
/////////////////

デザインパターン FactoryMethod:インスタンス作成をサブクラスに任せる

概要

インスタンス作成方法を抽象クラス(フレームワーク側)で規定
具象クラス(具象側で)実処理を行う
本例ではProduct(カードインスタンス)を具象クラスで作成する
抽象クラス側では具象クラスを参照していない為、具象クラス側の変更だけで全体の変更が済む

クラス図


本例

フレームワーク側

Product(製品)

public abstract class Product {
 public abstract void use();
}

Creator(作成者)

public abstract class Factory {
 インスタンス作成方法を規定
 実処理はサブクラスに任せる
 public final Product create(String owner) {
  Product p = this.createProduct(owner);
  this.registerProduct(p);
  return p;
 }
 protected abstract Product createProduct(String owner);
 protected abstract void registerProduct(Product p);
}

具象側

ConcreteProduct(具体的製品)

public class IDCard extends Product {

 private String owner;
 public IDCard(String owner) {
  System.out.println(owner + "様カード作成");
  this.owner = owner;
 }

 @Override
 public void use() {
  System.out.println(this.owner + "様カード使用");
 }
}

ConcreteCreator(具体的作成者)

public class IDCardFactory extends Factory {

 private List<IDCard> owners = new ArrayList<IDCard>();

 @Override
 protected Product createProduct(String owner) {
  return new IDCard(owner);
 }

 @Override
 protected void registerProduct(Product p) {
  this.owners.add((IDCard)p);
 }
}

利用

public class Program {

 public static void main(String[] args) {
  Factory f = new IDCardFactory();
  Product card1 = f.create("Java");
  Product card2 = f.create("PHP");
  Product card3 = f.create("C#");

  card1.use();
  card2.use();
  card3.use();
 }
}

結果
Java様カード作成
PHP様カード作成
C#様カード作成
Java様カード使用
PHP様カード使用
C#様カード使用

デザインパターン TemplateMethod:具体的な処理をサブクラスに任せる

概要

親クラスで処理の枠組み(テンプレート)を提供する
子クラスではテンプレートを変更できない

クラス図

抽象クラス

public abstract class AbstractDisplay {
 子クラスで変更可能な処理
 protected abstract void open();
 protected abstract void print();
 protected abstract void close();
 
 templateMethod
 子クラスで共用の処理(変更不可)
 public final void display(){
  this.open();
  for (int i=0; i<5; i++) {
   this.print();
  }
  this.close();
 };
}

具象クラス

public class CharDisplay extends AbstractDisplay {
 private char ch;
 public CharDisplay(char ch) {
  this.ch = ch;
 }
 @Override
 public void open() {
  System.out.print("<<");
 }
 @Override
 public void print() {
  System.out.print(this.ch);
 }
 @Override
 public void close() {
  System.out.println(">>");
 }
}

public class StringDisplay extends AbstractDisplay {
 private String string;
 private int width;
 public StringDisplay(String string) {
  this.string = string;
  this.width = string.getBytes().length;
 }
 @Override
 public void open() {
  this.printLine();
 }
 @Override
 public void print() {
  System.out.println("|" + string + "|");

 }
 @Override
 public void close() {
  this.printLine();
 }
 private void printLine() {
  System.out.print("+");
  for (int i=0; i<this.width; i++) {
   System.out.print("-");
  }
  System.out.println("+");
 }
}

利用クラス

public class Program {
 public static void main(String[] args) {
  AbstractDisplay d1 = new CharDisplay('H');
  AbstractDisplay d2 = new StringDisplay("Hello");
  AbstractDisplay d3 = new StringDisplay("こんにちは");

  d1.display();
  d2.display();
  d3.display();
 }
}

結果
<<HHHHH>>
+-----+
|Hello|
|Hello|
|Hello|
|Hello|
|Hello|
+-----+
+---------------+
|こんにちは|
|こんにちは|
|こんにちは|
|こんにちは|
|こんにちは|
+---------------+

デザインパターン Singleton:たった1つのインスタンス

概要

インスタンスが1つしか存在しない事を保証したい場合に利用

クラス図

singleton

Singleton

package myPack;
public class Singleton {
 private static Singleton singleton = new Singleton();
 クラスがロードされる際(一度だけ)にインスタンス変数を生成

 private Singleton(){}
 外部からのコンストラクタ実行を禁止

 public static Singleton getInstance(){
  return singleton;
  内部で生成したインスタンスを返す
 }
}

利用

package myPack;
public class Main {
 public static void main(String[] args){
  Singleton obj1 = Singleton.getInstance();
  Singleton obj2 = Singleton.getInstance();
  if (obj1==obj2){
   System.out.println("同じ");
  }
 }
}

Windowsバッチ(MS-DOS)

Windowsバッチ

Windows上の処理を自動化するプログラム
正確にはMS-DOS上の処理の自動化
Windowsの多彩な機能の操作はバッチコマンドでは実現できない
コマンドプロンプトにおけるMS-DOSコマンドをまとめて記述・保存しておく事で、まとめて実行できる
Linuxにおけるシェルスクリプト
MS-DOS、Linuxコマンドについては「バッチコマンド(Linux/DOS/PowerShell)」参照

コマンド

コマンド 機能
pause バッチ中断
exit コマンドプロンプト終了
@~ 画面非表示
timeout 待機

バッチ中断
pause

コマンドプロンプト終了
exit

画面非表示
@~
@echo、@if ~等

TIMEOUT /T 待機時間(秒)
TIMEOUT /T 60
TIMEOUT /T -1 ※無制限

コマンドパラメータ

パラメータ 機能
/E ファイルが存在しなくてもディレクトリごとコピー
/Y 同名のファイルが存在する場合、自動で上書き
/D コピー先に同名のファイルが存在する場合は更新日が新しいファイルのみコピー
/q 確認メッセージを表示しない
/p 確認メッセージを表示する

組込変数

変数 機能
%~dp0 実行ファイルが置かれているカレントディレクトリ
%0 実行ファイルパス
%~n0 ファイル名
%~x0 拡張子

起動パラメータ

受取

> test.bat 5 ABC ""
文字列は"で囲まない
※test.bat
set prm1 = %1
set prm2 = %2
set prm3 = %3

SQL*Plus実行時

> test.bat 5 ABC ""
※test.bat
sqlplus (接続情報) @C:\test.sql %1 %2 %3
起動パラメータをそのまま渡す

エラーハンドリング

%errorlevel%
ms-dos操作の結果が自動的に格納される組込み変数
明示的に値をセットする事も可能
parent.batからchild.batを呼び出す場合
※parent.bat

call c:\child.bat
child.batでの終了結果に応じて分岐

if %errorlevel% neq 0 goto NG
:OK
@echo OK
exit
*NG
@echo NG
exit
※child.bat

変数をクリア

set errorlevel =


errorlevelに正常(0)をセットして終了

exit /b 0


errorlevelに異常(1)をセットして終了

exit /b 1

SQL*Plusの戻り値

SQL*Plusを実行
更にPL/SQLを記述した外部スクリプトを実行する場合
> SQLPLUS (接続情報) @(スクリプトファイル名)
if %errorlevel% neq 0 goto NG

Oracle SQL*Plus使用方法」参照

制御文

For文
プログラム言語 制御文/For文