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?

DELETE

テーブルの行を削除します。

Synopsis

DELETE [%NOFPLAN] [restriction] [FROM] table-ref [[AS] t-alias]
     [FROM select-table1 [[AS] t-alias]
              {,select-table2 [[AS] t-alias]} ]
     [WHERE condition-expression]
DELETE [restriction] [FROM] table-ref [[AS] t-alias]
     [WHERE CURRENT OF cursor]

引数

%NOFPLAN オプション — %NOFPLAN キーワードは、Caché がこの操作の凍結されたプラン (ある場合) を無視して、新しいクエリ・プランを生成することを指定します。凍結されたプランは保持されますが、使用されません。 詳細は、"Caché SQL 最適化ガイド" の "凍結プラン" を参照してください。
restriction オプション — %NOLOCK、%NOCHECK、%NOINDEX、%NOTRIGGER のキーワードのうちの 1 つ、またはこれらのキーワードの空白で区切られたリスト。
FROM table-ref 行を削除するテーブル。これは、FROM 節ではありません。1 つのテーブル参照が続く FROM キーワードです(FROM キーワードはオプションで、table-ref は必須です)。テーブル参照の代わりに、テーブル行を削除できるビューを指定することも、括弧で囲んだサブクエリを指定することもできます。SELECT 文の FROM 節とは異なり、ここでは optimize-option キーワードは指定できません。この引数でテーブル値関数や JOIN 構文を指定することはできません。
FROM 節

オプションtable-refに指定する FROM 節。この FROM を使用して、削除する行を選択するために使用される 1 つ以上の select-table テーブルを指定できます。

複数のテーブルは、コンマ区切りのリストとして指定するか、ANSI 結合キーワードで関連付けることができます。テーブルあるいはビューのあらゆる組み合わせを指定できます。ここで 2 つの select-table の間にコンマを指定する場合、Caché は複数のテーブルに CROSS JOIN を実行して、JOIN 処理の結果テーブルからデータを取得します。ここで 2 つの select-table の間に ANSI 結合キーワードを指定する場合、Caché は指定された結合処理を実行します。詳細は、このドキュメントの "JOIN" のページを参照してください。

オプションで、クエリ実行を最適化するために、1 つ以上の optimize-option キーワードを指定できます。使用可能なオプションは、%ALLINDEX、%FIRSTTABLE tablename、%FULL、%INORDER、%IGNOREINDICES、%NOFLATTEN、%NOMERGE、%NOSVSO、%NOTOPOPT、%NOUNIONOROPT、および %STARTTABLE です。詳細は、"FROM" 節を参照してください。

AS t-alias オプションテーブルまたはビューの名前のエイリアス。エイリアスは有効な識別子である必要があります。AS キーワードはオプションです。
WHERE condition-expression オプション — 削除する行を限定する 1 つまたは複数のブーリアン述語を指定します。WHERE 節または WHERE CURRENT OF 節を指定することができます (両方は不可)。WHERE 節 (または WHERE CURRENT OF 節) が指定されていない場合、DELETE はテーブルからすべての行を削除します。詳細は、"WHERE" を参照してください。
WHERE CURRENT OF cursor オプション : 埋め込み SQL のみDELETE 処理がカーソルの現在の位置でレコードを削除することを指定します。WHERE CURRENT OF 節または WHERE 節を指定することができます (両方は不可)。WHERE CURRENT OF 節 (または WHERE 節) が指定されていない場合、DELETE はテーブルからすべての行を削除します。詳細は、"WHERE CURRENT OF" を参照してください。

概要

DELETE コマンドは、指定条件に適合する行をテーブルから削除します。テーブルからの行の削除は、直接、またはビュー経由が可能です。あるいは、サブクエリを使用して選択した行を削除できます。ビュー経由で削除する場合は、CREATE VIEW で説明されているように、必要条件や制限事項に従います。

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

table-ref は指定が必須です。table-ref の前の FROM キーワードは省略可能です。テーブルからすべての行を削除するには、以下のように指定します。

DELETE FROM tablename

または

DELETE tablename

これにより、テーブルからすべての行データが削除されますが、RowIdIDENTITY、および SERIAL (%Library.Counter) フィールドの各カウンタはリセットされません。TRUNCATE TABLE コマンドが、テーブルからすべての行データを削除し、これらのカウンタをリセットします。既定では、DELETE FROM tablename が削除トリガをプルします。削除トリガをプルしない場合は DELETE %NOTRIGGER FROM tablename と指定します。TRUNCATE TABLE は削除トリガをプルしません。

