テーブルに 1 行以上の新しい行を追加します。
Synopsis
INSERT [restriction] INTO table
DEFAULT VALUES |
[(columnlist)] VALUES (valuelist) |
[(columnlist)] VALUES host-variable |
[(columnlist)] query |
SET column1=value1 {,column2=value2, . . . }
-
INSERT では、新しい 1 行のデータ値をテーブルに挿入できます。
-
INSERT 文は、テーブルに新しい行を 1 行追加します。
SELECT 文と組み合わせた
INSERT 文では、テーブルに複数の新しい行を挿入できます。このテクニックは一般に、あるテーブルに他のテーブルから抽出した既存のデータを追加する場合に使用されます。このような
INSERT の使用方法は、以下の "
INSERT クエリ結果" のセクションで説明されています。
テーブルには、直接挿入することも、ビュー経由で挿入することもできます。ビュー経由で挿入する場合は、
CREATE VIEW で説明されているように、必要条件や制限事項に従います。
INSERT は、全か無かのイベントです。行がすべて挿入されるか、まったく挿入されないかのいずれかです。Caché は、SQLCODE ステータス変数を返し、
INSERT の成功もしくは失敗を示します。テーブルに行を挿入するには、以下の条件を満たしている必要があります。
-
テーブル名が存在している必要があります。存在しないテーブルに対して挿入を実行すると、SQLCODE -30 エラーが返されます。
-
テーブルに対する INSERT 特権と SELECT 特権の両方が必要です。これらの特権を持っていないと SQLCODE -99 (特権違反) エラーになります。詳細は、"
GRANT" コマンドを参照してください。
-
テーブルを READONLY として定義することはできません。読み取り専用テーブルを参照する
INSERT をコンパイルすると、SQLCODE -115 エラーが発生します。このエラーは実行時にのみ発生するのではなく、コンパイル時にも発生するようになったことに注意してください。"
Caché オブジェクトの使用法" の "
オブジェクトの永続性" の章で READONLY オブジェクトの説明を参照してください。
-
ビュー経由でテーブルを更新する場合、ビューを WITH READ ONLY として定義することはできません。これを実行しようとすると、SQLCODE -35 エラーが返されます。詳細は、"
CREATE VIEW" コマンドを参照してください。
-
すべての必須フィールドが挿入処理に指定されている必要があります。必須フィールドの値を指定せずに行を挿入すると、SQLCODE -108 エラーが返されます。
-
挿入に READONLY として定義されているフィールドを含めることはできません。読み取り専用フィールドを参照する
INSERT をコンパイルすると、SQLCODE -138 エラーが発生します。このエラーは実行時にのみ発生するのではなく、コンパイル時にも発生するようになったことに注意してください。
-
システム生成値のみが格納される、RowID、IDKey、IDENTITY などのフィールドを挿入対象に含めることはできません。これらのフィールドのいずれかに非 NULL フィールド値を挿入すると、SQLCODE -111 エラーが返されます。これらのフィールドのいずれかに NULL を挿入すると、Caché はその NULL をシステム生成値でオーバーライドします。したがって、挿入処理は成功し、エラー・コードは発行されません。
-
各フィールドの値が有効な値である必要があります。無効なフィールド値を挿入すると、SQLCODE -104 エラーが返されます。
-
すべてのフィールド値がすべてのフィールド制約に合格する必要があります。例えば、一意制約のあるフィールドに重複フィールド値を挿入すると、SQLCODE -119 エラーが返されます。
列のリストを省略すると、
INSERT は、すべての列が列番号順で挿入されるものと判断します。列のリストを指定すると、個々の値は、列のリスト内の列の名前と位置的に一致する必要があります。
INSERT オペレーションは、%ROWCOUNT 変数を、影響を受けた行の数に設定します (必ず 0 または 1 のどちらか)。
フィールド値がすべてそのフィールドの既定値に設定されているか NULL 値に設定されている行をテーブルに挿入できます。これには、以下のコマンドを使用します。
INSERT INTO Mytable DEFAULT VALUES
-
%NOCHECK 外部キーの参照整合性チェックは実行されません。ビュー経由で
INSERT を実行する際、ビューの WITH CHECK OPTION 検証は実行されません。
-
%NOLOCK
INSERT 時に行をロックしません。単独のユーザ/処理がデータベースを更新する際にのみ使用します。
-
%NOINDEX インデックス・マップは
INSERT 処理中には設定されません。
-
%NOTRIGGER ベース・テーブル・トリガは
INSERT 処理中にはかかりません。
%NOCHECK を指定しない場合、Caché ではシステム構成設定を使用して外部キーの参照整合性チェックを実行するかどうかが決まります。システムの既定値は以下のように設定できます。
-
ObjectScript $SYSTEM.SQL.SetFilerRefIntegrity() 関数を呼び出します。
-
INSERT 操作時に、すべての外部キー参照について、参照されるテーブルの該当する行に対する共有ロックが取得されます。この行は、トランザクションの終了までロックされています。これにより、参照されている行は、
INSERT の参照整合性チェックからトランザクションの終了までの間、変更されないことが保証されます。
ストリーム・フィールドには以下のタイプのデータ値を挿入できます。
-
-
文字列リテラル。ただし、文字列リテラルはオブジェクト参照 (oref) 文字列表現の形式をとることはできません。例えば、値
2@User.MyClass は文字列リテラルではなく、文字列版の oref とみなされます。
-
一時的なストリームの文字列版 oref。この文字列の oref は、%qstrhandle(%qacn) 配列内の 1 つの配列エントリとして存在している必要があります。文字列の oref は配列の添え字でなければならず、oref の値自体がデータ内に存在している必要があります。
詳細は、以下の埋め込み SQL の例を参照してください。
SET oref=##class(User.MyStream).%OpenId(1)
SET %qstrhandle(1,oref)=oref
SET InputValue=oref_""
&sql(INSERT INTO MyStreamTable (MyStreamField)
VALUES (:InputValue))
%qstrhandle の最初の添え字の値は、ローカル変数 %qacn です。上記のケースでは、%qacn は未定義で、既定で 1 となります。そのため、%qstrhandle 配列は以下のようにも設定できます。
SET oref=##class(User.MyStream).%OpenId(1)
SET %qacn=2
SET %qstrhandle(%qacn,oref)=oref
SELECT 文との組み合わせにより、1 つの
INSERT を使用して複数の行をテーブルに挿入することができます。
SELECT が 1 つのテーブルの複数の行から列データを抽出し、
INSERT がこの列データを格納した新しい対応する行を別のテーブル内に作成します。
以下の例では、2 つの埋め込み SQL プログラムを使用して
INSERT のこの使用方法を示します。最初の例で新しいテーブル Sample.Students を作成し、2 番目の例でこのテーブルに Sample.Person から抽出したデータを追加します。
この動作をはっきり示すために、2 つの埋め込み SQL プログラムは示されている順序で実行してください (埋め込み SQL では参照されるテーブルがすでに存在していなければ
INSERT 文をコンパイルすることができないため、ここでは 2 つの埋め込み SQL プログラムを使用する必要があります)。
WRITE !,"starting up"
&sql(CREATE TABLE Sample.Students (
StudentName VARCHAR(16),
StudentAge INTEGER))
IF SQLCODE=0 {
WRITE !,"Created table, SQLCODE=",SQLCODE }
ELSEIF SQLCODE=-201 {
WRITE !,"Table already exists, SQLCODE=",SQLCODE }
WRITE !,"inserting data"
&sql(INSERT INTO Sample.Students (StudentName,StudentAge)
SELECT Name,Age
FROM Sample.Person WHERE Age <= '21')
IF SQLCODE=0 {
WRITE !,"Inserted record, SQLCODE=",SQLCODE }
ELSE {
WRITE !,"Insert failed, SQLCODE=",SQLCODE }
データを表示するには、システム管理ポータルで SAMPLES ネームスペースの [グローバル] オプションを選択します。"Sample.StudentD" までスクロールし、[データ] オプションをクリックします。
INSERT クエリ結果の操作はアトミック処理です。指定された行がすべてテーブルに挿入されるか、1 行も挿入されないかのいずれかです。例えば、指定された行のいずれかの挿入が外部キーの参照整合性に違反する場合、
INSERT は失敗し、1 行も挿入されません。
%NOLOCK を指定しない場合、Caché は、
INSERT、
UPDATE、および
DELETE 操作時に標準のロックを実行します。一意フィールドの値は、現行のトランザクションの間、ロックされます。
既定のロックしきい値は、テーブルごとに 1000 ロックです。つまり、トランザクション時に 1000 行を超える行 (一意フィールド値) をテーブルに挿入する場合は、ロックしきい値に到達し、Caché はロック・レベルを自動的に一意フィールド値ロックからテーブル・ロックへと上げます。これによってトランザクション時に、ロック・テーブルをオーバーフローすることなく、大規模な挿入を実行できます。このロックしきい値は設定可能です。トランザクションでのロックの詳細は、このドキュメントの "SQL の概念" の "
トランザクション" を参照してください。
以下の埋め込み SQL の例は、Name、DOB、SSN の 3 つのフィールド値を持つ行を挿入します。
&sql(INSERT INTO Sample.Person (Name,DOB,SSN) VALUES
('David Vanderbilt', 46639,'123-45-6789'))
WRITE !,"Error code=",SQLCODE,!,"Row count=",%ROWCOUNT
ホスト変数構文では、
INSERT に値の配列を渡すために、最後の添え字が未定義の変数参照を使用できます。以下はその例です。
&sql(INSERT INTO Sample.Employee VALUES :emp("profile",))
WRITE !,"SQL Error code: ",SQLCODE," Row Count: ",%ROWCOUNT
これは、挿入された "Employee" 行の各フィールドを以下のように設定します。
ここでの "col" は、Sample.Employee テーブル内のフィールド列番号です。
以下の例は、
SELECT クエリの結果によって複数行のデータを指定し、これを
INSERT 文への入力データとして使用する方法を示しています。
INSERT INTO StudentRoster (NAME,GPA,ID_NUM)
SELECT FullName,GradeAvg,ID
FROM temp WHERE SchoolYear = '2004'