2016-01-13 45 views
11

我正在使用mysql,並且在變量image_url'成功'的表'項'中更新了'沒有任何警告。但是,實際上,更新失敗了:它用一個空格前綴值並刪除我給它的值的最後一個字符。mysql update off by one character

這裏是更新:

UPDATE items 
    SET image_url = 'http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg' 
    WHERE id=38; 

下面是選擇:

select * from items\G; 

這裏是輸出中的一個行:在

... 
image_url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
... 

通知缺少 'G'開頭的結尾和額外的空間。

我該如何解決這個問題?

下面是一些系統信息,可以幫助:

mysql> show variables LIKE '%version%'; 
+-------------------------+-------------------------+ 
| Variable_name   | Value     | 
+-------------------------+-------------------------+ 
| innodb_version   | 5.5.46     | 
| protocol_version  | 10      | 
| slave_type_conversions |       | 
| version     | 5.5.46-0ubuntu0.14.04.2 | 
| version_comment   | (Ubuntu)    | 
| version_compile_machine | i686     | 
| version_compile_os  | debian-linux-gnu  | 
+-------------------------+-------------------------+ 
7 rows in set (0.00 sec) 

編輯1下表說明:

mysql> desc items; 

+-------------+---------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+---------------+------+-----+---------+----------------+ 
... 
| image_url | varchar(255) | NO |  | NULL |    | 
... 

EDIT 2檢查觸發器:

mysql> show triggers \G 
Empty set (0.00 sec) 

編輯3另一個例子:

我正在從命令行執行所有這些命令。又如:

UPDATE items SET image_url = 'http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg33333333333333' WHERE id=38; 

select * from items\G; 

... 
image_url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg3333333333333 
... 

EDIT的輸入和輸出的4檢查長度:

mysql> select image_url,length(image_url) from items where id=38\G; 
*************************** 1. row *************************** 
     image_url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
length(image_url): 61 
1 row in set (0.00 sec) 

http://www.lettercount.com/給出http://ecx.images-amazon.com/images/I/61Dz5t8wjQL.SX522.jpg 61個字符爲好,這是有意義的給出該更新未改變的長度串,只是刪除最後一個字符,添加一個空格開始,

EDIT 5試圖編碼:

base64編碼: aHR0cDovL2VjeC5pbWFnZXMtYW1hem9uLmNvbS9pbWFnZXMvSS82MUR6NXQ4d2pRTC5fU1g1MjJfLmpwZw ==