DELETE を使用する場合、一般的には condition-expression に基づいて削除する行を指定します。既定では、DELETE 処理はテーブルのすべての行をチェックし、condition-expression を満たすすべての行を削除します。condition-expression を満たす行がない場合、DELETE は正常に終了して SQLCODE=100 (データがこれ以上ありません) を設定します。

WHERE 節または WHERE CURRENT OF 節を指定することができます (両方は不可)。WHERE CURRENT OF 節が使用される場合、DELETE 処理は現在のカーソル位置のレコードを削除します。WHERE CURRENT OF を使用する DELETE の例は、後述の “埋め込み SQL とダイナミック SQL の例” を参照してください。指定位置での実行の詳細は、"WHERE CURRENT OF" を参照してください。

既定では、DELETE は、全か無かのイベントです。指定されたすべての行が削除されるか、削除されないかのいずれかです。Caché は、DELETE の成功または失敗を示す SQLCODE ステータス変数を設定します。

テーブルから行を削除するには、以下の条件を満たしている必要があります。

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

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

  • 他のプロセスはテーブルを IN EXCLUSIVE MODE でロックできません。ロックされているテーブルから行を削除しようとすると、SQLCODE -110 エラーになり、%msg は "RowID = '10' の行でテーブル 'Sample.Person' の DELETE ロックを獲得できません" になります。SQLCODE -110 エラーは、 DELETE 文が削除される最初のレコードを検出したときにのみ発行され、タイムアウト期間内にロックできないことに注意してください。

  • DELETE コマンドの WHERE 節で、存在しないフィールドを指定すると、SQLCODE -29 が発行されます。指定したテーブルのために定義されているすべてのフィールド名をリストするには、"Caché SQL の使用法" の “テーブルの定義” の章の "列の名前と番号" を参照してください。フィールドは存在するが DELETE コマンドの WHERE 節の条件を満たすフィールド値がない場合は、影響を受ける行はないため、SQLCODE 100 (データの末尾) が発行されます。

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

  • ビュー経由で削除する場合、ビューを WITH READ ONLY として定義することはできません。これを実行しようとすると、SQLCODE -35 エラーが返されます。詳細は、"CREATE VIEW" コマンドを参照してください。同様に、サブクエリ経由で削除する場合は、そのサブクエリが更新可能である必要があります。例えば、サブクエリ DELETE FROM (SELECT COUNT(*) FROM Sample.Person) AS x を実行すると、SQLCODE -35 エラーが発生します。

  • 削除する行が存在している必要があります。通常、存在しない行を削除しようとすると、指定された行が見つからないため、SQLCODE 100 (これ以上データがない) が返されます。ただしまれに、削除する行が見つかったが別のプロセスにより即座に削除された場合には、SQLCODE -106 が返されます。

  • 削除対象に指定されたすべての行が削除可能である必要があります。既定では、1 行以上の行が削除不可能である場合、DELETE 操作は失敗し、行は削除されません。削除する行が別の同時プロセスによってロックされている場合、DELETE は SQLCODE -110 エラーを発行します。%NOCHECK が指定されていない状態で、指定された行のいずれかの削除操作が外部キーの参照整合性に違反する場合、DELETE は SQLCODE -124 エラーを発行します。この既定の動作は以下のように変更できます。

  • システム提供の特定 %SYS ネームスペース機能が削除されないように保護されています。例えば、DELETE FROM Security.Users は、_SYSTEM、_PUBLIC、または UnknownUser の削除には使用できません。これを実行しようとすると、SQLCODE -134 エラーが返されます。

アトミック性

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

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

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

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

  • NONE または 0 (トランザクションなしを自動化しない) — DELETE を呼び出してもトランザクションは開始されません。DELETE 操作の失敗により、指定された行の一部が削除されたり削除されなかったりすることで、データベースが整合性のない状態になる可能性があります。このモードでトランザクションのサポートを提供するには、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" }

FROM 構文

