mysql視圖的限制,以及實例

視圖從表象上看根表差不多,但是畢盡它不是表,對他的使用有什麼限制呢?

1,mysql的視圖名不能和現有表名重複

  1. mysql> show tables;     //查看錶

  2. +------------------+  

  3. | Tables_in_uchome |  

  4. +------------------+  

  5. | comment          |  

  6. | user             |  

  7. +------------------+  

  8. 2 rows in set (0.00 sec)  

  9. mysql> create view user as select * from user;        //視圖名和存在表重名,報錯

  10. ERROR 1050 (42S01): Table 'user' already exists  

  11. mysql> create view v_user as select * from user;     //創建視圖

  12. Query OK, 0 rows affected (0.00 sec)  

  13. mysql> show tables;    //查看錶,包涵了視圖

  14. +------------------+  

  15. | Tables_in_uchome |  

  16. +------------------+  

  17. | comment          |  

  18. | user             |  

  19. | v_user           |  

  20. +------------------+  

  21. 3 rows in set (0.00 sec)  

  22. mysql> check table v_user;     //查看一下視圖,

  23. +---------------+-------+----------+----------+  

  24. | Table         | Op    | Msg_type | Msg_text |  

  25. +---------------+-------+----------+----------+  

  26. | test_1.v_user | check | status   | OK       |  

  27. +---------------+-------+----------+----------+  

  28. 1 row in set (0.00 sec)  

從上面的一些操作,我們可以看出,其實mysql有的時候,已經把視圖當成一種虛擬表來使用了,既然是一種虛擬表,表名當然是不能重複的了。

