2005年08月07日

パッケージ&ストアドプロシージャでDB更新処理を高速化する方法

オンライントランザクション処理を実行する
プログラムは、複数の端末要求を即座に
処理し結果を応答するプログラムです。
ほとんどの場合、
データベースアクセスを伴うと同時に、
高い信頼性と優れたレスポンスを要求されます。

最近のデータベース管理システム(RDBMS)の大半が、
パッケージやストアドプロシージャをサポートしており、
ちょっとしたアプリケーションアーキテクチャの改善で、
データベースアクセスのパフォーマンスが
大幅に向上する可能性があります。

今回はDelphiの「dbExpress」ルーチンの
「TSQLStoredProc」を利用し、
Oracleストアドプロシージャを呼び出す方法を紹介します。

サンプルプログラムは、
簡単な表にデータを1件更新するだけのものです。
Oracleのストアドプロシージャは、
PL/SQLで記述された
処理手順をOracleが高速に実行できるよう、
コンパイルし中間コードのオブジェクトとして保持しています。
プログラムなどからストアドプロシージャが呼び出される際に、
SQL文の構文解析や再コンパイルといった
オーバーヘッドが発生しません。

従って、パフォーマンスを向上するためには、
更新の度にINSERT、UPDATE、DELETE、SELECTなどの
データ操作SQL文を毎回ちまちま発行するのではなく、
データベース更新の一連の処理をストアドプロシージャに隠蔽し、
パフォーマンスの向上を図るアーキテクチャが有効となります。

一方で複雑なデータベース更新処理を
ストアドプロシージャで実装する場合、
そのデバッグが困難となります。
ストアドプロシージャを効率よく
デバックする開発支援ツールがないと、
デバッグ作業にあなたの貴重な時間が代価として支払われます。

この記事が、あなたがつくるプログラムの
アプリケーションアーキテクチャの参考になればと思います。
(Good luck!)

ここで紹介した方法は、
パフォーマンス向上を目的とした
一つのアプリケーションアーキテクチャにすぎません。
表の正規化、
適切なインデックスの設定、
最適なSQL文の発行など基本的な
パフォーマンスチューニング技術を習得することをお忘れなく。

サンプルソースは【続きを読む】をクリック!

使用例
uses
 DBXpress,
 SqlExpr;

procedure TForm1.Button1Click(Sender: TObject);
var
 lDB: TSQLConnection;
 lSP: TSQLStoredProc;
 lTD: TTransactionDesc;
begin
 lDB := Nil;
 lSP := Nil;
 try
  // DB接続を初期化する
  lDB := TSQLConnection.Create(Nil);
  lDB.DriverName := 'ORACLE';
  lDB.GetDriverFunc := 'getSQLDriverORACLE';
  lDB.LibraryName := 'dbexpora.dll';
  lDB.VendorLib  := 'oci.dll';
  lDB.Params.Values['DataBase'] :=
   'CONNECT_STRINGS';
  lDB.Params.Values['User_Name'] := 'USER';
  lDB.Params.Values['Password'] := 'PASSWORD';
  lDB.Open;
  // DBトランザクションを開始する
  lTD.TransactionID := 1;
  lTD.IsolationLevel := xilREADCOMMITTED;
  lDB.StartTransaction(lTD);
  // DBストアドプロシージャを呼び出す
  lSP := TSQLStoredProc.Create(Nil);
  lSP.SQLConnection := lDB;
  lSP.PackageName := UpperCase('Test_Pkg');
  lSP.StoredProcName := UpperCase('Update_City');
  lSP.Prepared := True;
  lSP.ParamByName('in_Name').Value := 'Argentina';
  lSP.ParamByName('in_Capital').Value := 'Buenos';
  lSP.ParamByName('in_Population').Value :=
   32300003;
  lSP.ExecProc;
  // DBトランザクションの更新を確定する
  lDB.Commit(lTD);
  lDB.Close;
 finally
  lDB.Free;
  lSP.Free;
 end;
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

注意:
 下記ソースファイルは、本ページの管理者である「guy」が個人的に作成しました。
 このソースは作者に断り無く、個人がコピー、改造することは許可しますが、
 いかなる場合であっても、商用目的に使用することを固く禁じます。
 あと、ホームページでの公開の都合上、各ソースの先頭に全角スペースが入ってます。
 あなたがDelphiでコンパイルする前に、この全角スペースを半角スペースに変換してくださいね。

Source: create_table_Test.sql
create table City (
 Name varchar2(64),
 Capital varchar2(64),
 Population number(20)
);

alter table City
 add(
  CONSTRAINT XPK_Table PRIMARY KEY (
   Name
  )
 )
;


Source: create_package_Test_Pkg.sql
--------------------------------------------------------------------------------
create or replace package Test_Pkg
as
 procedure Update_City(
  in_Name    City.Name%type,
  in_Capital  City.Capital%type,
  in_Population City.Population%type
 );
end Test_Pkg;
/
--------------------------------------------------------------------------------
create or replace package body Test_Pkg
As
 Procedure Update_City(
  in_Name    City.Name%type,
  in_Capital  City.Capital%type,
  in_Population City.Population%type
 )
 as
  lROWID rowid;
 begin
  begin
   select rowid into lROWID from City
   where
    Name = in_Name;
   update City set
    Capital = in_Capital,
    Population = in_Population
   where
    rowid = lROWID;
  exception
   when NO_DATA_FOUND then
    insert into City (
     Name,
     Capital,
     Population
    ) values (
     in_Name,
     in_Capital,
     in_Population
    );
  end;
 end Update_City;
end Test_Pkg;
/

posted by guy at 06:33 | データベース編
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。