DELETE コマンドには、テーブルを指定する 2 つの FROM キーワードを含めることができます。この 2 つの FROM の使用法は根本的に異なります。

  • table-ref の前の FROM で、1 つ以上の行を削除するテーブル (またはビュー) を指定します。これは FROM キーワードであり、FROM 節ではありません。テーブルは 1 つのみ指定できます。結合構文または optimize-option キーワードを指定することはできません。FROM キーワード自体はオプションで、table-ref は必須です。

  • table-ref の後の FROM はオプションの FROM 節で、削除する行を特定するのに使用できます。1 つ以上のテーブルを指定できます。結合構文や optimize-option キーワードを含め、SELECT 文に使用できるすべての FROM 節の構文がサポートされます。この FROM 節は、(常にではありませんが) 通常は WHERE 節と共に使用します。

したがって、以下のいずれも有効な構文形式になります。

DELETE FROM table WHERE ...
DELETE table WHERE ...
DELETE FROM table FROM table2 WHERE ...
DELETE table FROM table2 WHERE ...

この構文では、Transact-SQL と互換性のある方法で複雑な選択条件がサポートされます。

以下の例は、2 つの FROM キーワードを使用する方法を示しています。ここでは、Retirees テーブル内に同じ EmpId がある場合、それらのレコードが Employees テーブルから削除されます。

DELETE FROM Employees AS Emp
       FROM Retirees AS Rt
       WHERE Emp.EmpId = Rt.EmpId

2 つの FROM キーワードで同じテーブルを参照する場合には、参照するテーブルが文字どおり同じであることも、テーブルの 2 つのインスタンスの結合であることもあります。これは、テーブルのエイリアスの使用方法によって異なります。

  • 両方のテーブル参照にエイリアスがない場合には、両方とも同じテーブルを参照します。

      DELETE FROM table1 FROM table1,table2   /* join of 2 tables */
    
  • 両方のテーブル参照に同じエイリアスがある場合には、両方とも同じテーブルを参照します。

      DELETE FROM table1 AS x FROM table1 AS x,table2   /* join of 2 tables */
    
  • 両方のテーブル参照にエイリアスがあり、それぞれのエイリアスが異なる場合には、Caché は 2 つのテーブルのインスタンスの結合を実行します。

      DELETE FROM table1 AS x FROM table1 AS y,table2   /* join of 3 tables */
    
  • 最初のテーブル参照にエイリアスがあり、2 番目にはない場合には、Caché は 2 つのテーブルのインスタンスの結合を実行します。

      DELETE FROM table1 AS x FROM table1,table2   /* join of 3 tables */
    
  • 最初のテーブル参照にエイリアスがなく、2 番目にはエイリアスのあるテーブルへの単一の参照がある場合には、両方とも同じテーブルを参照し、このテーブルには指定されたエイリアスがあります。

      DELETE FROM table1 FROM table1 AS x,table2   /* join of 2 tables */
    
  • 最初のテーブル参照にエイリアスがなく、2 番目にはテーブルへの複数の参照がある場合には、それぞれのエイリアスされたインスタンスは個別のテーブルと見なされ、それらのテーブルの結合が実行されます。

      DELETE FROM table1 FROM table1,table1 AS x,table2   /* join of 3 tables */
      DELETE FROM table1 FROM table1 AS x,table1 AS y,table2   /* join of 4 tables */
    
    

制限引数

restriction 引数を使用するには、現在のネームスペースに対応する admin-privilege が必要となります。詳細は "GRANT" を参照してください。

restriction 引数を指定すると、以下のように処理を制限します。

  • %NOCHECK — 削除される行を参照する外部キーの参照整合性チェックを抑制します。

  • %NOLOCK — 削除される行の行のロックを抑制します。単独のユーザ/処理がデータベースを更新する際にのみ使用します。

  • %NOINDEX — 削除される行のために全インデックスでのインデックス・エントリの削除を抑制します。テーブル・インデックス内に孤立した値が残るため、これは十分に注意して使用する必要があります。

  • %NOTRIGGER — DELETE 処理中にベース・テーブル・トリガの実行を抑制して、トリガが引き出されないようにします。

複数の restriction 引数を順不同で指定できます。複数の引数は、空白で区切られます。

親レコードの削除時に restriction 引数を指定すると、対応する子レコードの削除時に同じ restriction 引数が適用されます。

参照整合性

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

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

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

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

一連の外部キー参照が CASCADE として定義されている場合は、DELETE 操作により、循環参照が発生する可能性があります。Caché では、CASCADE 参照動作のある DELETE による循環参照ループの反復を防止します。元のテーブルに戻ると、Caché は、カスケード・シーケンスを終了します。

