- 論壇徽章:
- 0
|
本帖最后由 byrcc 于 2012-09-07 18:32 編輯
前些時間很忙,沒有繼續(xù)分析這個問題。今天再研究了一下,有些眉頭了,基本定位到prepare statement的問題,并且可以重現(xiàn),腳本附后面。在這里有個類似的問題http://bugs.mysql.com/bug.php?id=54791,不過粗看一下還是沒發(fā)現(xiàn)問題根源和解決辦法。求各位大牛幫分析分析!
重現(xiàn)條件:1,表gbk編碼。2,使用prepare方式插入數(shù)據(jù)。
我在5.0.77-log和5.1.61-log版本的mysql上都測試都有這問題,php版本5.1.6
插入數(shù)據(jù)可以成功,并在表中能查到數(shù)據(jù),值都正確,但是使用mysqlbinlog查看到的sql中的數(shù)值是十六進制的,而general query log也顯示是十六進制的,如下
mysqlbinlog查看結(jié)果:
insert into tbl_test_pdo values(0x30,0x313030373736363032,0xB2E2)
general log:- Time Id Command Argument
- 120907 18:24:20 1 Connect root@127.0.0.1 on cc
- 1 Query set names gbk
- 1 Prepare insert into tbl_test_pdo values(?,?,?)
- 1 Execute insert into tbl_test_pdo values(0x30,0x313030373736363032,0xB2E2)
- 1 Close stmt
復制代碼 我測試使用的腳本
建表:- CREATE TABLE `tbl_test_pdo` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `num` decimal(18,0) DEFAULT NULL,
- `dsc` varchar(32) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=gbk
復制代碼 php腳本:- $dbms='mysql';
- $host='127.0.0.1';
- $dbname='test';
- $dbuser='root';
- $dbpass='pass';
- $dsn="$dbms:host=$host;dbname=$dbname";
- try {
- $dbh = new PDO($dsn, $dbuser, $dbpass);
- $sql2 = "insert into tbl_test_pdo values(:_1,:_2,:_3)";
- $dbh->exec('set names gbk');
- $stmt = $dbh->prepare($sql2,array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
- $rlt = $stmt->execute(array(':_1'=>0,':_2'=>100776602,':_3'=>'測'));
- } catch (PDOException $e) { die ("Error!: " . $e->getMessage()); }
復制代碼 ===================上次發(fā)貼內(nèi)容=====================
新手求教大家一個問題
mysql版本:5.1.61-log
使用這個版本自帶mysqlbinlog查看一個binlog文件,發(fā)現(xiàn)有下面的sql。它的特點是,values列表的值全是十六進制的,開發(fā)反應也沒有直接使用十六進制操作數(shù)據(jù)庫。為啥查看出來的binlog結(jié)果是這樣的呢?
表的id定義為decimal(18,0) primary key,而這個sql中的id值0x313030373736383436轉(zhuǎn)成十進制后,已經(jīng)超過decimal(18,0)的范圍。當前mysql的sql_mode為默認設(shè)置。這條數(shù)據(jù),依據(jù)開發(fā)的log,id的值大概在100776703這個值大小。而100776703這個id在表中也能夠查到那條數(shù)據(jù)。
這問題導致的結(jié)果是,在從庫上,這個表的更新報錯了,錯誤描述是tbl_xxxxxxxxxx這個表id主鍵沖突,沖突的值是999999999999999999,這個值恰好是十六進制id值0x313030373736383436截斷到精度decimal(18,0)后的值。
不知道大家是否遇到過同樣的問題?
insert into tbl_xxxxxxxxxx (id,version,createtime,updatetime,...在此省略部分字段列表...) values (0x313030373736383436,0x31,0x323031322D30382D31342031363A31313A3132,0x323031322D30382D31342031363A31313A3132,"","",0x313932307831323030,"","","","",0x736F676F752E636F6D,0xBAA3D4F4CDF5382E6A7067,0x373532,"","","","","","","",0x2F75706C6F6164496D6167652F323031322F30382F31342F313334343933313837325F352E6A7067,0x2F75706C6F6164496D6167652F323031322F30382F31342F313334343933313837325F352E6A70675F73,0x31,0x33,0x2D31,0x3530,0x30,0x2D31,0x2D31,0x30,0x31,"") |
|