Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

TRUNCATE TABLE

テーブルからすべてのデータを削除し、カウンタをリセットします。

Synopsis

TRUNCATE TABLE tablename

引数

tablename すべての行を削除するテーブル。テーブル行が削除されるビューの指定をすることができます。詳細は、"FROM" を参照してください。

概要

TRUNCATE TABLE コマンドは、テーブルからすべての行を削除し、すべてのテーブル・カウンタをリセットします。テーブルの切り捨ては、直接またはビューを使用して行うことができます。ビューを使用してテーブルを切り捨てる場合は、CREATE VIEW で説明されている削除の必要条件や制限事項に従います。

TRUNCATE TABLE 操作により、ID フィールドIDENTITY フィールド、および SERIAL (%Library.Counter) フィールドの連続した整数値を生成するために使用される内部カウンタがリセットされます。Caché では、TRUNCATE TABLE に従ってテーブルに挿入される最初の行にこれらのフィールドの値 1 を割り当てます。テーブルのすべての行で DELETE を実行しても、これらの内部カウンタはリセットされません。

TRUNCATE TABLE では ROWVERSION カウンタはリセットされません。

TRUNCATE TABLE は、DELETE 処理中にベース・テーブル・トリガの実行を抑制して、トリガが引き出されないようにします。TRUNCATE TABLE は %NOTRIGGER 動作によって削除を実行するため、TRUNCATE TABLE を実行するには、ユーザに %NOTRIGGER 特権が付与されている必要があります (GRANT 文を使用)。TRUNCATE TABLE はこの点で、機能的には以下と同一です。

DELETE %NOTRIGGER FROM tablename

また、TRUNCATE TABLE 操作により、%ROWCOUNT ローカル変数に削除された行数が設定され、%ROWID ローカル変数に最後に削除された行の行 ID が設定されます。

Note:

DELETE コマンドは TRUNCATE TABLE 以上の機能を提供し、テーブルからデータを削除するために優先されるコマンドです。TRUNCATE TABLE は、その他のデータベース・ソフトウェアからのコード移行との互換性のために提供されています。

テーブルを切り捨てるには、以下の条件を満たしている必要があります。

  • テーブルは、現在の (または指定された) ネームスペースに存在している必要があります。指定されたされたテーブルが見つからない場合、Caché は SQLCODE -30 エラーを発行します。

  • テーブルに対する DELETE 特権が必要です。この特権を持っていないと SQLCODE -99 (特権違反) エラーになります。%CHECKPRIV コマンドを呼び出すことにより、現在のユーザが DELETE 特権を持っているかどうかを確認できます。$SYSTEM.SQL.CheckPriv()Opens in a new tab メソッドを呼び出すことにより、指定のユーザが DELETE 特権を持っているかどうかを確認できます。特権の割り当てについては、"GRANT" コマンドを参照してください。

  • テーブルを READONLY として定義することはできません。読み取り専用テーブルを参照するTRUNCATE TABLE をコンパイルすると、SQLCODE -115 エラーが発生します。このエラーは実行時にのみ発生するのではなく、コンパイル時にも発生するようになったことに注意してください。"Caché オブジェクトの使用法" の "永続クラスのその他のオプション" の章で READONLY オブジェクトの説明を参照してください。

  • ビューから削除する場合、ビューは更新可能である必要があり、WITH READ ONLY として定義することはできません。これを実行しようとすると、SQLCODE -35 エラーが返されます。詳細は、"CREATE VIEW" コマンドを参照してください。

  • すべての行が削除可能である必要があります。既定では、1 行以上の行が削除不可能である場合、TRUNCATE TABLE 操作は失敗し、行は削除されません。行をロックできない場合、TRUNCATE TABLE は行の削除に失敗し、エラーが発生します。行の削除が外部キーの参照整合性に違反する場合、TRUNCATE TABLE は行の削除に失敗し、代わりに SQLCODE -124 エラーが発行されます。この既定の動作は以下のように変更できます。

