前のページ|次のページ

MODIFYステートメント

既存のデータセットにあるオブザベーションの置き換え、削除、追加を実行します。ただし、オブザベーションのコピーは作成しません。

該当要素: DATAステップ
カテゴリ: ファイル操作
種類: 実行
制限事項: 変数の追加など、SASデータセットのディスクリプタ部分を変更することはできません。
注: パスワードで保護されたデータセットを変更する場合、DATAステートメントではなくMODIFYステートメントの適切なデータセットオプション(ALTER=またはPW=)にパスワードを指定します。
MODIFYステートメントを使用して読み込まれた変数はPDVで保持されます。詳細については、XisError: No pubcode in link data found for lrconおよびRETAINステートメントを参照してください。
注意:
MODIFYステートメントを含むDATAステップの実行中にシステムが異常終了すると、SASデータセットが破損する可能性があります。
ネイティブSASデータファイルのオブザベーションに誤ったデータ値が含まれたり、データファイルが読み込めなくなる場合があります。ビューで参照するDBMSテーブルには影響はありません。

構文

形式1:

形式2:

形式3:

形式4:

引数

master-data-set

変更対象となるSASデータセット(マスタデータセット)を指定します。

制限事項 このデータセットは、DATAステートメントにも指定する必要があります。
順次アクセスまたはマッチングアクセスの場合、マスタデータセットには、SASデータファイル、SAS/ACCESSビュー、SQLビュー、LIBNAMEステートメントのDBMSエンジンを指定できます。DATAステップビューとSQLプロシジャのパススルー機能を使用したビューは指定できません。
POINT=オプションを指定したランダムアクセスの場合、マスタデータセットにはSASデータファイルか、SASデータファイルを参照するSQLビューを指定する必要があります。
KEY=オプションを指定したダイレクトアクセスの場合、マスタデータセットにはSASデータファイルか、LIBNAMEステートメントのDBMSエンジンを指定できます。SASファイルを指定する場合、インデックス付きである必要があり、KEY=オプションにインデックス名を指定する必要があります。
DBMSの場合、KEY=オプションにキーワードDBKEYを設定し、インデックスとして使用する列名をDBKEY=データセットオプションに指定する必要があります。指定した列名は、DBMSに渡すWHERE式の生成に使用されます。
ヒント データセット名を使用するかわりに、オペレーティングシステムでサポートされている構文を使用してファイルの物理パス名を指定することができます。物理パス名は一重引用符または二重引用符で囲む必要があります。

(data-set-options)

SASデータセット名の後ろに、1つまたは複数のSASデータセットオプションを丸かっこで囲んで指定します。

データセットオプションは、処理対象のオブザベーションをDATAステップに読み込むときに実行するアクションを指定します。データセットオプションのリストについては、次を参照してください。 SASデータセットオプション: リファレンス
ヒント データセットリストに適用するデータセットオプションは、データセットリストに存在するすべてのデータセットに適用されます。

transaction-data-set

マッチングアクセスで使用する値を含むSASデータセットを指定します。この値はマスタデータセットの更新に使用されます。

制限事項 このデータセットは、DATAステップにBYステートメントが含まれている場合にのみ指定してください。
ヒント データセット名を使用するかわりに、オペレーティングシステムでサポートされている構文を使用してファイルの物理パス名を指定することができます。物理パス名は一重引用符または二重引用符で囲む必要があります。

by-variable

オブザベーションの識別に使用する、1つまたは複数の変数名を指定します。

CUROBS=variable

データセットから読み込んだオブザベーション数を含む変数を作成および名前を付与

END=variable

作成する一時変数の名前を指定します。この変数の値には終端指示子が格納されます。

制限事項 この引数は、POINT=オプションを指定したMODIFYステートメントには使用しないでください。POINT=オプションは、MODIFYステートメントでランダムアクセスを使用することを示しています。ランダムアクセスの場合、END=オプションに指定した変数の値が1に設定されることはありません。
この変数の初期値は0です。この変数の値が1に設定されるのは、MODIFYステートメントによって、変更するデータセットの最後のオブザベーションが読み込まれた場合(順次アクセスの場合)、またはトランザクションデータセットの最後のオブザベーションが読み込まれた場合(マッチングアクセスの場合)です。また、この変数の値は、MODIFYステートメントでKEY=オプションに指定した値に一致する値が見つからなかった場合にも1に設定されます(ランダムアクセスの場合)。
この変数はどのデータセットにも追加されません。

KEY=index

変更するSASデータセットの単一インデックスまたは複合インデックスを指定します。KEY=オプションを指定すると、他のソースに含まれる同一の変数名のインデックス値に基づいて、SASデータセットからオブザベーションを取得します。

