处理丢失和无效的数据值
1.MYSQL針對無效的值采用了一種“forgiving的方式”即采用與合法值最接近的值插入數據庫。例如一個unsigned的列值時,當輸入負值是會轉換為0插入。可能不會被回滾。
可以通過設定SQL mode通過sql_mode系統變量來執行嚴格的管理。
默認的情況是slq_mode='',意味著沒有限制,使用set sql_mode=' ';
Set sql_mode='STRICT_TRANS_TABLES';
Set ?sql_mode='STRICT_ALL_TABLES';設置后可以阻止例如越界,null例如指定not null列。
其他的SLQ mode如tranditionnal,能夠使嚴格的模式加上其他的限制在日期檢查和除數為0.
insert into t (i) values(43); ? //MySql執行自動string-to-number轉換對于第二天語句
insert into t(i) values('43');
下面的語句也可以執行轉換:insert into t(i) values('43x');也會進行轉換但是會產生一個警告可以使用strict ?SQL mode
5.8.1 處理丟失的值
create table t(
? ?i int null,
? j int not null,
? k int default -1
);
對于這個表
insert into t (i) values(0);
insert into t (i,k) values(1,2);
insert into t (i,k) values(1,2),(3,4);
insert into t values();
最后一個語句表示,空值表示使用默認值對于所有的列。
MySQL處理丟失的值:
1. 列的定義包含DEFAULT語句,如果沒有明確的default的語句這個列將采用空值,因此i列有個DEFAULT NULL的定義
2.如果一個列定義沒有DEFAULT語句,丟失的值處理取決于SQL 模式是否這個表示是transactional:
? ? 2.1如果嚴格的模式不是有效的,mysql插入沒有明確的默認值將產生一個警告
? ? 2.2 如果嚴格模式是有效的,一個錯誤將發生對于transactional表(和語句產生回滾)。錯誤發生在非transactional表上,但是部分更新可能導致:如果錯誤發生在第二行或以后的行,那么前面的行可能已經被插入。
? ?5.8.2 處理無效的值在非嚴格的模式
一般,mysql將執行類型轉換基于限制條件(列定義的)。如下:
1.當你插入和更新列值是如insert replace,update或者load data infile。
2.當你干部列的的定義使用alert table
3.當你指定一個默認值使用default語句時
如果MYsql沒有運行在嚴格模式,他將修正無效的輸入值到合法的值和產生警告信息。這些消息經通過show warning語句來展示。
? 1.Conversion of out-of-range values to in-range values.如果你試圖存儲一個比最小值還小的值時就存儲最小值。如果存儲比最大值還大的值時就存儲最大的值。
? ?2.String truncation ?字符串值太長需要被截斷來匹配列。如果你試圖存儲‘Sakila’到一個char(4)列,mysql存儲它作為‘Saki’和拋棄剩余的字符
? ?3.Enumeration 和 set value conversion. 如果值不在Enum定義,mysql將轉換他為‘’字符串。如果一個值不在set列,將拋棄這些元素,仍舊保留合法元素。
? ? 4.Conversion to data type default。如果你試圖存儲一個值不能被轉換為列數據類型。Mysql經存儲不明確的默認值,例如,如果嘗試存儲‘Sakila’到int 列,mysql存儲0.對于日期類型是0000-00-00
? ? 5.處理Handling assignment of null to not null columns。分配NULL到非空列取決于是否這個分配發生在一個單行或多行的插入語句。對于一個單行的插入,一個錯誤發生和語句失敗。對于一個多行的插入,mysql分配列的不明確的默認值對于它的數據類型。
使用alert來改變列的數據類型時,將會導致一些列的值改變。如果改變int到tinyint,任何值在tinyint的將被剪切到tinyint的附近。
如果列被改變為not null,那么mysql將會轉換null值到這不明確的值
接下的表表明幾種字符串值的類被處理轉換為date或int數據類型。
?輸入的值可能是無效的對于下面的原因:
? ? ?1.對于一個數值或臨時的列,一個值坑能越界
? ? ?2. 對于string可能太長
? ? 3.對于enum不在范圍,對于set 不包含插入的元素
? ?4.對于not null的列,一個null值肯能插入
在嚴格的模式,服務器將拒絕越界,有不正確數據類型和丟失列值(對于那些沒有default的列)。嚴格的模式能夠使用strict_tans_tables和strict_all_tables
? ?strict_trans_table:能夠采用嚴格的行為對于錯誤能夠回滾或取消沒有干嘛表到數據正在進入的狀態。如果錯誤發生對于transactional表,這語句將拋棄和回滾。對于一個non-transactional表,這語句將被拋棄沒有改變表如果一個無效的值發生在當行插入或者多行插入的第一行。否則,為了避免部分更新對于non-transactional表,mysql將修正任何無效的值到合法的值然后插入他和產生一個警告。
? ? strict_all_tables:和strict_tans_table相似但是將引發non-transaction表拋棄沒有發生在第二行或者之后的多行插入。這意味著一個部分更新可能發生,因為更早插入的語句將已經被插入。
? ?5.8.4 Enabling additional input data restrictions
? ? ?可能的模式可以使用:
? ? 1. Divison by zero 使用ERRO_FOR_DIVISION_BY_ZERO值,將產生錯誤。set sql_mode=‘stricat——all_tables,error_for_division_by_zero’;
? ? ?2.默認情況下,mysql運行‘zero’日期和有0部分的日期。例如日期被允許盡管你能夠采用嚴格模式,但是如果你想阻止他們,可以使用NO_zero_date 和no_zero_in_date
? ?
? ? 這traditional模式值是一個組合模式能夠嚴格模式和其他限制被描述。如果你想要Mysql服務器關于輸入數據檢查
5.8.5 ?覆蓋輸入數據限制
為了覆蓋輸入數據限制,使用insert ignoreor update ignore 而不是使用insert or update。這ignore關鍵字經引起mysql使用non-strict行為對于這個語句。
?如果你想要使用relaxed日期檢查,需要set sql_mode='allow_invalid_dates';
set sql_mode='strict_all_tables,allow_invalid_dates';
總結
以上是生活随笔為你收集整理的处理丢失和无效的数据值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 所有排序算法
- 下一篇: Indetifier