データの更新と主キーの重要性SQL実践講座(14)

» 2001年04月28日 00時00分 公開
[篠原光太郎@IT]

「UPDATE」でデータを更新する

 前回(第13回 「テーブル中のデータ識別に必要な主キー」)は、「CardInfo」という名前のテーブルに「プライマリキー(主キー)」を作成しました。今回は、このテーブルのデータ更新を行います。

 まず、CardInfoのデータを表示させます。連載の第12回(「データの登録を行うINSERT文」)で使用した、CardIDが「NW」で始まるデータを検索してみましょう。

【例1】

SELECT *
FROM CardInfo 
WHERE CardID like 'NW%'
画面1 CardInfoテーブルの中から、CardIDが「NW」で始まるデータを抽出したところ(画面をクリックすると拡大表示します)

 では、CardIDがNW0001の顧客のExpireDateを「2004年3月31日」に更新します。この場合は、次のようなSQL文を発行します。

【例2】

UPDATE CardInfo
SET ExpireDate = '2004/3/31'
WHERE CardID = 'NW0001'

 確認のために、例1のSQLをもう一度実行してみましょう。

画面2 UPDATE文による例2の変更が反映されたかを例1のSQL文で確認したところ(画面をクリックすると拡大表示します) 画面2 UPDATE文による例2の変更が反映されたかを例1のSQL文で確認したところ(画面をクリックすると拡大表示します)

 更新されたのが確認できますね。では、例2のSQLを見ていきましょう。

 データの更新には「UPDATE」文を使用します。UPDATEの後には、更新対象のテーブル名を記述します。SET句には更新する列と、更新する値を記述します。ここでは、ExpireDateの更新ですので、ExpireDate = '2004/3/31' としています。最後にWHERE句で更新対象のデータを指定します。ここでは、CardIDが「NW0001」のカードデータを更新しますので、CardID = 'NW0001' としています。

 CardIDを主キーに設定しましたが、その理由の1つがここにあります。CardInfoテーブルに主キーの設定をしなかった場合、データの挿入は特に問題なくすることができます。ただし、更新することを考えると、必ず特定の行を指定するためのキーが必要になります。キーがなかった場合は、最悪、ある特定の行を更新できないデータを作成することも可能になってしまうからです。テーブルを設計する際は、キーになる列を必ず作成し、「主キー」として定義した方が安全です。

 ただし、主キーを設定したからといって、更新のためのWHERE句に指定するのが主キーだけとは限りません。更新が必要な行がWHERE句によって特定できればOKです。例えば、WHERE句の検索結果が複数行の場合を試してみましょう。次のSQLを実行します。

【例3】

UPDATE CardInfo
SET EmployeeID = '9'
WHERE CardID like 'NW%'
画面3 主キー以外のフィールドを更新の条件にすることもできる(画面をクリックすると拡大表示します) 画面3 主キー以外のフィールドを更新の条件にすることもできる(画面をクリックすると拡大表示します)

 WHERE句で指定した条件は、2行の顧客データが該当するため、EmployeeIDが両方とも「9」に更新されているのが確認できますね。1つのSQLで複数の行を処理対象とできるのは、SQLの大きな特徴ですね。

 WHERE句を指定しなかった場合は、テーブルに格納されている全行が更新の対象となります。間違ってWHERE句を指定しなかったりすると大変なことになります。通常の操作では「やり直し(UNDO)」は効かなくなっているため、注意が必要です。更新などのDB操作の「UNDO」にあたる処理を可能にする「トランザクション制御」に関しては、回を改めて解説する予定です。

 では、もう少しUPDATE文を見ていきましょう。主キーであるCardIDを変えた場合はどうなるでしょうか。

【例4】

UPDATE CardInfo
SET CardID = 'NW0002'
WHERE CardID like 'NW0001'

 例1のSQLを発行して、更新された内容を確認します。

画面4 主キー自体の内容を変更することもできる(画面をクリックすると拡大表示します) 画面4 主キー自体の内容を変更することもできる(画面をクリックすると拡大表示します)

 特に問題なく更新されました。では、同じIDがある場合はどうでしょうか。

【例5】

UPDATE CardInfo
SET CardID = 'NW0009'
WHERE CardID like 'NW0002'
画面5 主キーの内容を、すでに存在するデータと同じものに変更しようとしたところ、警告メッセージが表示された(画面をクリックすると拡大表示します) 画面5 主キーの内容を、すでに存在するデータと同じものに変更しようとしたところ、警告メッセージが表示された(画面をクリックすると拡大表示します)

 「PRIMARY KEY 違反」、つまり、主キーの制約違反のエラーが発生し、データの更新は完了できませんでしたね。主キーはユニークキーである、という説明を前回しましたが、ここでこの制約が発動しています。つまり、同じ値がほかにある場合は、更新ができないよう制限されているのが確認できました。

SQL Server Enterprise Managerからのデータ更新

 では、SQL Server Enterprise Managerを使用したデータ更新の方法を確認してみましょう。テーブルリストからCardInfoを選び、右クリックで「テーブルを開く」→「全行を返す」を選択します。

画面6 SQL Server Enterprise Managerでテーブル内容の変更を行うには、該当するテーブルを選択した状態で、右クリックメニューで「テーブルを開く」→「全行を返す」の順に選択する(画面をクリックすると拡大表示します) 画面6 SQL Server Enterprise Managerでテーブル内容の変更を行うには、該当するテーブルを選択した状態で、右クリックメニューで「テーブルを開く」→「全行を返す」の順に選択する(画面をクリックすると拡大表示します)
画面7 テーブル内のデータ一覧が表示され、データの変更が可能になる(画面をクリックすると拡大表示します) 画面7 テーブル内のデータ一覧が表示され、データの変更が可能になる(画面をクリックすると拡大表示します)

 Excelライクなデータ一覧が表示されます。必要な個所を選択し、直接データを変更することが可能です。データを変更中は、一番左のライン・インジケータが鉛筆のアイコンに変わります。ほかの行にカーソルが移ると、データが更新され、ライン・インジケータが三角形に戻ります。

 さて、先ほど、主キーのないテーブルは更新時に不具合がある可能性がある、という説明をしましたが、CardInfo2を使用してデータ編集をするとどうなるかを確認してみましょう。

 テーブルリストからCardInfo2を選択し、データの編集画面を表示します。

画面8 CardInfo2テーブルの編集画面を表示したところ。CardIDのフィールドに「NW0010」という同じ内容のデータが2つ登録されていることが分かる(画面をクリックすると拡大表示します) 画面8 CardInfo2テーブルの編集画面を表示したところ。CardIDのフィールドに「NW0010」という同じ内容のデータが2つ登録されていることが分かる(画面をクリックすると拡大表示します)

 この状態では、CardIDが「NW0010」のカード情報が2行あることが分かりますね。また、この2行は、すべての列のデータがまったく同一で、見分けがつかない状態です。このデータの一部を変更して確定してみましょう。

画面9 画面上では編集できるが、実際にデータが更新しようとした段階で、警告のエラーメッセージが表示される(画面をクリックすると拡大表示します) 画面9 画面上では編集できるが、実際にデータが更新しようとした段階で、警告のエラーメッセージが表示される(画面をクリックすると拡大表示します)

 画面上では修正できますが、データを更新しようとした段階でエラーとなります。メッセージのとおり、まったく同じ行が2行あり、どちらを更新したらよいのか分からないために出るエラーです。主キーの重要性が確認できますね。

今回のまとめ

今回は、データの更新について解説しました。次回は、Viewの定義について解説していきます



「SQL実践講座」バックナンバー

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。