デフォルト KEY=オプションの値が見つからない場合、自動変数_ERROR_の値は1に設定されます。また、自動変数_IORC_は、SYSRC自動呼び出しマクロのニーモニック_DSENOMに対応する値を受け入れます。自動変数_IORC_とSYSRC自動呼び出しマクロを参照してください。
制限事項 KEY=オプションの処理は、SAS/ACCESS Engineによって異なります。詳細については、SAS/ACCESSのドキュメントを参照してください。
ヒント KEYRESET=オプションを使って、読み込むデータセットのインデックスの先頭からKEY=オプションに指定された値の検索を開始するかどうかをコントロールします。
インデックス値のソースの例として、SETステートメントに指定した別のSASデータセットやINPUTステートメントで読み込まれた外部ファイルなどがあります。
マスタデータセットにインデックス値の重複がある場合、そのインデックス値を持つ最初のオブザベーションしか更新されません。これを回避するには、DO ループ処理を使用して、KEY=オプションに指定したデータセットのSETステートメントがマスタデータセットの重複インデックス値に対して繰り返し実行されるようにします。
トランザクションデータセットの重複インデックス値が連続している場合、UNIQUEオプションを指定して、マスタデータセットでのインデックス値の検索が、常にインデックスの先頭から実行されるようにします。さらに、合計ステートメントを使用して、トランザクションデータセットの重複インデックス値のオブザベーションがマスタデータセットのオブザベーションに追加されるようにする必要もあります。UNIQUEオプションを指定しない場合、重複インデックス値のうち、最初に検出されたトランザクションデータセットのオブザベーションのみを使用してマスタデータセットを更新します。
トランザクションデータセットの重複インデックスが連続していない場合、検索は毎回インデックスの先頭から開始されるので、重複インデックス値がマスタデータセットにそれぞれ適用されます。合計ステートメントを作成すると、トランザクションデータセットの重複インデックス値のオブザベーションがマスタに追加されます。
参照項目 KEYRESET=variable
UNIQUE
インデックスにより検索されるオブザベーションの変更

重複するインデックス値の処理

I/Oの制御

KEYRESET=variable

読み込むデータセットのインデックスの先頭からKEY=オプションに指定された値の検索を開始するかどうかをコントロールします。KEYRESET変数の値が1の場合、インデックスの一番上から検索します。KEYRESET変数の値が0の場合、インデックスの検索はリセットされないので、最後の検索のつづきから検索します。

操作 KEYRESET=オプションはUNIQUEオプションに似ていますが、KEYRESET=オプションではKEY=検索をインデックスの最初からにするかどうかを決められます。
参照項目 KEY=index
UNIQUE

NOBS=variable

作成する一時変数の名前を指定します。この一時変数の値は、入力データセットに含まれるオブザベーションの合計数になります。特定のSASビューとTAPEやXMLエンジンのような順次エンジンに対しては、SASがオブザベーション数を検知することができません。この場合、NOBS=オプションに指定した変数の値には、動作環境で使用できる最大の正の整数値が設定されます。

コンパイル時に、データセットのディスクリプタ情報を読み込んでから、NOBS=オプションの変数の値を自動的に割り当てます。そのため、MODIFYステートメントの実行前にもNOBS=オプションの変数を参照できます。この変数はDATAステップで使用できますが、新しいデータセットには追加されません。
ヒント NOBS=オプションとPOINT=オプションは互いに独立しています。
オブザベーション番号により検索されるオブザベーションの変更

POINT=variable

オブザベーション番号をもとにランダム(ダイレクト)アクセスを使用してSASデータセットを読み込みます。variableには、読み込むオブザベーションの番号を格納する変数の名前を指定します。POINT=オプションに指定した変数はDATAステップのどの位置にでも指定できますが、SASデータセットには追加されません。

制限事項 POINT=オプションは次のものとは併用できません。
  • BYステートメント
  • WHEREステートメント
  • WHERE=データセットオプション
  • 移送形式のデータセット
  • テープまたはディスクに記録された順次データセット
  • 他社製のリレーショナルデータベース管理システムにあるテーブル
圧縮データセットでPOINT=オプションを使用できるのは、POINTOBS=データセットオプションをYES(デフォルト値)に設定してこのデータセットを作成した場合のみです。
SASバージョン7以降を使用している場合のみ、圧縮ファイルにランダムアクセス方式を使用できます。
要件 POINT=オプションを使用する場合、次のプログラミング要素のどちらかまたは両方を使用してください。
  • STOPステートメント
  • POINT=オプションに指定した変数の値が無効かどうかを確認するプログラミングロジック
POINT=オプションでは指定したオブザベーションのみを読み込むため、順次アクセスでファイルを読み込む場合とは違い、ファイル終端条件を読み取ることができません。ファイル終端条件を検出するとDATAステップを自動的に終了させるため、POINT=オプションの使用時にDATAステップを終了させる別の方法を準備しないと、DATAステップで無限ループが発生する場合があります。
ヒント POINT=オプションに指定した変数の値がオブザベーションの番号と一致しない場合、自動変数_ERROR_の値が1に設定されます。
オブザベーション番号により検索されるオブザベーションの変更

UNIQUE

変更するデータファイルの先頭からKEY=オプションに指定した値の検索を開始します。

制限事項 UNIQUEオプションは、KEY=オプションを指定する場合にのみ使用できます。
ヒント UNIQUEオプションは、トランザクションデータセットの中にKEY=オプションに指定したインデックス値の重複が連続して存在する場合に使用します。このオプションを使用すると、トランザクションデータセットにある重複した値ごとに、マスタデータセットでの一致する値の検索をインデックスファイルの先頭から開始します。この場合、合計ステートメントを使用する必要があります。合計ステートメントを使用しないと、重複した値による上書きが発生するため、最後のトランザクションの値のみがマスタオブザベーションに反映されます。
参照項目 KEYRESET=variable
重複するインデックス値の処理

UPDATEMODE=MISSINGCHECK | NOMISSINGCHECK

