PSQL Programmer's Guide (v11)

レコードの挿入と更新 (トランザクショナル インターフェイス)

ほとんどの場合、レコードの挿入と更新は簡単なプロセスです。つまり、Insert オペレーション(2)または Update オペレーション(3)を使用し、データ バッファーを使用してレコードを渡します。ここでは、挿入と更新に関連するいくつかの特別な場合について説明します。

ミッションクリティカルな挿入と更新における信頼性の確保

MicroKernel は非常に信頼性のあるデータ管理エンジンですが、システム障害を防ぐことができません。クライアント/サーバー アプリケーションでシステム障害がよく起こるのは、ネットワーク障害が発生する可能性があるからです。以下の MicroKernel 機能を利用して、信頼性を高めることができます。

重複不可キーの挿入

レコードを挿入する場合で、同じキー値が既に存在する可能性があり、それを重複させたくない場合は、次のいずれかの方法を実行します。

Insert オペレーションが単独で存在し、ファイル内の論理カレンシーに依存しない場合、各 Insert より前に Get Equal を実行すると、オーバーヘッドが増えます。しかし、挿入がグループになっている場合は、Get Equal オペレーションがキー位置を指すインデックス ページをメモリに取り込むことで、これ以降に行われる Insert オペレーションが促進されます。

可変長レコードの挿入および更新

可変長データ ファイルを設計する場合は、アプリケーションがサポートするレコードの可変長部分の最大サイズを決定する必要があります。固定長部分と可変長部分の最大サイズを合計したサイズを収容するレコード構造を設定する必要があります。可変長レコードの読み取り、挿入および更新を行うときは、この構造体をデータ バッファーとして使用します。

可変長レコードを挿入または更新する場合は、データ バッファー長パラメーターによって書き込むデータ量を MicroKernel に指示します。固定長部分のサイズに可変長部分の実際のデータ量を加えたサイズに、このパラメーターを設定します。データ バッファー長を、アプリケーションが可変長フィールドに対して許可する最大サイズに固定長を加えたサイズに設定しないでください。設定すると、MicroKernel は常に最大サイズを書き込みます。

たとえば、以下のレコードを挿入すると仮定します。

キー 0:Owner
30 バイト ZSTRING
キー 1:Account
8 バイト INTEGER
Balance(キーではない)
8 バイト
Comments(キーではない)
1,000 バイト
John Q. Smith
263512477
1024.38
解説

以下に、Insert オペレーションの例を示します。ここで、データ バッファー長は固定長部分に Comments フィールド内のデータ量(8 バイト)を加えた長さとして計算されることに注意してください。加えるのは、Comments フィールドの最大サイズ(1,000 バイト)ではありません。

Insert オペレーション

#define MAX_COMMENT 1000 /* コメントの最大サイズ */ 
typedef struct  
{ char owner[30]; 
  int  number; 
  int  balance; 
} FixedData; 
typedef struct  
{ FixedData fix; 
  char      variable[MAX_COMMENT]; 
} DataBuffer; 
 
  DataBuffer account;  
  BTI_ULONG  dataBufLen;  
  BTI_SINT   status;  
   
  strcpy(account.fix.owner, "John Q. Smith");  
  account.fix.number = 263512477;  
  account.fix.balance = 102438; 
  strcpy (account.variable, “Comments”); 
  dataBufLen = sizeof(FixedData) + strlen(account.variable) +1; 
    /* +1 はデータの後にヌル文字用 */ 
  status = BTRV(B_INSERT, PosBlock, &account, &dataBufLen, keyBuffer, 0); 

固定長部分の読み取りおよび更新

データ バッファー サイズを固定長に設定することによって、レコードの固定長部分だけを読み取ることができます。MicroKernel は、固定長部分とステータス コード 22 だけを読み取りますが、そのとき Update オペレーションを使用し、固定長部分だけを渡すと、可変長部分は失われます。その代わり、Update Chunk オペレーション(53)を使用すると、バイト オフセットと長さに基づいてレコードの一部が更新されます。バイト オフセットを 0 に設定し、その長さを固定長部分の長さに設定します。このオペレーションは固定長部分を更新し、可変長部分を残します。

変更不可キーの更新

変更不可と定義されているキー値を更新しようとすると、MicroKernel はステータス コード 10 を返します。いずれにしてもキー値を変更する場合は、まずレコードを Delete(4)し、次にレコードを Insert(2)する必要があります。

No-Currency-Change(NCC)オペレーション

キー番号パラメーターに -1(0xFF)を渡すことによって、No-Currency-Change(NCC)オペレーションと呼ぶ、標準の Insert または Update のバリエーションを実行することができます。NCC オペレーションは、アプリケーションが Get Next オペレーション(6)などの別のオペレーションを実行するために元の論理位置をファイルに保存しておく必要がある場合に有効です。

NCC Insert オペレーションを使用せずに同じ効果を実現するには、以下の手順を実行する必要があります。

  1. Get Position(22)-現在の論理レコードの 4 バイト物理アドレスを取得します。手順 3 で使用するためにこの値を保存します。
  2. Insert(2)-新しいレコードを挿入します。このオペレーションにより、新しい論理カレンシーおよび物理カレンシーが確立されます。
  3. Get Direct/Record(23)-論理カレンシーと物理カレンシーが手順 1 の時点の状態になるよう、これらを再確立します。

NCC Insert オペレーションは論理カレンシーで標準の Insert と同じ効果がありますが、物理カレンシーでは別の効果があります。たとえば、これら 2 つの手順のいずれかに続けて Get Next(6)オペレーションを実行した場合は、どちらの手順でも結果は変わりませんが、Step Next(24)を実行した場合は、異なるレコードが返される可能性があります。

NCC Update オペレーションを使用せずにオリジナルの位置を保つには、以下の手順を実行する必要があります。

  1. Get Next(6)-次の論理レコードを確立します。
  2. Get Position(22)-次の論理レコードの 4 バイトの物理アドレスを取得します。手順 8 で使用するためにこの値を保存します。
  3. Get Previous(7)-現在の論理レコードを再確立します。
  4. Get Previous(7)-直前のレコードを確立します。
  5. Get Position(22)-直前の論理レコードの 4 バイトの物理アドレスを取得します。手順 8 で使用するためにこの値を保存します。
  6. Get Next(6)-現在の論理レコードを再確立します。
  7. Update(3)-影響を受けたレコードを更新します。この標準の Update オペレーションが指定されたキーの値を変更する場合、新しい論理カレンシーも確立します。
  8. Get Direct/Record(23)-手順 7 で更新されたレコードの前または後のレコードにカレンシーを設定します。アプリケーションが前方検索を続ける場合は、手順 2 で保存されたアドレスを Get Direct/Record オペレーションに渡します。アプリケーションが後方検索を続ける場合は、手順 5 で保存されたアドレスを渡します。

レコードへのアクセス (トランザクショナル インターフェイス)

マルチレコードのオペレーション (トランザクショナル インターフェイス)