2,視圖所對應的表,不能是臨時表

  1. //創建臨時表 tmp_user

  2. mysql> CREATE temporary TABLE IF NOT EXISTS `tmp_user` (  

  3. ->   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶ID',  

  4. ->   `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名稱',  

  5. ->   `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0爲男,1爲女',  

  6. ->   PRIMARY KEY (`id`)  

  7. -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  

  8. Query OK, 0 rows affected (0.04 sec)  

  9. mysql> desc tmp_user;   //查看臨時表,用show tables;看不到的。用check table也可以看到

  10. +-------+-------------+------+-----+---------+----------------+  

  11. | Field | Type        | Null | Key | Default | Extra          |  

  12. +-------+-------------+------+-----+---------+----------------+  

  13. | id    | int(11)     | NO   | PRI | NULL    | auto_increment |  

  14. | name  | varchar(50) | NO   |     |         |                |  

  15. | sex   | int(1)      | NO   |     | 0       |                |  

  16. +-------+-------------+------+-----+---------+----------------+  

  17. 3 rows in set (0.00 sec)  

  18. mysql> create view v_test as select * from tmp_user;      //用臨時表會報錯,看下的錯

  19. ERROR 1352 (HY000): View's SELECT refers to a temporary table 'tmp_user'  

3,創建視圖時不能使用系統或用戶變量

  1. mysql> set @test="2";   //定義一個用戶變量

  2. Query OK, 0 rows affected (0.00 sec)  

  3. mysql> create view vv_test as select * from aa where id=@test;   //創建視圖

  4. ERROR 1351 (HY000): View's SELECT contains a variable or parameter   //報sql中有變量,錯誤

  5. mysql> select * from aa where id=@test;  //真正的表是可以使用的

  6. +----+------+------------+------+  

  7. | id | name | nname      | sex  |  

  8. +----+------+------------+------+  

  9. |  2 | d    | bbbb,4bbbb | NULL |  

  10. +----+------+------------+------+  

  11. 1 row in set (0.00 sec)  

4,不能使用預處理語句參數,存儲過程中的參數或局部變量

  1. mysql> prepare p_test from "select * from user";   //產生一個預處理變量

  2. Query OK, 0 rows affected (0.00 sec)  

  3. Statement prepared  

  4. mysql> create view v_test as execute p_test;   //使用預處理變量報錯

  5. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'execute p_test' at line 1  

  6. mysql> create view v_test as p_test;    //這樣也不行

  7. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'p_test' at line 1  

  8. mysql>  execute p_test;    //單獨是沒問題的

  9. +----+--------+-----+  

  10. | id | name   | sex |  

  11. +----+--------+-----+  

  12. |  1 | zhangy |   0 |  

  13. |  3 | tank   |   0 |  

  14. |  4 | tank   |   0 |  

  15. +----+--------+-----+  

  16. 3 rows in set (0.00 sec)  

存儲過程中產生的參數,或者是局量也不行,大家可以試一下。

5,如果預處理語句調用了視圖,視圖就不能變了。

  1. mysql> create view aa_test as select * from comment;    //創建一個視圖

  2. Query OK, 0 rows affected (0.26 sec)  

  3. mysql> prepare test22 from "select * from aa_test";   //預處理語句使用了這個視圖

  4. Query OK, 0 rows affected (0.00 sec)  

  5. Statement prepared  

  6. mysql> execute test22;     //調用一下預處理語句

  7. +------+------+--------+---------+  

  8. | c_id | u_id | name   | content |  

  9. +------+------+--------+---------+  

  10. |    1 |    1 | zhangy | test    |  

  11. |    2 |    1 | zhangy | test2   |  

  12. +------+------+--------+---------+  

  13. 2 rows in set (0.00 sec)  

  14. mysql> alter view aa_test as select * from user;    //修改視圖,把基礎表改成user

  15. Query OK, 0 rows affected (0.00 sec)  

  16. mysql> execute test22;      //在調用一下預處理語句,內容沒有變

  17. +------+------+--------+---------+  

  18. | c_id | u_id | name   | content |  

  19. +------+------+--------+---------+  

  20. |    1 |    1 | zhangy | test    |  

  21. |    2 |    1 | zhangy | test2   |  

  22. +------+------+--------+---------+  

  23. 2 rows in set (0.00 sec)  

6,在存儲過程中不能修改視圖

  1. mysql> create procedure test3()  

  2. -> begin  

  3. -> select * from aa_test;  

  4. -> alter view aa_test as"select * from comment";  

  5. -> select * from aa_test;  

  6. -> end;|  

  7. ERROR 1314 (0A000): ALTER VIEW is not allowed in stored procedures    //會報錯的

爲什麼是mysql手冊裏面,我看到可以在存儲過程中修改視圖的,爲什麼我用的mysql就不行呢?是不是mysql版本的問題。我用的是Server version: 5.1.26-rc-log Source distribution

7,不能給視圖添加索引

  1. mysql> create index aa_index on aa_test (c_id);  

  2. ERROR 1347 (HY000): 'test.aa_test' is not BASE TABLE   //添加索引會報錯的

視圖根本不是基本的表,在存放數據的文件夾中,他只有一個結構文件,沒有.MYD,.MYI文件,如果能增加索引存放到什麼地方。

8,視圖插入,添加,刪除的限制

對於有些視圖是可以UPDATE、DELETE或INSERT等操作的,以達到修改基本表的內容。對於可更新的視圖,它必須和基本表是一一對應關係。如果視圖中包括以下的東西就不是一一對應關係了。就不能進行更新操作。

  1. //下面的視圖根基本表user是一一對應關係,可以進行更新操作

  2. mysql> create view v_user as select * from user;  

  3. Query OK, 0 rows affected (0.00 sec)  

  4. //視圖對應二個基本表,視圖中的內容,不和任何一張表一一對應,不能進行更新操作

  5. mysql> create view tall as select a.id,a.name,b.content from user a left join comment b on a.id=b.u_id where b.content != 'null';  

  6. Query OK, 0 rows affected (0.00 sec)  

a),聚合函數(SUM(), MIN(), MAX(), COUNT()等)。
b),DISTINCT
c),GROUP BY
d),HAVING
e),UNION或UNION ALL
f),位於選擇列表中的子查詢
g),Join
h),FROM子句中的不可更新視圖
i),WHEHE子句中的子查詢,引用FROM子句中的表。
m),僅引用文字值(在該情況下,沒有要更新的基本表)。
n),ALGORITHM = TEMPTABLE(使用臨時表總會使視圖成爲不可更新的)。
o),關於可插入性(可用INSERT語句更新),如果它也滿足關於視圖列的下述額外要求,可更新的視圖也是可插入的:
p),不得有重複的視圖列名稱。
q),視圖必須包含沒有默認值的基表中的所有列。
r),視圖列必須是簡單的列引用而不是導出列。

上面a-r的這幾種情況,其實就是一種情況,規則就是,視圖的數據根基本表的數據不一樣了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章