mysql insert 错误码_利用 MySQL 自身错误诊断区域-爱可生
原標題:利用 MySQL 自身錯誤診斷區域-愛可生
背景
本篇文章來源于今天客戶問的一個問題。
問題大概意思是:我正在從 Oracle 遷移到 MySQL,數據已經轉換為單純的 INSERT 語句。由于語句很多,每次導入的時候不知道怎么定位到錯誤的語句。 如果 INSERT 語句少也就罷了,我可以手工看,不過 INSERT 語句很多,我怎么定位到是哪些語句出錯了,我好改正呢?總不能每次遇到的錯誤的時候改一下,再重新運行繼續改正吧?有沒有簡單點的方法。
其實 MySQL 自身就有錯誤診斷區域,如果能好好利用,則事半功倍。
演示
下面我來簡單說下怎么使用錯誤診斷區域。
比如說我要插入的表結構為 n3,保存錯誤信息的日志表為 error_log 兩個表結構如下:
-- tables definition.
[ytt]>create table n3 (id int not null, id2 int generated always as ((mod(id,10))));
Query OK, 0 rows affected (0.04 sec)
[ytt]>create table error_log (sqltext text, error_no int unsigned, error_message text);
Query OK, 0 rows affected (0.04 sec)
假設插入的語句,為了演示,我這里僅僅簡單寫了 8 條語句。
-- statements body.
set @a1 = "INSERT INTO n3 (id) VALUES(100)";
set @a2 = "INSERT INTO n3 (id) VALUES('test')";
set @a3 = "INSERT INTO n3 (id) VALUES('test123')";
set @a4 = "INSERT INTO n3 (id) VALUES('123test')";
set @a5 = "INSERT INTO n3 (id) VALUES(200)";
set @a6 = "INSERT INTO n3 (id) VALUES(500)";
set @a7 = "INSERT INTO n3 (id) VALUES(null)";
set @a8 = "INSERT INTO n3 (id) VALUES(10000000000000)";
MySQL 的錯誤代碼很多,不過總體歸為三類:
sqlwarning SQLSTATE 代碼開始為 '01'
not found SQLSTATE 代碼開始為 '02'
sqlexception SQLSTATE 代碼開始非 '00','01','02' 的所有錯誤代碼。
為了簡單方便,我們寫這些代碼到存儲過程里。以下為示例存儲過程。
-- stored routines body.
drop procedure if exists sp_insert_simple;
delimiter ||
create procedure sp_insert_simple()
l1:begin
DECLARE i,j TINYINT DEFAULT 1; -- loop counter.
DECLARE v_errcount,v_errno INT DEFAULT 0; -- error count and error number.
DECLARE v_msg TEXT; -- error details.
declare v_sql json; -- store statements list.
declare v_sql_keys varchar(100); -- array index.
declare v_sql_length int unsigned; -- array length.
-- Handler declare.
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND -- exception in mysql routines.
l2:BEGIN
get stacked diagnostics v_errcount = number;
set j = 1;
WHILE j <= v_errcount
do
GET stacked DIAGNOSTICS CONDITION j v_errno = MYSQL_ERRNO, v_msg = MESSAGE_TEXT;
-- record error messages into table.
INSERT INTO error_log(sqltext,error_no,error_message) VALUES (@sqltext, v_errno,v_msg);
SET j = j + 1;
END WHILE;
end;
-- sample statements array.
set v_sql = '{
"a1": "INSERT INTO n3 (id) VALUES(100)",
"a2": "INSERT INTO n3 (id) VALUES(''test'')",
"a3": "INSERT INTO n3 (id) VALUES(''test123'')",
"a4": "INSERT INTO n3 (id) VALUES(''123test'')",
"a5": "INSERT INTO n3 (id) VALUES(200)",
"a6": "INSERT INTO n3 (id) VALUES(500)",
"a7": "INSERT INTO n3 (id) VALUES(null)",
"a8": "INSERT INTO n3 (id) VALUES(10000000000000)"
}';
set i = 1;
set v_sql_length = json_length(v_sql);
while i <=v_sql_length do
set v_sql_keys = concat('$.a',i);
set @sqltext = replace(json_extract(v_sql,v_sql_keys),'"','');
prepare s1 from @sqltext;
execute s1;
set i = i + 1;
end while;
drop prepare s1;
-- invoke procedure.
-- call sp_insert_simple;
end;
delimiter ;
我們來調用這個存儲過程看下結果。
[(none)]>use ytt
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
[ytt]>call sp_insert_simple;
Query OK, 0 rows affected (0.05 sec)
表N3的結果。
[ytt]>select * from n3;
+-----+------+
| id | id2 |
+-----+------+
| 100 | 0 |
| 200 | 0 |
| 500 | 0 |
+-----+------+
3 rows in set (0.00 sec)
錯誤日志記錄了所有錯誤的語句。
[ytt]>select * from error_log;
+--------------------------------------------+----------+-------------------------------------------------------------+
| sqltext | error_no | error_message |
+--------------------------------------------+----------+-------------------------------------------------------------+
| INSERT INTO n3 (id) VALUES('test') | 1366 | Incorrect integer value: 'test' for column 'id' at row 1 |
| INSERT INTO n3 (id) VALUES('test123') | 1366 | Incorrect integer value: 'test123' for column 'id' at row 1 |
| INSERT INTO n3 (id) VALUES('123test') | 1265 | Data truncated for column 'id' at row 1 |
| INSERT INTO n3 (id) VALUES(null) | 1048 | Column 'id' cannot be null |
| INSERT INTO n3 (id) VALUES(10000000000000) | 1264 | Out of range value for column 'id' at row 1 |
+--------------------------------------------+----------+-------------------------------------------------------------+
5 rows in set (0.00 sec)
其實這個問題如果用 Python 或 PHP 等外部語言來說,將會更簡單,思路差不多。
關鍵字:愛可生、MySQL數據庫、數據庫運維管理、開源數據庫解決方案返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的mysql insert 错误码_利用 MySQL 自身错误诊断区域-爱可生的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 检视_Java高并发系列——检
- 下一篇: python3精要(4)-python数