Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (日本語) » SQL Anywhere サーバ - SQL の使用法 » ストアド・プロシージャとトリガ » プロシージャ、トリガ、バッチの使用

 

バッチの概要

バッチは一緒に送信されてグループとして次々に実行される一連の SQL 文です。プロシージャ (CASE、IF、LOOP など) で使われる制御文はバッチでも使えます。バッチが BEGIN/END で囲まれた複合文で構成される場合、ホスト変数、変数のローカル宣言、カーソル、テンポラリ・テーブル、例外を含めることもできます。ホスト変数参照は、次の制限付きでバッチ内で使用できます。

  • ホスト変数を参照できるのはバッチ内の 1 文だけです。

  • ホスト変数を使用する文の前に、結果セットを返す文を入れることはできません。

バッチの使用を明確に示すために、BEGIN/END を使うことをおすすめします。

バッチ内の文はセミコロンで区切ることができます。その場合、バッチは Watcom-SQL 構文に準拠しています。文を区切るためにセミコロンを使用しない複数文のバッチは、Transact-SQL 構文に準拠します。バッチの構文によって、バッチ内で使用できる文とバッチ内でのエラーの処理方法が決まります。Transact-SQL バッチの詳細については、Transact-SQL のバッチの概要を参照してください。

多くの点で、バッチはストアド・プロシージャに似ていますが、いくつかの違いがあります。

  • バッチには名前がありません。

  • バッチにはパラメータを使用できません。

  • バッチは永続的にデータベースに保存されません。

  • バッチは異なる接続で共有できません。

簡単なバッチは、デリミタのない SQL 文のセットで、次の行に go という単語が続きます。次の例では、Eastern Sales という部署を作成し、Massachusetts のすべての営業担当者を Eastern Sales に転送します。これは Transact-SQL バッチの例です。

INSERT
INTO Departments ( DepartmentID, DepartmentName )
VALUES ( 220, 'Eastern Sales' )

UPDATE Employees
SET DepartmentID = 220
WHERE DepartmentID = 200
AND State = 'MA'

COMMIT
go

go という単語は Interactive SQL によって認識され、前の文は 1 つのバッチとしてサーバに送信されます。複数の SQL 文の実行を参照してください。

次の例は見た目は似ていますが、Interactive SQL での処理はまったく異なります。この例では、Transact-SQL 構文を使用しません。各文はセミコロンで区切られています。Interactive SQL はセミコロンで区切られた各文を個別にサーバに送信します。この場合は、バッチとしては処理されません。

INSERT
INTO Departments ( DepartmentID, DepartmentName )
VALUES ( 220, 'Eastern Sales' );

UPDATE Employees
SET DepartmentID = 220
WHERE DepartmentID = 200
AND State = 'MA';

COMMIT;

Interactive SQL でバッチとして処理するには、BEGIN ... END を使用して、複合文に変更します。次の構文は、前の例を修正したものです。複合文に含まれる 3 つの文は、バッチとしてサーバに送信されます。

BEGIN
  INSERT
  INTO Departments ( DepartmentID, DepartmentName )
  VALUES ( 220, 'Eastern Sales' );

  UPDATE Employees
  SET DepartmentID = 220
  WHERE DepartmentID = 200
  AND State = 'MA';

  COMMIT;
END

この例の場合、サーバがバッチと個別のどちらで文を実行しても結果は同じになります。ただし、結果が異なる場合もあります。次の例を考えます。

DECLARE @CurrentID INTEGER;
SET @CurrentID = 207;
SELECT Surname FROM Employees
  WHERE EmployeeID=@CurrentID;

Interactive SQL を使用してこの例を実行すると、データベース・サーバが変数が見つからないことを示すエラーを返します。このエラーは、Interactive SQL が 3 つの文を個別にサーバに送信するために発生します。これらの文はバッチとしては実行されません。このようなエラーに対処するには、複合文を使用して Interactive SQL が強制的に 3 つの文をバッチとしてサーバに送信するようにします。次の例では、複合文を使用しています。

BEGIN
  DECLARE @CurrentID INTEGER;
  SET @CurrentID = 207;
  SELECT Surname FROM Employees
    WHERE EmployeeID=@CurrentID;
END

一連の文を BEGIN と END で囲んだ場合、Interactive SQL は強制的に文をバッチとして処理します。

IF 文は複合文の一例です。Interactive SQL は、次の文を 1 つのバッチとしてサーバに送信します。

IF EXISTS(   SELECT *
            FROM SYSTAB
            WHERE table_name='Employees' )
THEN
   SELECT   Surname AS LastName,
            GivenName AS FirstName
   FROM Employees;
   SELECT Surname, GivenName
   FROM Customers;
   SELECT Surname, GivenName
   FROM Contacts;
ELSE
   MESSAGE 'The Employees table does not exist'
   TO CLIENT;
END IF

別の方法で SQL 文を作成して実行した場合、この例は適用されません。たとえば、ODBC を使用するアプリケーションでは、セミコロンで区切られた文をバッチとして作成および実行できます。

Interactive SQL の文とサーバ向けの SQL 文が混在している場合は、注意が必要です。次の例は、Interactive SQL の文と SQL 文を混合する場合の問題を示します。この例では、Interactive SQL の OUTPUT 文が複合文に組み込まれているので、その他のすべての文と一緒にバッチとしてサーバに送信され、構文エラーが発生します。

IF EXISTS(   SELECT *
            FROM SYSTAB
            WHERE table_name='Employees' )
THEN
   SELECT   Surname AS LastName,
            GivenName AS FirstName
   FROM Employees;
   SELECT Surname, GivenName
   FROM Customers;
   SELECT Surname, GivenName
   FROM Contacts;
   OUTPUT TO 'c:\\temp\\query.txt';
ELSE
   MESSAGE 'The Employees table does not exist'
   TO CLIENT;
END IF

正しい OUTPUT 文の例は、次のとおりです。

IF EXISTS(   SELECT *
            FROM SYSTAB
            WHERE table_name='Employees' )
THEN
   SELECT   Surname AS LastName,
            GivenName AS FirstName
   FROM Employees;
   SELECT Surname, GivenName
   FROM Customers;
   SELECT Surname, GivenName
   FROM Contacts;   
ELSE
   MESSAGE 'The Employees table does not exist'
   TO CLIENT;
END IF;
OUTPUT TO 'c:\\temp\\query.txt';