CASCADE、SET NULL、または SET DEFAULT で定義された外部キー・フィールドに対して、%NOLOCK を指定して DELETE 操作を実行した場合は、対応する参照アクションが %NOLOCK によって実行されて外部キー・テーブルが変更されます。

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

%NOLOCK を指定しない場合、INSERTUPDATE、および DELETE 操作時に自動的にレコードに標準のロックがかかります。影響を受ける各レコード (行) は、現在のトランザクションが継続している間はロックされます。

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

Caché は、以下の 2 つのロック・エスカレーション策のどちらかを適用します。

  • “E” タイプのロック・エスカレーション:Caché は、次のことに該当する場合にこのタイプのロック・エスカレーションを使用します。(1) クラスで %CacheStorage が使用されている (これは、管理ポータルの SQL スキーマ表示で [カタログの詳細] から判断できます)。(2) クラスで、IDKey インデックスが指定されていないか、単一プロパティの IDKey インデックスが指定されている。“E” タイプのロック・エスカレーションについては、"Caché ObjectScript リファレンス" の LOCK コマンドで説明されています。

  • 従来の SQL ロック・エスカレーション:クラスで “E” タイプのロック・エスカレーションが使用されない理由は、マルチプロパティの IDKey インデックスの存在にあると考えられます。この場合は、%Save ごとにロック・カウンタがインクリメントされます。つまり、トランザクション内の単一オブジェクトを 1001 回保存を行うと、Caché はロックのエスカレーションを試みます。

どちらのロック・エスカレーション策の場合も、$SYSTEM.SQL.GetLockThreshold()Opens in a new tab メソッドを使用して、現在のシステム全体用ロックしきい値を決定できます。既定は 1000 です。このシステム全体のロックしきい値は、以下の方法を使用して設定できます。

  • $SYSTEM.SQL.SetLockThreshold()Opens in a new tab メソッドを使用します。

  • 管理ポータルを使用する。システム, 構成, 一般SQL設定 に移動します。[ロックしきい値] の現在の設定を表示して編集します。既定は 1000 ロックです。この設定を変更すると、変更後に開始される新しいプロセスは、新しい設定になります。

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

結果として、自動ロック・エスカレーションでは、デッドロックの状況が起こる可能性があります。つまり、テーブル・ロックへのエスカレーションを試みたときに、テーブル内のレコード・ロックを保持する別プロセスとの競合が起こる可能性があります。これを避けるための方策としては、次のいくつかが考えられます。 (1) ロック・エスカレーションがトランザクション内で起こる可能性が低くなるように、ロック・エスカレーションのしきい値を上げる。(2) ロック・エスカレーションが即座に起こるように、ロック・エスカレーションのしきい値を大幅に下げる。これにより、別プロセスが同一テーブル内のレコードをロックする機会が少なくなります。(3) トランザクションが継続している間はテーブル・ロックを適用し、レコード・ロックは実行しない。これは、LOCK TABLE、UNLOCK TABLE (テーブル・ロックがトランザクションの終了まで持続するよう、IMMEDIATE キーワードはなし) の順に指定することで、トランザクション開始時に実行できます。その後、%NOLOCK オプションを使用して削除を実行します。

自動ロック・エスカレーションは、ロック・テーブルのオーバーフローを防ぐことを目的としています。ただし、大量の削除などを実行したために <LOCKTABLEFULL> エラーが発生した場合は、DELETE によって SQLCODE -110 エラーが発行されます。

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

以下の例は、両方とも、TempEmployees テーブルからすべての行を削除します。FROM キーワードはオプションです。

DELETE FROM TempEmployees
DELETE TempEmployees

以下の例は、Employees テーブルから、従業員番号 234 番を削除します。

DELETE
     FROM Employees
     WHERE EmpId = 234

以下の例は、CurStatus 列が "Retired" に設定されているすべての行を、ActiveEmployees テーブルから削除します。

DELETE FROM ActiveEmployees
     WHERE CurStatus = 'Retired'

以下の例は、サブクエリを使用して行を削除します。

DELETE FROM (SELECT Name,Age FROM Sample.Person WHERE Age > 65)

埋め込み SQL とダイナミック SQL の例

