4.38.1 UPDATE文 形式3,形式4の形式と規則
- 〈この項の構成〉
(1) 機能
配列形式の埋込み変数を指定して,複数の更新処理を実行できます。
- 形式3
-
表内の,指定した探索条件を満足する行の値を列単位で複数回更新します。
- 形式4
-
FIX指定の表内の,指定した探索条件を満足する行の値を行単位で複数回更新します。
(2) 使用権限
表に対するUPDATE権限を持つユーザが,その表の列の値を更新できます。
ただし,探索条件中に副問合せを指定する場合は,その副問合せ指定の表に対してSELECT権限が必要です。
(3) 形式3 <埋込み変数配列を指定して,列単位で表内の行を複数回更新>
FOR :埋込み変数 UPDATE 〔認可識別子.〕表識別子 〔IN (RDエリア名指定)〕 〔〔AS〕 相関名〕 〔使用インデクスのSQL最適化指定〕 SET {更新対象=更新値 |(更新対象,更新対象〔,更新対象〕)=行副問合せ} 〔,{更新対象=更新値 |(更新対象,更新対象〔,更新対象〕…)=行副問合せ}〕… 〔WHERE 探索条件〕 〔WITH ROLLBACK〕 〔WRITE IMMEDIATE〕 更新対象::={列名|コンポネント指定|列名[{添字|*}]}
(4) 形式4 <埋込み変数配列を指定して,FIX指定の表内の行を行単位で複数回更新>
FOR :埋込み変数 UPDATE 〔認可識別子.〕表識別子 〔IN (RDエリア名指定)〕 〔〔AS〕 相関名〕 〔使用インデクスのSQL最適化指定〕 SET ROW=行更新値 〔WHERE 探索条件〕 〔WITH ROLLBACK〕 〔WRITE IMMEDIATE〕
(5) オペランド
FOR,IN(RDエリア名指定),SET句,探索条件以外のオペランド,及びオペランド規則については,「UPDATE文 形式1(データ更新)」及び「UPDATE文 形式2(データ更新)」を参照してください。
(a) 形式3のオペランド及びオペランド規則
- SET句
-
列の値を更新します。
- 更新値
-
更新値の列の値として,次に示す項目が指定できます。
-
:埋込み変数配列〔:標識変数配列〕
-
列名
-
定数
-
値式(四則演算,連結演算を含みます)
-
スカラ副問合せ
-
USER値関数
-
CURRENT_DATE値関数
-
CURRENT_TIME値関数
-
CURRENT_TIMESTAMP値関数
-
NULL(ナル値を表します)
-
DEFAULT(更新対象の列の既定値を表します)
-
?パラメタ
ただし,更新値には配列形式でない埋込み変数は指定できません。
-
(b) 形式4のオペランド及びオペランド規則
ROWを指定する場合の規則を次に示します。
-
行単位の更新は,FIX属性の実表に対してだけ使用できます。ROWは行全体(予備列を含む)を意味し,これを指定すると行全体を一つのデータとして,一つの領域のデータで更新します。更新するデータのデータ型は,各列のデータ型に関係なく,ROW型になります。ROW型に対しては,CHAR(n)〔nは行長〕に対する変数,又は同じ長さの構造体を指定できます。ただし,構造体中に境界調整による空きがあってはいけません。また,データ長は,行長(各列のデータ長の総和)になります。
-
UAPが動作するプラットフォームとHiRDBサーバが動作するプラットフォームのエンディアンを同じにしてください。異なるエンディアン間では,ROWは使用できません。例えば,WindowsのUAPでROWを使用する場合は,HiRDBサーバも同じエンディアンのWindows版を使用してください。
(c) 形式3及び形式4に共通するオペランド及びオペランド規則
- FOR :埋込み変数
-
埋込み変数配列を使用して更新を行う回数を設定した埋込み変数を指定します。SMALLINT型の埋込み変数を指定してください。設定値は1から4,096までの範囲で,かつ埋込み変数配列,及び標識変数配列の要素数以下にしてください。0及び負の値は設定できません。範囲外の値を設定した場合は実行時にエラーとなります。
- 埋込み変数配列
-
配列形式で宣言した埋込み変数です。NULL値以外の更新値を指定するための配列変数を指定します。それぞれの行を更新する値を埋込み変数配列の各要素に設定してください。更新する値にNULL値を含む場合は,埋込み変数配列と標識変数配列を両方指定します。
- 標識変数配列
-
配列形式で宣言した標識変数です。埋込み変数配列の各要素を更新する値が,NULL値かどうかを示す値を,標識変数配列の対応する要素に設定してください。設定する値については,「標識変数の値の設定」を参照してください。
- 〔IN (RDエリア名指定)〕
-
RDエリア名指定を埋込み変数で行う場合は,埋込み変数配列にしてください。配列でない埋込み変数を指定した場合はエラーとなります。そのほかのオペランド規則については,形式1を参照してください。
- 〔 WHERE探索条件 〕
-
省略すると,指定した表のすべての行が更新されます。
- 探索条件
-
更新の対象となる行を選択する条件を指定します。この探索条件を満足するすべての行を更新します。探索条件に埋込み変数を使用する場合,配列形式でない埋込み変数は指定できません。
(6) 共通規則
(a) 形式3の規則
-
埋込み変数配列のデータ型は対応する列のデータ型,又は変換できるデータ型にしてください。
-
配列を使用したUPDATEでは,BLOB型,最大長が32,001バイト以上のBINARY型及び抽象データ型は扱えません。
-
配列を使用したUPDATEでは,繰返し列の複数要素の更新はできません。
-
INTEGER,又はSMALLINTのデータ型の列を,固定小数点,又は浮動小数点数のデータで更新する場合は,端数(小数)部分は更新前に切り捨てられます。また,DECIMALデータ型の列を固定小数点のデータで更新する場合には,列の位取りから下位のけたの部分が更新前に切り捨てられます。
-
更新する列の値として,表の定義時に指定した長さ以上の文字データ又はBINARYデータは入力できません。
-
更新する列の値として,定義域の範囲外の数データは入力できません。
-
固定長文字列(各国文字列,混在文字列を含む)の列を更新するデータが列の長さより短い場合は,左詰めに挿入され,余りの部分に余白が設定されます。
-
SET句は,一つのSQL文中にそれぞれ1回だけ指定できます。
-
SET句内の項目は,それぞれ最大30,000個指定できます。
-
改竄防止表に対してUPDATE文は実行できません。ただし,更新可能列は更新できます。
改竄防止表でUPDATE ONLY FROM NULL指定した列の値の更新可否を次に示します。
更新前の列の値
更新後の列の値
更新可否
ナル値
ナル値
○
ナル値
非ナル値
○
非ナル値
ナル値
×
非ナル値
非ナル値※
×
- (凡例)
-
○:更新できます。
×:更新できません。
- 注
-
繰返し列の場合は,ナル値(要素数が0の値)から添え字指定無しでの列単位更新だけ実行できます。
改竄防止表で,指定した探索条件を満たす行のうち,UPDATE ONLY FROM NULLを指定した列の値に非ナル値の行がある場合,エラーになります。
- 注※
-
更新前の値と同値を含みます。
-
更新対象列を含む表にWITHOUT ROLLBACKを指定し,かつ更新対象列にインデクスを定義している場合にエラーとなります。
-
WITHOUT ROLLBACKを指定した表のインデクス構成列を更新対象列とする場合,インデクス構成列に対する更新値が同値更新以外のときは実行できません。詳細は「CREATE TABLE(表定義)」のWITHOUT ROLLBACKの規則を参照してください。
-
更新対象表が共用表で,かつ更新対象列にインデクスを定義している場合,更新前にその共用表に対するLOCK文を排他モードで実行してください。LOCK文を実行しないで共用表のインデクスを定義した列の値を更新した場合,エラーとなります。ただし,インデクスを定義している列の値に変更がない場合はLOCK文を実行する必要はありません。共用表に対する更新については,マニュアル「HiRDB システム導入・設計ガイド」を参照してください。共用表に対してLOCK文を実行した場合の排他制御の対象については「LOCK文(表の排他制御)」の留意事項を参照してください。
-
更新対象表が次の条件をすべて満たす場合,その列をDEFAULTで更新するには更新前にその共用表に対するLOCK文を排他モードで実行してください。LOCK文を実行しないで更新した場合,エラーとなります。
-
更新対象表が共用表である
-
更新対象列が時刻印データ型である
-
表定義時に既定値としてCURRENT_TIMESTAMP USING BESを指定している
-
(b) 形式4の規則
-
WITHOUT ROLLBACKを指定し,かつインデクスを定義した表を表識別子に指定する場合,インデクス構成列に対する更新値が同値更新以外の場合は実行できません。詳細は「CREATE TABLE(表定義)」のWITHOUT ROLLBACKの規則を参照してください。
-
更新対象表が共用表で,かつどれかの列にインデクスを定義している場合,更新前にその共用表に対するLOCK文を排他モードで実行してください。LOCK文を実行しないで共用表を行単位(ROW指定)で更新した場合,エラーとなります。ただし,インデクスを定義している列の値に変更がない場合はLOCK文を実行する必要はありません。共用表に対する更新については,マニュアル「HiRDB システム導入・設計ガイド」を参照してください。共用表に対してLOCK文を実行した場合の排他制御の対象については「LOCK文(表の排他制御)」の留意事項を参照してください。
-
行単位でのUPDATE文はすべての列の値を更新するため,1列でも更新不可である改竄防止表に対して,行単位でのUPDATE文は実行できません。
-
既定文字集合以外の文字データ型の列を含む表に対しては,行単位でのUPDATE文は実行できません。
(c) 形式3及び形式4の共通規則
-
FOR句以外に埋込み変数配列を一つ以上指定してください。指定しない場合はエラーとなります。
-
FOR句以外に配列形式でない埋込み変数を指定するとエラーとなります。
-
埋込み変数配列,及び標識変数配列の要素数は1から4,096までの範囲にしてください。範囲外の値を指定した場合はエラーとなります。また,”FOR :埋込み変数”で指定する要素数の最大値以上になるようにしてください。
-
各埋込み変数配列,及び標識変数配列で1回の更新処理によって評価される要素は同じ要素番号の要素となります。
-
配列の先頭の要素から順に評価されます。
-
複数回更新を行う場合の更新対象は,前回の配列要素を使用して更新が行われた後の更新対象となります。
-
SQL連絡領域のSQLERRD[2]領域には,重複して更新された行数も含めた更新行数の総和が設定されます。
-
UPDATE文形式3は埋込み変数配列,及び標識変数配列を含むため,PREPARE文で前処理することはできません。動的に実行する場合については,「EXECUTE文 形式2(配列を使用したSQLの実行)」を参照してください。
-
配列を使用したUPDATEは手続きの中では使えません。
-
更新するどれかの行で警告する必要のある事象が発生した場合,SQL連絡領域のSQLWARNに警告情報が設定されます。
-
更新するどれかの行でエラーが発生した場合,ロールバックされます。
-
UPDATE文は改竄防止表に対して指定できません。ただし,更新可能列を定義している場合は形式3及び形式4の規則に従ってください。
-
RDエリア名指定を指定した場合,分割数が表の分割数と異なるインデクスは利用できません。RDエリア名指定を指定した問合せのためにインデクスを定義する場合は,分割数が表の分割数と等しいインデクスを定義してください。
(7) 参照制約に関する規則
-
被参照表の主キーの更新,参照表の外部キーの更新をする場合,又は被参照表,参照表に対して行単位で更新する場合の規則については,「CREATE TABLE(表定義)」の参照動作の説明を参照してください。
-
制約動作がRESTRICTで定義された被参照表の主キー構成列の値を更新する場合,その更新値が参照表の外部キー構成列の値に含まれるかどうかを確認するため,参照表を検索します。このとき,参照表の検索時のデータ保証レベルは共用モードになります。そのため,制約動作がRESTRICTで定義された被参照表の行を削除するときに,ほかのトランザクションによって参照表に対する操作が行われていると,そのトランザクションが決着するまでその行削除は待ち状態になります。
-
次の条件が重なった場合,参照制約での被参照表と参照表間でデータの不整合が発生することがあります。また,制約動作がRESIRICT又はCASCADEのどちらかの場合でも発生することがあります。
-
参照表の行を削除するトランザクションと,被参照表の行を更新,又は削除するトランザクションが異なる
-
上記二つのトランザクションが同時に実行される
-
参照表で削除する行の主キー構成列の値と,被参照表で更新,又は削除する行の外部キー構成列の値と同じである
-
参照表の行を削除するトランザクションをコミット,被参照表の行を更新,又は削除するトランザクションをロールバックする
-
-
次の条件が重なった場合,被参照表を操作するトランザクションと参照表を操作するトランザクション間でデッドロックが発生することがあります。また,制約動作がRESIRICT,CASCADEのどれかの場合でも発生することがあります。
-
参照表の行を更新するトランザクションと,被参照表の行を更新するトランザクションが異なる
-
上記二つのトランザクションが同時に実行される
-
参照表で更新する行の外部キー構成列の値と,被参照表で削除する行の主キー構成列が同じである
-
(8) 使用例
-
UPDATE文形式1を使用して,C言語の配列変数に設定した商品コード(SCODE)及び在庫量(ZSURYO)の値別に,在庫量(ZSURYO)を次の表で示す値に更新します。
表4‒8 表に格納された商品コードと在庫量(更新前) 商品コード
在庫量の更新値
‘101M’
40
‘101L’
70
‘201M’
15
‘202M’
28
‘302S’
7
表4‒9 更新対象となる行の商品コードと在庫量(埋込み変数配列に設定) 商品コード
在庫量の更新値
‘101M’
35
‘101L’
62
‘201M’
13
‘202M’
10
‘302S’
6
表4‒10 表に格納された商品コードと在庫量(更新後) 商品コード
在庫量の更新値
‘101M’
35
‘101L’
62
‘201M’
13
‘202M’
10
‘302S’
6
EXEC SQL BEGIN DECLARE SECTION; short XUPDATE_NUM; char XSCODE[5][5]; short ISCODE[5]; long XZSURYO[5]; short IZSURYO[5]; EXEC SQL END DECLARE SECTION; ・・・各変数配列の要素に値設定・・・ XSCODEに{’101M’,’101L’,’201M’,’202M’,’302S’}を設定 XZSURYOに{35,62,13,10,6}を設定 XUPDATE_NUM = 5; EXEC SQL FOR :XUPDATE_NUM UPDATE ZAIKO SET ZSURYO = :XZSURYO:IZSURYO WHERE SCODE = :XSCODE:ISCODE;
-
UPDATE文形式2を使用して,C言語の配列変数に設定した商品コード(SCODE)の値別に,在庫表(ZAIKO)の行全体を,埋込み変数配列(XROW)の内容でまとめて更新します。
XUPDATE_NUM = 5; EXEC SQL FOR :XUPDATE_NUM UPDATE ZAIKO SET ROW = :XROW WHERE SCODE = :XSCODE:ISCODE;