トランザクションデータセットにある変数の欠損値を使用して、マスタデータセットにある既存の変数の値を置き換えるかどうかを指定します。

MISSINGCHECK

トランザクションデータセットにある変数の欠損値を使用して、マスタデータセットにある変数の値を置き換えないように指示します。

NOMISSINGCHECK

欠損値があるかどうかのチェックを実行しません。トランザクションデータセットにある変数の欠損値を使用して、マスタデータセットにある変数の値を置き換えられるようにします。

デフォルト MISSINGCHECK
要件 オブザベーションの一致を検出する基準を指示するBYステートメントに、UPDATEMODEオプションを指定する必要があります。
ヒント ただし、特殊欠損値は例外です。この場合、MISSINGCHECKが有効な場合でも、マスタデータセットの値は特殊欠損値で置き換えられます。

詳細

マッチングアクセス(形式1)

マッチングアクセス法では、BYステートメントを使用して、トランザクションデータセットのオブザベーションとマスタデータセットのオブザベーションを突き合わせて対応させます。BYステートメントには、トランザクションデータセットとマスタデータセットの両方に含まれる変数を指定します。
MODIFYステートメントでトランザクションデータセットからオブザベーションを読み込むと、動的WHERE処理を実行し、マスタデータセットの中で対応するオブザベーションを探します。マスタデータセットのオブザベーションには、次のいずれかの処理が実行されます。
  • マスタデータセットの値をトランザクションデータセットの値で置き替える
  • マスタデータセットから削除する
  • マスタデータセットに追加する
トランザクションデータセットを使用したオブザベーションの変更 には、マッチングアクセス方式の使用例が紹介されています。

BY値の重複(形式1)

マスタデータセットに重複が存在する場合でも、トランザクションデータセットに重複が存在する場合でも、処理に影響します。
  • マスタデータセットに重複が存在する場合、重複する値のうち、最初に検出された値のみが更新されます。これは、生成されるWHEREステートメントではマスタデータセット内で常に条件に一致する最初の値を探すためです。
  • トランザクションデータセットに重複が存在する場合、重複した値は上書きされます。これを回避するには、合計ステートメントを作成して重複する値をすべてマスタデータセットに追加する必要があります。合計ステートメントを使用しないと、重複している値は上書きされるので、最後のオブザベーションの値だけがマスタデータセットのオブザベーションに反映されます。

インデックス付きの値によるダイレクトアクセス(形式2)

この方法では、MODIFYステートメントにKEY=オプションを指定する必要があります。KEY=オプションには、変更するデータセットに含まれるインデックス付きの変数の名前を指定する必要があります。もう1つのデータソース(通常、SETステートメントに指定したSASデータセットか、INPUTステートメントで読み込んだ外部ファイル)から、インデックス付きの変数に値を提供する同じ名前の変数を得ます。MODIFYステートメントは、インデックス値を使用して変更対象のデータセットに格納されているオブザベーションを検出します。
インデックスにより検索されるオブザベーションの変更 では、インデックス付きの値を使用したダイレクトアクセス方式の例を紹介しています。

インデックス値の重複(形式2)

  • マスタデータセットにインデックス付きの変数の値が重複して存在する場合、最初に検出された値のみを対象にして取得、変更、置き換えを実行します。DOループ処理を使用してKEY=オプションを指定したSETステートメントを繰り返し実行すると、重複するすべての値がトランザクションの値で更新されます。
  • データソースの同一名の変数に重複した値が連続せずに存在する場合、MODIFYステートメントは、データソースのインデックス値に一致する値が最初に検出されたマスタデータセットのオブザベーションに対して、重複するトランザクションを繰り返し適用します。そのため、重複するトランザクションの最後の値のみがマスタオブザベーションに反映されます。これを回避するには、合計ステートメントを作成し、重複するトランザクションのそれぞれの値をマスタオブザベーションに追加する必要があります。
  • データソースの同一名の変数に重複した値が連続して存在する場合、データソースの中で最初に検出されたオブザベーションの値がマスタデータセットに適用されます。ただし、重複する値のうち、データソースの中で2番目に検出された値に対応するオブザベーションをマスタデータセットで探そうとすると、エラーが発生するためDATAステップが終了します。このエラーを回避するには、MODIFYステートメントにUNIQUEオプションを指定します。UNIQUEオプションを使用すると、マスタデータセットの先頭に戻ってから一致するインデックス値を取得します。この場合、合計ステートメントを記述して、重複する値をすべて合計する必要があります。合計ステートメント記述しない場合、最後に検出された値のみがマスタオブザベーションに反映されます。
    重複するインデックス値の処理 では、重複するインデックス値を扱う例を紹介しています。
  • 両方のデータセットに重複するインデックス値が存在する場合、SQLを使用すると、トランザクションデータセットの重複した値をマスタデータセットの重複した値と1対1で対応させることができます。

オブザベーション番号によるダイレクトアクセス(ランダムアクセス) (形式3)

