JAVA调用MySQL存储过程插入无单引号十六进制值失败如何解决
问题原因
你在MySQL命令行中写的0xf6fdffe48c908deb0f4c3bd36c032e72是不带引号的二进制字面量,本质是字节序列,不是普通字符串。你之前用setString传入带0x前缀的字符串时,JDBC会自动将参数作为字符串处理,执行时会给值包裹单引号,最终传入存储过程的是'0xf6fdffe48c908deb0f4c3bd36c032e72'字符串,和预期的二进制值完全不符,所以执行出错。
解决方法
不需要将MD5计算结果转成带0x前缀的字符串作为第二个参数,直接传入MD5生成的原始字节数组即可,使用setBytes方法赋值:
步骤1:保留MD5计算生成的原始字节数组
修改你的MD5计算逻辑,存储原始字节数组:
byte[] md5RawBytes = null; // 新增变量存储原始MD5字节 String result = ""; String login_password = login + password; MessageDigest m; try { m = MessageDigest.getInstance("MD5"); m.update(login_password.getBytes()); md5RawBytes = m.digest(); // 直接获取原始字节数组 BigInteger hash = new BigInteger(1, md5RawBytes); result = hash.toString(16); while (result.length() < 32) { result = "0" + result; } result = "0x" + result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
步骤2:修改参数赋值逻辑
将第二个参数的赋值方法从setString改为setBytes,传入刚才存储的原始字节数组:
cstmt.setString(1, login); cstmt.setBytes(2, md5RawBytes); // 替换原来的setString(2, result) // 其余3-16位参数保持不变 cstmt.setString(3, "0"); // ... 省略中间重复的赋值代码 cstmt.setString(14, "0"); cstmt.setString(15, "0"); cstmt.setString(16, "0"); // 第17位参数如果存储过程要求是字符串格式的十六进制,保留原来的setString即可 // 如果第17位也是二进制类型,同样改为cstmt.setBytes(17, md5RawBytes) cstmt.setString(17, result);
修改后执行效果和你直接在MySQL中执行的CALL语句完全一致。
内容的提问来源于stack exchange,提问作者Bruno Souto
相关产品推荐
相关产品推荐