アトミック性

既定では、TRUNCATE TABLEDELETEUPDATE、および INSERT はアトミック処理として実行されます。TRUNCATE TABLE は、正常に終了するか、操作全体がロールバックされるかのいずれかです。行のいずれかを削除できない場合、行は 1 行も削除できずにデータベースは TRUNCATE TABLE を発行する前の状態に戻ります。

現在のプロセスに対するこの既定は、SET TRANSACTION %COMMITMODE を呼び出すことによって SQL 内で変更できます。現在のプロセスに対するこの既定は、SetAutoCommit()Opens in a new tab メソッドを呼び出すことによって ObjectScript 内で変更できます。以下のオプションを使用できます。

  • IMPLICIT または 1 (自動コミットがオン) — 上記のように、これが既定の動作です。各 TRUNCATE TABLE は、個別のトランザクションを構成します。

  • EXPLICIT または 2 (自動コミットがオフ) — 進行中のトランザクションがない場合は、TRUNCATE TABLE コマンドによってトランザクションは自動的に開始されます。ただし、COMMIT または ROLLBACK で明示的にトランザクションを終了する必要があります。EXPLICIT モードでは、トランザクションあたりのデータベース操作の数は、ユーザ定義です。

  • NONE または 0 (トランザクションなしを自動化しない) — TRUNCATE TABLE を呼び出してもトランザクションは開始されません。TRUNCATE TABLE 操作の失敗により、行の一部が削除されたり削除されなかったりすることで、データベースが整合性のない状態になる可能性があります。このモードでトランザクションのサポートを提供するには、START TRANSACTION を使用してトランザクションを開始し、COMMIT または ROLLBACK を使用してトランザクションを終了する必要があります。

現在のプロセスのアトミック性設定を確認するには、以下の ObjectScript の例のように、GetAutoCommit()Opens in a new tab メソッドを使用します。

  DO $SYSTEM.SQL.SetAutoCommit($RANDOM(3))
  SET x=$SYSTEM.SQL.GetAutoCommit()
  IF x=1 {
    WRITE "Default atomicity behavior",!
    WRITE "automatic commit or rollback" }
  ELSEIF x=0 {
    WRITE "No transaction initiated, no atomicity:",!
    WRITE "failed DELETE can leave database inconsistent",!
    WRITE "rollback is not supported" }
  ELSE { WRITE "Explicit commit or rollback required" }

参照整合性

Caché ではシステム構成設定を使用して外部キーの参照整合性チェックを実行するかどうかが決まります。システムの既定値は以下のように設定できます。

  • $SYSTEM.SQL.SetFilerRefIntegrity()Opens in a new tab メソッド呼び出し。

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[INSERT、UPDATE、DALETE の外部キーについて参照整合性チェックを実行する] の現在の設定を表示して編集します。既定は “はい” です。この設定を変更すると、変更後に開始される新しいプロセスは、新しい設定になります。

TRUNCATE TABLE 操作時には、すべての外部キー参照について、参照されるテーブルの該当する行に対する共有ロックが取得されます。この行は、トランザクションの終了までロックされています。これにより、参照される行は、TRUNCATE TABLE のロールバックがあってもそれより前に変更されることがなくなります。

トランザクションでのロック

Caché は、TRUNCATE TABLE 操作時に標準のロックを実行します。一意フィールドの値は、現行のトランザクションの間、ロックされます。

既定のロックしきい値は、テーブルごとに 1000 ロックです。つまり、トランザクション時にテーブルから 1000 を超える一意フィールド値を削除する場合は、ロックしきい値に到達し、Caché はロック・レベルを自動的に一意フィールド値ロックからテーブル・ロックへと上げます。これによってトランザクション時に、ロック・テーブルをオーバーフローすることなく、大規模な削除を実行できます。