MODIFYステートメントにPOINT=オプションを使用すると、もう1つのデータソース(マスタデータセットを除く)の変数名を指定することができます。この変数の値がマスタデータセットで変更するオブザベーションの番号になります。MODIFYステートメントはPOINT=オプションに指定した変数の値を使用して、データセットに格納されている変更対象のオブザベーションを取得します。(圧縮データセットにPOINT=オプションを使用できるのは、データセットがPOINTOBS=データセットオプションを指定して作成された場合に限られます。)
プログラミング時には、POINT=オプションの変数の値を検証すること、また、自動変数_ERROR_の値のステータスを確認することをお勧めします。
オブザベーション番号により検索されるオブザベーションの変更 では、オブザベーション番号によるダイレクトアクセス(ランダムアクセス)方式について説明しています。
注意:
POINT=オプションを指定すると、無限ループが発生する可能性あります。
POINT=オプションを使用する場合は、DATAステップを正常に停止できないと、DATAステップで無限ループが発生する可能性があるので注意してください。STOPステートメントを使用するか、POINT=オプションに指定した変数の値が無効かどうかを確認するプログラミングロジックを使用するか、またはこの両方を使用してください。

順次アクセス(形式4)

順次アクセス方式は、MODIFYステートメントで最も簡単な形式ですが、ダイレクトアクセス方式に比べると制御できる要素は少なくなります。順次アクセス方式を使用する場合、NOBS=オプションおよびEND=オプションを使用してデータセットを変更できます。ただし、POINT=オプションまたはKEY=オプションは使用しません。

MODIFYステートメントを使用する前にデータセットを準備する

MODIFYステートメントの使用時にパフォーマンスを改善したり、必要な結果を取得するために準備できることがいくつかあります。詳細については、XisError: No pubcode in link data found for lrconを参照してください。

自動変数_IORC_とSYSRC自動呼び出しマクロ

自動変数_IORC_には、MODIFYステートメントでI/O操作を実行するたびにリターンコードが格納されます。自動変数_IORC_の値を検証するもっとも簡単な方法は、SYSRC自動呼び出しマクロで提供されるニーモニックコードを使用することです。それぞれのニーモニックコードには、特定の条件が記述されています。そのため、ニーモニックを使用すると、DATAステッププログラムで発生した問題を簡単に検証するできるようになります。次のコードを使用すると便利です。
_DSENMR
トランザクションデータセットのオブザベーションがマスタデータセット上に存在しないことを示します(MODIFYステートメントとBYステートメントを併用した場合にのみ使用)。異なるBY値を持つ連続するオブザベーションがマスタデータセットに存在しない場合、どちらのオブザベーションにも_DSENMRが返されます。
_DSEMTR
指定したBY値を持つ複数のトランザクションデータセットのオブザベーションがマスタデータセット上に存在しないことを示します(MODIFYステートメントとBYステートメントを併用した場合にのみ使用)。同じBY値を持つ連続したオブザベーションがマスタデータセットに存在しない場合、最初のオブザベーションに対しては_DSENMR、後続のオブザベーションに対しては_DSEMTRが返されます。
_DSENOM
変更対象のデータセットにKEY=オプションまたはPOINT=オプションで要求したオブザベーションが含まれていないことを示します。
_SENOCHN
オブザベーションに対してOUTPUTステートメントまたはREPLACEステートメントを実行しようとしていますが、このオブザベーションに含まれているキー値と同じ値が、一意のキー値が必要な既存のインデックス付きデータセットに存在することを示しています。
_SOK
オブザベーションが検出されたことを示しています。
注: IORCMSG関数は、自動変数_IORC_の現在の値に関連するエラーメッセージを指定された形式で返します。
I/Oの制御 では、自動変数_IORC_およびSYSRC自動呼び出しマクロの使用方法について説明しています。

DATAステップでMODIFYが使用される場合のオブザベーションの書き込み

DATAステップにMODIFYステートメントが含まれている場合にオブザベーションをSASデータセットに書き出す方法は、他にどのステートメントが使用されているかによって異なります。次の場合が考えられます。
明示的なステートメントが存在しない場合
現在のオブザベーションをSASデータセットの元の位置に書き込みます。このアクションは、DATAステップの最後のアクションとして実行されます(REPLACEステートメントがDATAステップの最後のステートメントとして記述されているのと同じように処理)。
OUTPUTステートメント
OUTPUTステートメントにデータセットが指定されていない場合、DATAステップに指定したすべてのデータセットの最後に現在のオブザベーションを書き込みます。データセットが指定されている場合、このステートメントは指定されたデータセットの最後に現在のオブザベーションを書き込みます。このアクションは、DATAステップでOUTPUTステートメントが検出された時点で実行されます。
REPLACE <data-set-name>ステートメント
指定された1つまたは複数のデータセットに現在のオブザベーションを再度書き込みます。また、引数を指定しない場合は、DATAステートメントに指定されている各データセットに現在のオブザベーションを再度書き込みます。このアクションは、REPLACEステートメントが検出された時点で実行されます。
REMOVE <data-set-name>ステートメント
指定された1つまたは複数のデータセットから現在のオブザベーションを削除します。また、引数を指定しない場合は、DATAステートメントに指定されている各データセットから現在のオブザベーションを削除します。データセットを管理しているエンジンの特性に応じて、削除が物理的に実行される場合も、論理的に実行される場合もあります。
これらのステートメントを使用する場合は、次に注意してください。
  • OUTPUTステートメント、REPLACEステートメント、REMOVEステートメントがどれも指定されていない場合、デフォルトのアクションはREPLACEステートメントになります。
  • OUTPUT、REPLACE、REMOVEの各ステートメントは互いに独立して動作します。1つのオブザベーションに適用するOUTPUT、REPLACE、REMOVEの各ステートメントを複数記述することができます。ただし、いったんOUTPUT、REPLACE、REMOVEのいずれかのステートメントを実行した場合は、次のREPLACEステートメントまたはREMOVEステートメントを実行する前に、MODIFYステートメントを再度実行する必要があります。
    次の例の条件ロジックに示すように、OUTPUTステートメントおよびREPLACEステートメントを使用できます。これは、オブザベーションごとにREPLACEステートメントまたはOUTPUTステートメントのどちらか1つのみが実行されるためです。
    data master;
       modify master trans; by key;
       if _iorc_=0 then replace;
       else
          output;
    run;
    ただし、この例に示すように、同じオブザベーションに対して複数のREPLACE操作を実行しないでください。
    data master;
       modify master;
       x=1;
       replace;
       replace;
    run;
    オブザベーションごとに複数のOUTPUTステートメントを記述できます。ただし、複数のOUTPUTステートメントを使用する場合は注意が必要です。OUTPUTステートメントを1つだけ使用する場合でも、無限ループが発生する可能性があります。
    data master;
       modify master;
       output;
    run;
  • DATAステップでOUTPUT、REPLACE、REMOVEのいずれかのステートメントを使用すると、オブザベーションのデフォルトの置き換えより優先されます。DATAステップでこれらのステートメントのいずれかを使用する場合は、実行するアクションを明示的に記述する必要があります。
  • OUTPUTステートメントとREPLACEステートメントの両方、またはREMOVEステートメントを指定したオブザベーションに対して実行する場合、オブザベーションポインタの位置を正しく保つためにOUTPUT操作を最後に実行する必要があります。
