Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLのViewについてまとめています。

MySQLのサンプルデータベースEmployeesを使用しています。

SQLのviewは、viewに対して更新が可能

シンプルなselect文で作成したviewはupdate文による更新が可能です。

以下は、employees(社員)テーブルのemp_no(社員番号)、first_name(名)、last_name(姓)のみを使ったviewに対して、first_nameを更新するサンプルです。

# viewを作成
mysql> create view updtest as select emp_no, first_name, last_name from employees;
Query OK, 0 rows affected (0.03 sec)

# viewの構造を表示
mysql> desc updtest;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| emp_no     | int         | NO   |     | NULL    |       |
| first_name | varchar(14) | NO   |     | NULL    |       |
| last_name  | varchar(16) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

# viewから10件表示j
mysql> select * from updtest limit 10;
+--------+------------+-----------+
| emp_no | first_name | last_name |
+--------+------------+-----------+
|  10001 | Georgi     | Facello   |
|  10002 | Bezalel    | Simmel    |
|  10003 | Parto      | Bamford   |
|  10004 | Chirstian  | Koblick   |
|  10005 | Kyoichi    | Maliniak  |
|  10006 | Anneke     | Preusig   |
|  10007 | Tzvetan    | Zielinski |
|  10008 | Saniya     | Kalloufi  |
|  10009 | Sumant     | Peac      |
|  10010 | Duangkaew  | Piveteau  |
+--------+------------+-----------+
10 rows in set (0.00 sec)

# viewに対してfirst_nameカラムを更新
mysql> update updtest set first_name="xGeorgi" where emp_no="10001";
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

# 更新後のviewを確認
mysql> select * from updtest where emp_no="10001";
+--------+------------+-----------+
| emp_no | first_name | last_name |
+--------+------------+-----------+
|  10001 | xGeorgi    | Facello   |
+--------+------------+-----------+
1 row in set (0.00 sec)

# 更新後の元テーブルを確認
mysql> select * from employees where emp_no="10001";
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | xGeorgi    | Facello   | M      | 1986-06-26 |
+--------+------------+------------+-----------+--------+------------+
1 row in set (0.00 sec)

【関連記事】
SQLのview作成 joinやサブクエリを使ったselectも使用可能

ただし、単一テーブルの特定のカラムをselectするようなシンプルなviewでのみupdateが可能です。例えば、以下の様な場合は、update実行時にエラーとなります。

joinを使ったviewに更新失敗

employees(社員)テーブル、dept_emp(部署名・社員紐付け)テーブル、departments(部署)テーブルの3テーブルをjoinするviewに対してupdateを実行すると、同様にエラーになりました。

create view jointest as SELECT 
	employees.emp_no, 
	first_name, 
	last_name, 
	dept_name 
FROM 
	employees 
	left join dept_emp on employees.emp_no = dept_emp.emp_no and first_name like 'G%'
	left join departments on dept_emp.dept_no = departments.dept_no
Query OK, 0 rows affected (0.04 sec)


mysql> desc jointest;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| emp_no     | int         | NO   |     | NULL    |       |
| first_name | varchar(14) | NO   |     | NULL    |       |
| last_name  | varchar(16) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> select * from jointest limit 10;
+--------+------------+-----------+-------------+
| emp_no | first_name | last_name | dept_name   |
+--------+------------+-----------+-------------+
|  10001 | Georgi     | Facello   | Development |
|  10002 | Bezalel    | Simmel    | NULL        |
|  10003 | Parto      | Bamford   | NULL        |
|  10004 | Chirstian  | Koblick   | NULL        |
|  10005 | Kyoichi    | Maliniak  | NULL        |
|  10006 | Anneke     | Preusig   | NULL        |
|  10007 | Tzvetan    | Zielinski | NULL        |
|  10008 | Saniya     | Kalloufi  | NULL        |
|  10009 | Sumant     | Peac      | NULL        |
|  10010 | Duangkaew  | Piveteau  | NULL        |
+--------+------------+-----------+-------------+
10 rows in set (0.00 sec)

mysql> update jointest set first_name="xGeorgi" where emp_no="10001";
ERROR 1288 (HY000): The target table jointest of the UPDATE is not updatable

こちらの場合は、The target table jointest of the UPDATE is not updatableと、対象テーブルがupdateできない旨のエラーが表示されました。

サブクエリを使ったviewでupdate失敗

create view subquerytest as select * from 
(select emp_no, first_name, last_name, hire_date from employees where birth_date > 1970-01-01 and gender = 'F'
union all
select emp_no, first_name, last_name, hire_date from employees where birth_date < 1960-01-01 and gender = 'M'
) t1
order by last_name, emp_no

mysql> desc subquerytest;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| emp_no     | int         | NO   |     | 0       |       |
| first_name | varchar(14) | NO   |     |         |       |
| last_name  | varchar(16) | NO   |     |         |       |
| hire_date  | date        | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

mysql> select * from subquerytest limit 10;
+--------+------------+-----------+------------+
| emp_no | first_name | last_name | hire_date  |
+--------+------------+-----------+------------+
|  12516 | Sreenivas  | Aamodt    | 1990-03-06 |
|  12982 | Sachem     | Aamodt    | 1992-01-11 |
|  17400 | Basim      | Aamodt    | 1991-09-15 |
|  18182 | Dekang     | Aamodt    | 1988-05-25 |
|  27188 | Vasilii    | Aamodt    | 1996-10-12 |
|  27413 | Phuoc      | Aamodt    | 1987-08-28 |
|  28387 | Nahla      | Aamodt    | 1997-02-15 |
|  29182 | Arumugam   | Aamodt    | 1986-01-09 |
|  31701 | Carrsten   | Aamodt    | 1985-10-07 |
|  35101 | Christ     | Aamodt    | 1990-02-05 |
+--------+------------+-----------+------------+
10 rows in set, 2 warnings (0.91 sec)

mysql> update subquerytest set first_name="xSreenivas" where emp_no="12516";
ERROR 1292 (22007): Incorrect date value: '1968' for column 'birth_date' at row 1

社員番号12516に対してfirst_nameをupdateしようとしたところ、Incorrect date value: ‘1968’ for column ‘birth_date’エラーとなりました。

view作成時に指定したselect文が複雑になると、予想外のエラーが表示されるようです。

まとめ

ポテパンダの一言メモ
  • viewに対するupdateは条件付きで可能
  • サブクエリやjoinを使った複雑なviewは、update発行時にエラーとなる
  • The target table jointest of the UPDATE is not updatable以外のエラーとなるケースもある

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。