現在のシステム全体のロックしきい値は、GetLockThreshold()Opens in a new tab メソッドを使用して確認できます。このシステム全体のロックしきい値は、以下の方法を使用して設定できます。

  • SetLockThreshold()Opens in a new tab メソッドを使用する。

  • 管理ポータルを使用する。システム, 構成, 一般SQL設定 に移動します。[ロックしきい値] の現在の設定を表示して編集します。

ロックしきい値を変更するには、%Admin Manage Resource の USE 許可が必要です。Caché は、ロックしきい値の変更を現在のプロセスすべてに即座に適用します。

トランザクションでのロックの詳細は、"Caché SQL の使用法" の “データベースの変更“ の章にある "トランザクション処理" を参照してください。

インポートされた SQL のコード

DDLImport("CACHE")Opens in a new tab および Cache()Opens in a new tab メソッドは TRUNCATE TABLE コマンドをサポートしません。これらのメソッドによってインポートされた SQL コード・ファイルの TRUNCATE TABLE コマンドは無視されます。これらのインポート・メソッドは DELETE コマンドをサポートします。

以下の 2 つのダイナミック SQL の例では、DELETETRUNCATE TABLE を比較しています。それぞれの例では、テーブルを作成し、テーブルに行を挿入し、テーブル内のすべての行を削除してから、空になったテーブルに単一の行を挿入しています。

最初の例では DELETE を使用して、テーブル内のすべてのレコードを削除します。DELETE は %RowID カウンタをリセットしないことに注意してください。

  ZNSPACE "SAMPLES"
  SET tcreate = "CREATE TABLE SQLUser.MyStudents (StudentName VARCHAR(32),StudentDOB DATE)"
  SET tinsert = "INSERT INTO SQLUser.MyStudents (StudentName,StudentDOB) "_
                "SELECT Name,DOB FROM Sample.Person WHERE Age <= '21'"
  SET tinsert1 = "INSERT INTO SQLUser.MyStudents (StudentName,StudentDOB) VALUES ('Bob Jones',60123)"
  SET tdelete = "DELETE SQLUser.MyStudents"
  SET tStatement = ##class(%SQL.Statement).%New()
  SET qStatus = tStatement.%Prepare(tcreate)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName,!

  SET qStatus = tStatement.%Prepare(tinsert)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!

  SET qStatus = tStatement.%Prepare(tdelete)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!

  SET qStatus = tStatement.%Prepare(tinsert1)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!
  &sql(DROP TABLE SQLUser.MyStudents)

2 番目の例では TRUNCATE TABLE を使用して、テーブル内のすべてのレコードを削除します。%StatementTypeNameOpens in a new tabTRUNCATE TABLE に対して “DELETE” を返すことに注意してください。TRUNCATE TABLE は %RowID カウンタを 0 にリセットすることに注意してください。

  ZNSPACE "SAMPLES"
  SET tcreate = "CREATE TABLE SQLUser.MyStudents (StudentName VARCHAR(32),StudentDOB DATE)"
  SET tinsert = "INSERT INTO SQLUser.MyStudents (StudentName,StudentDOB) "_
                "SELECT Name,DOB FROM Sample.Person WHERE Age <= '21'"
  SET tinsert1 = "INSERT INTO SQLUser.MyStudents (StudentName,StudentDOB) VALUES ('Bob Jones',60123)"
  SET ttrunc = "TRUNCATE TABLE SQLUser.MyStudents"
  SET tStatement = ##class(%SQL.Statement).%New()
  SET qStatus = tStatement.%Prepare(tcreate)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName,!

  SET qStatus = tStatement.%Prepare(tinsert)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!

  SET qStatus = tStatement.%Prepare(ttrunc)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!

  SET qStatus = tStatement.%Prepare(tinsert1)
   IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
   WRITE rset.%StatementTypeName," rowcount ",rset.%ROWCOUNT," last rowID: ",rset.%ROWID,!
  &sql(DROP TABLE SQLUser.MyStudents)

関連項目

FeedbackOpens in a new tab