オブザベーションの置換と削除、オブザベーションの他のSASデータセットへの書き込み では、OUTPUT、REMOVE、REPLACEの各ステートメントを使用してオブザベーションを書き込む方法について説明しています。

欠損値とMODIFYステートメント

デフォルトでは、UPDATEMODE=MISSINGCHECKオプションが有効です。そのため、トランザクションデータセットの欠損値によって、マスタデータセットの既存の値が置き換えられることはありません。そのため、すべての変数ではなく一部の変数のみを更新する場合、またオブザベーションごとに更新する変数が異なる場合は、変更しない変数を欠損値に設定します。トランザクションデータに含まれる欠損値でマスタデータセットに含まれる既存の値を置き換える場合は、UPDATEMODE=NOMISSINGCHECKを使用します。
UPDATEMODE=MISSINGCHECKが有効な場合でも、トランザクションデータセットで特殊欠損値の文字を使用すると、既存の値を欠損値に置き換えることができます。特殊欠損値を含むトランザクションデータセットを作成するには、DATAステップでMISSINGステートメントを使用します。トランザクションデータセットにAからZまでの特殊欠損値の1つを定義すると、マスタデータセットに含まれる数値変数はその値に更新されます。
マスタデータセットの値を通常の欠損値に設定する場合は、トランザクションデータセット内でアンダースコア(_)を1つ使用して欠損値を示します。このように指定すると、マスタデータセットの値は、数値の欠損値がピリオド(.)に設定され、文字の欠損値はブランクに設定されます。
特殊欠損値文字の定義方法および使用方法の詳細については、 MISSINGステートメントを参照してください。

データセットオプションを用いたMODIFYの使用

プログラムでデータセットオプション(KEEP=オプションなど)を使用する場合は、MODIFYステートメントでマスタデータセットに対してこれらのオプションを指定します。DATAステートメントでデータセットオプションを使用すると、予期しない結果が生じることがあります。

SAS/SHARE環境でMODIFYを使用する

SAS/SHARE環境では、MODIFYステートメントは更新モードでオブザベーションにアクセスします。つまり、MODIFYステートメントでオブザベーションを読み込んだときから、REPLACEステートメントまたはREMOVEステートメントを実行するまでオブザベーションはロックされます。実行した時点でオブザベーションのロックは解除されます。MODIFYステートメントで再度読み込むまで、オブザベーションにアクセスすることはできません。MODIFYステートメントは更新モードでデータセットを開きますが、制御レベルは使用するステートメントによって異なります。たとえば、KEY=オプションとPOINT=オプションはメンバレベルのロックを実行します。詳細については、SAS/SHARE User's Guideを参照してください。

比較

  • DATAステップでMERGE、SET、UPDATEのいずれかのステートメントを使用すると、新しいSASデータセットが作成されます。新しいデータセットのデータセットディスクリプタは、元のデータセットのディスクリプタとは異なります(変数の追加、削除、ラベルの変更などによる)。ただし、DATAステップでMODIFYステートメントを使用する場合は、新しいデータセットは作成されません。そのため、データセットディスクリプタが変更されることはありません。
    DBMSの置き換えルールの詳細については、SAS/ACCESSのマニュアルを参照してください。
  • MODIFYステートメントをBYステートメントと併用する場合、MODIFYステートメントはUPDATEステートメントとほとんど同じように機能します。ただし、次の点が異なります。
    • マスタデータセットとトランザクションデータセットのどちらも並び替えやインデックスの作成を行う必要はありません。(BYステートメントを指定したMODIFYステートメントでは、動的WHERE処理がトリガされます。)
      注: 並べ替えまたはインデックスの作成を実行していないSASデータセットをMODIFYステートメントで変更する場合、動的WHERE処理はシステムに負担をかけることがあります。マスタデータセットで並べ替えまたはインデックスの作成を実行しておくと、特にサイズが大きいファイルの場合には処理時間を削減できます。
    • 重複したBY変数の値を持つオブザベーションがマスタデータセットとトランザクションデータセットの両方に存在する場合があります。MODIFYステートメントでの重複する値の処理方法については、 BY値の重複(形式1)を参照してください。
    • MODIFYステートメントでは、UPDATEステートメントと同じように、データセットのディスクリプタ情報を変更することはできません。そのため、このステートメントでは、変数の追加や削除、変数ラベルの変更などは実行できません。