mysql> UPDATE items SET image_url = 'aHR0cDovL2VjeC5pbWFnZXMtYW1hem9uLmNvbS9pbWFnZXMvSS82MUR6NXQ4d2pRTC5fU1g1MjJfLmpwZw==' WHERE id=38; 
Query OK, 1 row affected (0.02 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> select image_url,length(image_url) from items where id=38\G; 
*************************** 1. row *************************** 
     image_url: aHR0cDovL2VjeC5pbWFnZXMtYW1hem9uLmNvbS9pbWFnZXMvSS82MUR6NXQ4d2pRTC5fU1g1MjJfLmpwZw= 
length(image_url): 84 
1 row in set (0.00 sec) 

解碼:aHR0cDovL2VjeC5pbWFnZXMtYW1hem9uLmNvbS9pbWFnZXMvSS82MUR6NXQ4d2pRTC5fU1g1MjJfLmpwZw =

給出: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg

EDIT 6檢查是否插入失敗,以及:

mysql> INSERT INTO items (url, image_url) VALUES('http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg', 'http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jpg'); 
Query OK, 1 row affected, 2 warnings (0.03 sec) 

警告是不是因爲我沒給了空的所有值:在這個沒有值插入

mysql> SHOW WARNINGS; 
+---------+------+-------------------------------------------------+ 
| Level | Code | Message           | 
+---------+------+-------------------------------------------------+ 
| Warning | 1364 | Field 'created_at' doesn't have a default value | 
| Warning | 1364 | Field 'updated_at' doesn't have a default value | 
+---------+------+-------------------------------------------------+ 
2 rows in set (0.00 sec) 


mysql> select image_url,length(image_url),url from items where id=39\G; 
*************************** 1. row *************************** 
     image_url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
length(image_url): 61 
       url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
1 row in set (0.00 sec) 

因此,它也將失敗的插入。

EDIT 7創建表信息

mysql> show create table items\G; 
*************************** 1. row *************************** 
     Table: items 
Create Table: CREATE TABLE `items` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    ... 
    `image_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `color` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    ... 
    `store` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `index_items_on_id` (`id`), 
    KEY `index_items_on_url` (`url`) 
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 
1 row in set (0.00 sec) 

ERROR: 
No query specified 

EDIT 8更多表和列信息

select * from information_schema.columns where table_name='items' and column_name='image_url'\G; 

*************************** 2. row *************************** 
      TABLE_CATALOG: def 
      TABLE_SCHEMA: development_database 
       TABLE_NAME: items 
      COLUMN_NAME: image_url 
     ORDINAL_POSITION: 5 
      COLUMN_DEFAULT: NULL 
      IS_NULLABLE: NO 
       DATA_TYPE: varchar 
CHARACTER_MAXIMUM_LENGTH: 255 
    CHARACTER_OCTET_LENGTH: 765 
     NUMERIC_PRECISION: NULL 
      NUMERIC_SCALE: NULL 
     CHARACTER_SET_NAME: utf8 
      COLLATION_NAME: utf8_unicode_ci 
      COLUMN_TYPE: varchar(255) 
       COLUMN_KEY: 
        EXTRA: 
       PRIVILEGES: select,insert,update,references 
      COLUMN_COMMENT: 
2 rows in set (0.01 sec) 

ERROR: 
No query specified 

EDIT 9個 Charlength讀數

mysql> select image_url,length(image_url),char_length(image_url),url from items where id=39\G; 
*************************** 1. row *************************** 
      image_url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
    length(image_url): 61 
char_length(image_url): 61 
        url: http://ecx.images-amazon.com/images/I/61Dz5t8wjQL._SX522_.jp 
1 row in set (0.00 sec) 

ERROR: 
No query specified 

EDIT 10表示變量,如字符

mysql> show variables like 'character%'; 
+--------------------------+----------------------------+ 
| Variable_name   | Value      | 
+--------------------------+----------------------------+ 
| character_set_client  | utf8      | 
| character_set_connection | utf8      | 
| character_set_database | utf8      | 
| character_set_filesystem | binary      | 
| character_set_results | utf8      | 
| character_set_server  | latin1      | 
| character_set_system  | utf8      | 
| character_sets_dir  | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 
8 rows in set (0.00 sec) 

編輯11:潛在問題

錯誤沒有出現在用戶表,但它確實發生在項目表中。以下是我認爲可能導致問題的區別。 (我還沒有一個解決方案,因爲該項目表有UTF-8是有原因的:URL可以有一些時髦的字符)

show create table users\G; 

ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 

show create table items\G; 

ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 
+2

**編輯10 **中引用'latin1'或'utf8'的所有行都應該是相同的,理想情況下應該是'utf8mb4'。我現在要冒險猜測,在非真正的UTF-8字符整理中保存UTF-8字符意味着任何字符串的最後一個字符是不完整的引用,因此不能顯示。 – Martin

+1

對於您的信息'utf8mb4'是完整且完整的UTF-8集合,因此將顯示任何可用於網址的任何字符。如果數據中有一些模糊的字符,我建議你在*之前將列更改爲'BLOB'列*,然後將其更改爲'utf8mb4',因爲這會將正確的字符定義*保留爲輸入*,而不是*假定由MySQL *根據已經輸入的數據。 – Martin

+2

不,你不想要utf8,在MySQL中這是一樣好,你想要的是'utf8mb4',MySQL中的標準UTF8定義是垃圾,而不是你想要的。 – Martin

回答

4

說實話,我覺得這應該是一個社區答案,如我在現場不久之後就是 ,其他人已經做了一些重要的地面工作 確定了這個問題過去和現在都沒有的因素。

This link may be relevant,爲你的表字符集是utf8所以字符串中的最後一個字符可能會越來越傾斜(和不保存正確,從而消失)。

所有行中EDIT 10哪個參考latin1utf8字符集歸類應該是相同的,並且理想地應該是utf8mb4。我現在要冒險猜測,在非真正的UTF-8字符整理中保存UTF-8字符意味着任何字符串的最後一個字符是不完整的引用,因此不能顯示。

所以要解決你的問題,運行以下命令:

ALTER TABLE items CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; 

對於信息/背景:

utf8mb4是全面和完整的UTF-8字符集,所以會表現出任何一位可以在網址中使用的字符。如果在該數據中的一些模糊的人物,我建議你前列更改爲BLOB然後將其更改爲utf8mb4列,因爲這會保留正確的字符定義作爲輸入而非由MySQL作爲假設對已經輸入的數據。

你不希望utf8_字符集,在MySQL中是一樣好破壞,你想要的是utf8mb4,在MySQL中的標準UTF8定義是妥協的,因爲它保存3字節塊中的4字節字符,從而損壞保存的字符數據。