以下に示す一連のプログラム例のうち、最初のプログラムでは、3 つの列を持つ SQLUser.WordPairs という名前のテーブルを作成します。その次のプログラムではテーブルに 6 つのレコードを挿入します。以降のプログラムでは、カーソル・ベースの埋め込み SQL を使用してすべての English レコードを削除し、ダイナミック SQL を使用してすべての French レコードを削除します。最後のプログラムでは、残りのレコードを表示し、その後テーブルを削除します。

CreateTable
   ZNSPACE "Samples"
   &sql(CREATE TABLE SQLUser.WordPairs (
        Lang        CHAR(2) NOT NULL,
        Firstword   CHAR(30),
        Lastword    CHAR(30) )
       )
  IF SQLCODE=0 {
    WRITE !,"Table created" }
  ELSEIF SQLCODE=-201 {WRITE !,"Table already exists"  QUIT}
  ELSE {
    WRITE !,"CREATE TABLE failed. SQLCODE=",SQLCODE }
InsertSixRecords
  #SQLCompile Path=Cinema,Sample
  ZNSPACE "Samples"
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('En','hello','goodbye'))
  IF SQLCODE = 0 { WRITE !,"1st record inserted" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE
         QUIT}
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('Fr','bonjour','au revoir'))
  IF SQLCODE = 0 { WRITE !,"2nd record inserted" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE  QUIT}
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('It','pronto','ciao'))
  IF SQLCODE = 0 { WRITE !,"3rd record inserted" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE  QUIT}
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('Fr','oui','non'))
  IF SQLCODE = 0 { WRITE !,"4th record inserted" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE  QUIT}
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('En','howdy','see ya'))
  IF SQLCODE = 0 { WRITE !,"5th record inserted" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE  QUIT}
  &sql(INSERT INTO WordPairs (Lang,Firstword,Lastword) VALUES 
   ('Es','hola','adios'))
  IF SQLCODE = 0 { WRITE !,"6th record inserted",!!
     SET myquery = "SELECT %ID,* FROM SQLUser.WordPairs"
     SET tStatement = ##class(%SQL.Statement).%New()
     SET qStatus = tStatement.%Prepare(myquery)
       IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
     SET rset = tStatement.%Execute()
     DO rset.%Display()
     WRITE !,"End of data" }
  ELSE { WRITE !,"Insert failed, SQLCODE=",SQLCODE }
EmbeddedSQLDeleteEnglish
  #SQLCompile Path=Sample
  NEW SQLCODE,%ROWCOUNT,%ROWID
  &sql(DECLARE WPCursor CURSOR FOR 
        SELECT Lang FROM WordPairs
        WHERE Lang='En')
   &sql(OPEN WPCursor)
   FOR { &sql(FETCH WPCursor)
        QUIT:SQLCODE 
        &sql(DELETE FROM WordPairs
       WHERE CURRENT OF WPCursor)
    IF SQLCODE=0 {
    WRITE !,"Delete succeeded"
    WRITE !,"Row count=",%ROWCOUNT," RowID=",%ROWID }
    ELSE {
    WRITE !,"Delete failed, SQLCODE=",SQLCODE }
    }
    &sql(CLOSE WPCursor)
DynamicSQLDeleteFrench
  SET sqltext = "DELETE FROM WordPairs WHERE Lang=?"
  SET tStatement = ##class(%SQL.Statement).%New(0,"Sample")
  SET qStatus = tStatement.%Prepare(sqltext)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rtn = tStatement.%Execute("Fr")
  IF rtn.%SQLCODE=0 {
    WRITE !,"Delete succeeded"
    WRITE !,"Row count=",rtn.%ROWCOUNT," RowID of last record=",rtn.%ROWID }
  ELSE {
    WRITE !,"Delete failed, SQLCODE=",rtn.%SQLCODE }
DisplayAndDeleteTable
  ZNSPACE "Samples"
  SET myquery = "SELECT %ID,* FROM SQLUser.WordPairs"
  SET tStatement = ##class(%SQL.Statement).%New()
  SET qStatus = tStatement.%Prepare(myquery)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rset = tStatement.%Execute()
  DO rset.%Display()
  WRITE !,"End of data"
  &sql(DROP TABLE SQLUser.WordPairs)
   IF SQLCODE=0 {
    WRITE !!,"Table deleted"
    QUIT }
  ELSE {
    WRITE !,"Table delete failed, SQLCODE=",SQLCODE }

関連項目

FeedbackOpens in a new tab