例1: 例で使用する入力データセットの説明

例では、INVTY.STOCKデータセットを変更します。INVTY.STOCKデータセットには、次の変数が含まれています。
PARTNO
文字変数です。個々のツール番号を識別する一意の値が格納されます。
DESC
文字変数です。各ツールのテキストでの説明が格納されます。
INSTOCK
数値変数です。社内で保有している各ツールの在庫数が格納されます。
RECDATE
数値変数です。どの変数INSTOCKの値が現在のものかを示すSAS日付の値が格納されます。
PRICE
数値変数です。各ツールの単価が格納されます。
さらに、データセットINVTY.STOCKには、変数PARTNOの値をキーとする単一インデックスが格納されています。次のDATAステップを実行すると、データセットINVTY.STOCKが作成されます。
libname invty 'SAS-library';
data invty.stock(index=(partno));
   input PARTNO $ DESC $ INSTOCK @17 
         RECDATE date7. @25 PRICE;
   format  recdate date7.;
   datalines;
K89R seal   34  27jul95 245.00
M4J7 sander 98  20jun95 45.88
LK43 filter 121 19may96 10.99
MN21 brace 43   10aug96 27.87
BC85 clamp 80   16aug96 9.55
NCF3 valve 198  20mar96 24.50
KJ66 cutter 6   18jun96 19.77
UYN7 rod  211   09sep96 11.55
JD03 switch 383 09jan97 13.99
BV1E timer 26   03jan97 34.50
;

例2: すべてのオブザベーションの変更

この例では、データセットINVTY.STOCKのすべてのレコードにある日付を現在の日付で置き換えます。また、データセットINVTY.STOCKに格納されているすべてのオブザベーションに対して、変数RECDATEの値を現在の日付に置き換えます。
data invty.stock;
   modify invty.stock;
   recdate=today();
run;
proc print data=invty.stock noobs;
   title 'INVTY.STOCK';
run;
RECDATEフィールドの更新結果
RECDATEフィールドの更新結果
MODIFYステートメントは、更新処理を行うためにデータセットINVTY.STOCKを開きます。DATAステップの1回の繰り返しで、データセットINVTY.STOCKのオブザベーションを1つ読み込みます。また、コードに記述された処理を実行します。この場合、DATAステップを繰り返すたびに、変数RECDATEの値をTODAY関数の結果で置き換えます。DATAステップの最後に暗示的なREPLACEステートメントを指定すると、各オブザベーションがデータセットINVTY.STOCKの元の位置に書き込まれます。

例3: トランザクションデータセットを使用したオブザベーションの変更

この例では、新しく受け取った在庫数をデータセットINVTY.STOCKに追加し、在庫を受け取った日付を更新します。WORKライブラリにあるトランザクションデータセットADDINVには新しいデータが含まれています。
ADDINVデータセットは、更新された情報を格納するデータセットです。また、ADDINVデータセットには、次の変数が格納されています。
PARTNO
文字変数です。データセットINVTY.STOCKのインデックス付き変数PARTNOに対応しています。
NWSTOCK
数値変数です。新しく受け取った各ツールの在庫数を示しています。
データセットADDINVは、MODIFYステートメントに指定されている2番目のデータセットです。そのため、データセットADDINVをトランザクションデータセットとして使用し、このデータセットの各オブザベーションを順番に読み込みます。BYステートメントには共通する変数PARTNOが指定されています。そのため、MODIFYステートメントは、データセットADDINVの変数PARTNOの値に最初に一致する値を、データセットINVTY.STOCKの変数PARTNOの値から探します。一致する値が検出されたオブザベーションごとに、DATAステップによって変数RECDATEの値が本日の日付に変更されます。また、変数INSTOCKの値がこれまでの変数INSTOCKの値とADDINVに格納されている変数NWSTOCKの値の合計に置き換えられます。MODIFYステートメントでは、データセットディスクリプタが変更されるので、変数NWSTOCKはデータセットINVTY.STOCKに追加されません。そのため、DROPステートメントで変数NWSTOCKを指定する必要はありません。
この例では、データセットADDINVをトランザクションデータセットとして指定します。このデータセットにはデータセットINVTY.STOCKを変更するための情報が格納されています。共通する変数をBYステートメントに指定します。この変数の値を基にして、データセットINVTY.STOCKに格納されているオブザベーションを検索します。
このDATAステップを実行すると、データセットADDINVが作成されます。
data addinv;
   input PARTNO $ NWSTOCK;
   datalines;
