テーブルの作成方法(2)
TDBISAMQueryによるテーブルの作成
自分で使うデータベースは、DBSYSユーティリティで作成したものを使えばよいでしょうが、エンドユーザがアプリケーションのインストールを行わせる場合には、「予め作成済みのテーブルを決められた場所にコピーさせる」という操作すら、できれば無くしたいものです。
もっとも楽な方法は、インストールしたアプリケーションを初回に起動した際に、アプリケーション自身がテーブルを作成するというものです。このために一番手軽なのは、SQLのCREATE TABLE文を、TDBISAMQueryコンポーネントで実行することです。
テーブル作成SQLの作成DBSYSユーティティのメニューから「Utilities」「Reverse Engineer」を選び、既存のテーブルを選択すると、そのテーブルの構造を定義するSQLスクリプトがテキストファイルとして自動生成されます。初めはこの機能を使えば、自分でCREATE TABLE文を書く必要はないでしょう。例えば、以下に挙げるような形式のSQLで、テーブルを作成できます。
DROP TABLE IF EXISTS "biolife";Delphiからの利用 アプリケーションからテーブルを作成するには、上記のようなSQLのDDL文を、TDBISAMQueryコンポーネントのSQLプロパティにセットして、ExecSQLメソッドを呼び出します。
CREATE TABLE IF NOT EXISTS "biolife"
( "Species No" FLOAT,
"Category" CHARACTER(16),
"Common_Name" CHARACTER(30),
"Species Name" CHARACTER(40),
"Length (cm)" FLOAT,
"Length_In" FLOAT,
"Notes" MEMO,
"Graphic" GRAPHIC,
PRIMARY KEY ("Species No") COMPRESS FULL
LOCALE "ANSI Standard"
);
ATableName := 'TestTable';上記のように、テーブルの存在をチェックして、なければ新たに作成し、初期データをセットするという動作全体をコンポーネント化することができます。以下に示すようなコンポーネントを定義して使うのが便利です。
CreateSQL :=
' CREATE TABLE TestTable (' + #13#10 +
' "Key" INTEGER NOT NULL,' + #13#10 +
' "Data" CHARACTER(32) NOT NULL,' + #13#10
' PRIMARY KEY ("Key") COMPRESS NONE' + #13#10 +
' LOCALE "ANSI Standard" ' + #13#10 +
');';
FTable := TDBISAMTable.Create(self);
try
FTable.DatabaseName := DBISAMDatabase.DatabaseName;
FTable.TableName := ATableName;
if not FTable.Exists then begin //存在しなければ作成する
FQuery := TDBISAMQuery.Create(self);
try
FQuery.DatabaseName := FTable.DatabaseName;
FQuery.SQL.Text := CreateSQL;
FQuery.ExecSQL;
finally
FQuery.Free;
end;
end;
try
FTable.Active := True;
FTable.Active := False;
except
raise Exception.Create(
'テーブル作成に失敗しました('+ATableName+')');
end;
finally
FTable.Free;
end;
end;
unit TableCreator;△前 ▼続き
interface
uses Classes, Controls, DBISAMTb;
type
TTableCreator = class(TComponent)
private
FTableName: String;
FSQL: TStringList;
FDatabase: TDBISAMDatabase;
FTable: TDBISAMTable;
FQuery: TDBISAMQuery;
procedure SetSQL(const Value: TStrings);
procedure SetTableName(const Value: string);
procedure SetDatabase(const Value: TDBISAMDatabase);
public
constructor Create(AOwner: TComponent);override;
destructor Destroy; override;
procedure SetupTable; //テーブル(TableName)が存在しなければSQLを実行する
published
property Database: TDBISAMDatabase read FDatabase write SetDatabase;
property TableName: string read FTableName write SetTableName;//作成するテーブル名
property SQL: TStrings read FSQL write SetSQL;//初期化用のSQLスクリプト
end;
procedure Register;
implementation
uses SysUtils;
procedure Register;
begin
RegisterComponents('Local', [TTableCreator]);
end;
{ TTableCreator }
constructor TTableCreator.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSQL := TStringList.Create();
end;
destructor TTableCreator.Destroy;
begin
FSQL.Free;
inherited;
end;
procedure TTableCreator.SetDatabase(const Value: TDBISAMDatabase);
begin
FDatabase := Value;
end;
procedure TTableCreator.SetSQL(const Value: TStrings);
begin
FSQL.Assign(Value);
end;
procedure TTableCreator.SetTableName(const Value: string);
begin
FTableName := Value;
end;
procedure TTableCreator.SetupTable;
begin
FTable := TDBISAMTable.Create(self);
try
FTable.DatabaseName := self.Database.DatabaseName;
FTable.TableName := self.TableName;
if not FTable.Exists then begin
FQuery := TDBISAMQuery.Create(self);
try
FQuery.DatabaseName := self.Database.DatabaseName;
FQuery.SQL.Assign(self.SQL);
FQuery.ExecSQL;
finally
FQuery.Free;
end;
end;
try
// Try to open the table
FTable.Active := True;
FTable.Active := False;
except
raise Exception.Create(
'Cannot Setup Table('+TableName+')');
end;
finally
FTable.Free;
end;
end;
end.