K89R 55
M4J7 21
LK43 43
MN21 73
BC85 57
NCF3 90
KJ66 2
UYN7 108
JD03 55
BV1E 27
;
次のDATAステップでは、データセットADDINVの値を使用してデータセットINVTY.STOCKを更新します。
libname invty 'SAS-library';
data invty.stock;
   modify invty.stock addinv;
   by partno;
   RECDATE=today();
   INSTOCK=instock+nwstock;
   if _iorc_=0 then replace;
run;
proc print data=invty.stock noobs;
   title 'INVTY.STOCK';
run;
INSTOCKフィールドおよびRECDATEフィールドの更新結果
INSTOCKフィールドおよびRECDATEフィールドの更新結果

例4: オブザベーション番号により検索されるオブザベーションの変更

この例では、データセットNEWPを読み込みます。次に、データセットINVTY.STOCKの中で更新対象とするオブザベーション番号をTOOL_OBSの値に基づいて特定してから、更新を実行します。ここでは、変数PRICEの値を変数NEWPの値で置き換えるため、割り当てステートメントを使用して更新作業を明示的に指定しています。
データセットNEWPには、次の2つの変数が格納されています。
TOOL_OBS
ツール会社のマスタデータセットINVTY.STOCKにある各ツールのオブザベーション番号が格納されています。
NEWP
各ツールの新価格が格納されています。
次のDATAステップを実行すると、データセットNEWPが作成されます。
data newp;
   input TOOL_OBS NEWP;
   datalines;
 1 251.00
 2 49.33
 3 12.32
 4 30.00
 5 15.00
 6 25.75
 7 22.00
 8 14.00
 9 14.32
10 35.00
;
次のDATAステップを実行すると、データセットINVTY.STOCKが更新されます。
libname invty 'SAS-library';
data invty.stock;
   set newp;
   modify invty.stock point=tool_obs
          nobs=max_obs;
   if _error_=1 then
      do;
        put 'ERROR occurred for TOOL_OBS=' tool_obs /
        'during DATA step iteration' _n_ /
        'TOOL_OBS value might be out of range.';
        _error_=0;
        stop;
      end;
   PRICE=newp;
   RECDATE=today();
run;
proc print data=invty.stock noobs;
   title 'INVTY.STOCK';
run;
RECDATEフィールドおよびPRICEフィールドの更新結果
RECDATEフィールドおよびPRICEフィールドの更新結果

例5: インデックスにより検索されるオブザベーションの変更

この例では、KEY=オプションを使用して、データセットADDINVの変数PARTNOの値とデータセットINVTY.STOCKの変数PARTNOのインデックス付きの値で一致する値を探し、取得するオブザベーションを特定します。データセットADDINVの作成については、 トランザクションデータセットを使用したオブザベーションの変更を参照してください。
KEY=オプションによって、MODIFYステートメントで更新対象のオブザベーションに直接アクセスできるインデックス値が指定されます。動的WHERE処理は実行されません。この例では、マスタデータセットINVTY.STOCKの変数INSTOCKの値に、トランザクションデータセットADDINVの変数NWSTOCKの値を追加します。
libname invty 'SAS-library';
data invty.stock;
   set addinv;
   modify invty.stock key=partno;
   INSTOCK=instock+nwstock;
   RECDATE=today();
   if _iorc_=0 then replace;
run;
proc print data=invty.stock noobs;
   title 'INVTY.STOCK';
run;
インデックスを使用したINSTOCKフィールドとRECDATEフィールドの更新結果
インデックスを使用したINSTOCKフィールドとRECDATEフィールドの更新結果

例6: 重複するインデックス値の処理

この例では、SETデータセットに格納されている重複した変数の値をMODIFYステートメントで処理する方法を示します。このSETデータセットによって、マスタデータセットのインデックス値が提供されます。
データセットNEWINVは、更新された情報が格納するデータセットです。また、データセットNEWINVには、次の変数が格納されています。
PARTNO
文字変数です。データセットINVTY.STOCKのインデックス付き変数PARTNOに対応しています。データセットNEWINVでは、変数PARTNOに重複した値が存在しています。この場合、M4J7が2つ含まれています。
NWSTOCK
数値変数です。新しく受け取った各ツールの在庫数を示しています。
次のDATAステップを実行すると、データセットNEWINVが作成されます。
data newinv;
   input PARTNO $ NWSTOCK;
   datalines;
K89R 55
M4J7 21
M4J7 26
LK43 43
MN21 73
BC85 57
NCF3 90
KJ66 2
UYN7 108
JD03 55
BV1E 27
;
次を実行すると、データセットNEWINVで2番目に検出されるM4J7に一致するオブザベーションをデータセットINVTY.STOCKで探そうとしたときにエラーが発生し、DATAステップが異常終了します。
libname invty 'SAS-library';
   /* This DATA step terminates with an error! */
data invty.stock;
   set newinv;
   modify invty.stock key=partno;
   INSTOCK=instock+nwstock;
   RECDATE=today();
run;
SASログには次のメッセージが表示されます。
ERROR:No matching observation was found in MASTER data set.PARTNO=M4J7 NWSTOCK=26 DESC=sander INSTOCK=166 RECDATE=08DEC10 PRICE=45.88 _ERROR_=1 _IORC_=1230015 _N_=3 NOTE:The SAS System stopped processing this step because of errors.NOTE:There were 3 observations read from the data set WORK.DEPT010.NOTE:The data set INVTY.STOCK has been updated.There were 2 observations rewritten, 0 observations added and 0 observations deleted.
MODIFYステートメントにUNIQUEオプションを追加すると、前述のDATAステップで発生したエラーを回避することができます。UNIQUEオプションを追加すると、SETデータセットで一致する値を検索するたびに、インデックスの先頭に戻ってから検索を実行します。そのため、SETデータセットで検出されるそれぞれのM4J7に対して、マスタデータセットに含まれるM4J7が検出されます。出力されるM4J7 >の更新結果では、データセットNEWINVにある変数NWSTOCKの2つのM4J7の値が、データセットINVTY.STOCKの変数INSTOCKの値M4J7に追加されます。次に、合計ステートメントで値を合計します。合計ステートメントを指定しない場合、M4J7の最後のインスタンスの値だけがデータセットINVTY.STOCKに反映されます。
data invty.stock;
   set newinv;
   modify invty.stock key=partno / unique;
   INSTOCK=instock+nwstock;
   RECDATE=today();
   if _iorc_=0 then replace;
run; 
proc print data=invty.stock noobs;
   title 'Results of Using the UNIQUE Option';
run;
UNIQUEオプションを使用したINSTOCKフィールドとRECDATEフィールドの更新結果
UNIQUEオプションを使用したINSTOCKフィールドとRECDATEフィールドの更新結果

例7: I/Oの制御

この例では、SYSRC自動呼び出しマクロと自動変数_IORC_を使用して、I/O条件を制御しています。これにより、検出されない可能性のある予期しない結果を防ぐことができます。この例では、インデックス値を使用したダイレクトアクセス方式で、データセットINVTY.STOCKを更新します。データセットNEWSHIPのデータにより、データセットINVTY.STOCKが更新されます。
次のDATAステップを実行すると、データセットNEWSHIPが作成されます。
data newship;
   input PARTNO $ DESC $ NWSTOCK @17 
         SHPDATE date7. @25 NWPRICE;
   datalines;
K89R seal 14    14nov96 245.00
M4J7 sander 24  23aug96 47.98
LK43 filter 11  29jan97 14.99
MN21 brace 9    09jan97 27.87
BC85 clamp 12   09dec96 10.00
ME34 cutter 8   14nov96 14.50
;
SELECTステートメントに指定したそれぞれのWHEN句では、SYSRC自動呼び出しマクロが返す入出力のリターンコードごとに対応するアクションを指定しています。
  • _SOKは、MODIFYステートメントが正常に実行されたことを示します。
  • _DSENOMは、データセットINVTY.STOCKの中に一致するオブザベーションが見つからなかったことを示します。OUTPUTステートメントでは、データセットINVTY.STOCKにオブザベーションを追加するように指定しています。出力結果に表示される最後のオブザベーションを確認してください。
  • SYSRC自動呼び出しマクロで他のコードが返された場合は、DATAステップを終了し、PUTステートメントでメッセージをログに出力します。
libname invty 'SAS-library';
data invty.stock;
   set newship;
   modify invty.stock key=partno;
   select (_iorc_);
      when (%sysrc(_sok)) do;
         INSTOCK=instock+nwstock;
         RECDATE=shpdate;
         PRICE=nwprice;
         replace;
      end;
      when (%sysrc(_dsenom)) do;
         INSTOCK=nwstock;
         RECDATE=shpdate;
         PRICE=nwprice;
         output;
         _error_=0;
      end;
      otherwise do;
         put
         'An unexpected I/O error has occurred.'/
         'Check your data and your program';
         _error_=0;
         stop;
       end;
   end;
run;
proc print data=invty.stock noobs;
   title 'INVTY.STOCK Data Set';
run;
更新後のINVTY.STOCKデータセット
更新後のINVTY.STOCKデータセット

例8: オブザベーションの置換と削除、オブザベーションの他のSASデータセットへの書き込み

この例では、オブザベーションの置き換えや削除、別のデータセットへのオブザベーションの書き込みが実行できることを示しています。この例に示すように、OUTPUTステートメント、REPLACEステートメント、REMOVEステートメントを使用する場合、デフォルトのステートメントが生成されないので、実行するアクションを明示的に指定する必要があります。
1997年に受け取った部品はデータセットINVTY.STOCK97に出力し、データセットINVTY.STOCKから削除します。同じように1995年に受け取った部品はデータセットINVTY.STOCK95に出力し、データセットINVTY.STOCKから削除します。1996年に受け取った部品だけはデータセットINVTY.STOCKに残し、データセットINVTY.STOCKの中でだけPRICEの値を更新します。
libname invty 'SAS-library';
data invty.stock invty.stock95 invty.stock97;
   modify invty.stock;
   if recdate>'01jan97'd then do;
       output invty.stock97;
       remove invty.stock;
   end;
   else if recdate<'01jan96'd then do;
       output invty.stock95;
       remove invty.stock;
   end;
   else do; 
      price=price*1.1;
      replace invty.stock;
   end; 
run;
proc print data=invty.stock noobs;
   title 'New Prices for Stock Received in 1996';
run;
特定のSASデータセットにオブザベーションを書き込んだ後の出力結果
特定のSASデータセットにオブザベーションを書き込んだ後の出力結果

関連項目:

XisError: No pubcode in link data found for lrcon
SAS SQLプロシジャユーザーガイド
前のページ|次のページ|ページの先頭へ