处理coldfusion中的MySQL NativeError Code 1366和SQLState HY000

请在下面找到错误的最初几行堆栈跟踪:(sl这列是我在存储过程代码中用到的)

Please find the initial few lines of stack trace of the error below: (The column sl is what I have used in the stored procedure code)

Incorrect string value: 'xC2x80xC2x99t ...' for column 'sl' at row 1 at 
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946):946 at 
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985):2985 at 
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631):1631 at 
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723):1723 at 
com.mysql.jdbc.Connection.execSQL(Connection.java:3283):3283 at 

and so on..

存储过程代码,CODE II,从下面提到的CODE I调用:

The stored procedure code, CODE II which is getting called from CODE I mentioned below:

代码 II

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`mystuff`@`%` PROCEDURE `usp_sg_ins_fv3`(IN `na` BIGINT, IN `sb` VARCHAR(200), IN `sc` INT, IN `se` INT, IN `sf` VARCHAR(200), IN `sg` VARCHAR(200), IN `sh` VARCHAR(500), IN `si` VARCHAR(200), IN `dj` DATETIME, IN `sk` VARCHAR(200), IN `sl` VARCHAR(500), IN `sm` VARCHAR(200)

, IN `sn` VARCHAR(50))
BEGIN  
    INSERT INTO sgfDatav3
                (
                 a_bi, 
                 b_vc,
                 c_int,
                 e_int,
                 f_vc, 
                 g_vc, 
                 h_vc,
                 i_vc,
                 j_dt,
                 k_vc,
                 l_vc,
                 m_vc,
                 n,
                 myTimestamp_dt
               )
            VALUES
                (
                na,
                sb,
                sc,
                se,
                sf,
                sg,
                sh,
                si,
                dj,
                sk,
                sl,
                sm,
                sn,
                CURRENT_TIMESTAMP()
                );
END

代码 I:我用来获取 Sendgrid 发布的数据的代码

CODE I: Code which I am using to get the data posted by Sendgrid

<cftry>              
 <cfset incomingData = toString(getHttpRequestData().content) />
 <cfset djs = DeserializeJSON(incomingData)/>

<cfset a = "0">
<cfset b = "">
<cfset c = "0">
<cfset d = "0">
<cfset e = "">
<cfset f = "">
<cfset g = "">
<cfset h = "">
<cfset i = "">
<cfset k = "#NOW()#">
<cfset l = "">
<cfset m = "">
<cfset n = "">

<cfoutput>
<cfloop from="1" to="#arraylen(djs)#" index="i">

    <cfset a = "0">
    <cfset b = "">
    <cfset c = "0">
    <cfset d = "0">
    <cfset e = "">
    <cfset f = "">
    <cfset g = "">
    <cfset h = "">
    <cfset i = "">
    <cfset k = "#NOW()#">
    <cfset l = "">
    <cfset m = "">
    <cfset n = "">

    <cfif StructKeyExists(djs[i],'p')>
        <cfset a       = djs[i].p />
    </cfif>

    <cfif StructKeyExists(djs[i],'q')>
        <cfset b           = djs[i].q />
    </cfif>
    <cfif StructKeyExists(djs[i],'r')>
        <cfset c       = djs[i].r />
    </cfif>
    <cfif StructKeyExists(djs[i],'s')>
        <cfset d       = djs[i].s />
    </cfif>     
    <cfif StructKeyExists(djs[i],'t')>
        <cfset e       = djs[i].t />
    </cfif>
   <cfif StructKeyExists(djs[i],'u')>
        <cfset f           = djs[i].u />
    </cfif>
    <cfif StructKeyExists(djs[i],'v')>
        <cfset g       = djs[i].v />
    </cfif>

    <cfif StructKeyExists(djs[i],'w')>
        {                                                                         
        <cfset i  = djs[i].w />
        <cfset k  = dateAdd("s", i, createDateTime(1970, 1, 1, 0, 0, 0))/>
        }
    </cfif>
    <cfif StructKeyExists(djs[i],'x')>
        <cfset l         = djs[i].x />
    </cfif>
    <cfif StructKeyExists(djs[i],'y')>
        <cfset m       = djs[i].y />
    </cfif>
    <cfif StructKeyExists(djs[i],'z')>
        <cfset n       = djs[i].z /> 
    </cfif>

    <cfstoredproc procedure="sp1" datasource="db1">
        <cfprocparam cfsqltype="cf_sql_bigint" value="#a#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(b,199)#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#c#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#d#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(e,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(f,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(g,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(h,199)#">
        <cfprocparam cfsqltype="cf_sql_timestamp" value="#k#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(l,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#LEFT(m,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(n,99)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="XX.XX.X.XX">
    </cfstoredproc>
</cfloop>

</cfoutput>

</cftry>

经过研究,我发现人们在谈论一些 UTF8 格式.但如果那是实际问题,那我为什么会得到上述仅在少数情况下出错,而不是每次都出错?请指教.

Upon researching I found people talking about some UTF8 format. But if that is the actual problem, then why do I get the above error for only few cases and not every time? Please advise.

推荐答案

更新: 从 MySQL 5.5.3 开始,还有 UTF8mb4 通常比 UTF8 更推荐.

UPDATE: As of MySQL 5.5.3, there is also UTF8mb4 which is often recommended over UTF8.

听起来确实与 unicode 有关.该列的字符集和排序规则是什么?请参阅 INFORMATION_SCHEMA.COLUMNS 视图.

It does sound like it is related to unicode. What is the charset and collation for that column? See the INFORMATION_SCHEMA.COLUMNS view.

至于错误是零星的,我想这将取决于您插入的字符(可能会更改).严格遵守 错误消息描述,即er_truncated_wrong_value_for_field,听起来输入包含无效字符或输入字符串的解释被截断.同样,这听起来像是某种字符集问题.

As far as the error being sporadic, I imagine it would depend on exactly what characters you are inserting (which probably change). Going strictly off the error message description, ie er_truncated_wrong_value_for_field, it sounds like either the input contains invalid characters or the interpretation of the input string is being truncated. Again, it sounds like some sort of charset issue.

更新:

假设您收到一个有效的 UTF8 字符串,这似乎是一个字符集问题.尽管我的测试数据库默认为字符集 UTF8,但我能够通过创建一个使用两种不同字符集的小表来重现该错误:LATIN1 和 UTF8.然后在两列中插入一个小的 UTF8 字符串.插入 UTF8 列工作正常,但 LATIN1 列失败并出现错误:

Assuming you are receiving a valid UTF8 string, it does seem to be a charset problem. Though my test database defaults to charset UTF8, I was able to reproduce that error by creating a small table that used two different charsets: LATIN1 and UTF8. Then inserting a small UTF8 string into the both columns. The insert into the UTF8 column worked fine, but the LATIN1 column failed with the error:

不正确的字符串值:列的/xD0/x9D/xD0/xB0/xD0..."第 1 行的ColDefaultCharset"...

Incorrect string value: '/xD0/x9D/xD0/xB0 /xD0...' for column 'ColDefaultCharset' at row 1 ...

尝试将字符集更改为 UTF8,我认为 INSERT 会正常工作:

Try changing the charset to UTF8 and I think the INSERT will work correctly:

  ALTER TABLE YourTable MODIFY YourColumnName VARCHAR(500) CHARACTER SET utf8;

表格:

CREATE TABLE  TestTable (
  ID INTEGER NOT NULL AUTO_INCREMENT
  , ColDefaultCharset VARCHAR(100) CHARSET LATIN1 NULL
  , ColUTF8Charset VARCHAR(100) CHARSET UTF8 NULL
  , PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=LATIN1;

示例文本:

На берегу пустынных волн
Стоял он, дум великих полн,

程序:

CREATE PROCEDURE `testWithUTF8`
(
  IN `sl` VARCHAR(500)
)
BEGIN
    INSERT INTO testTable (ColUTF8Charset)
    VALUES ( sl );

END


CREATE PROCEDURE `testWithLatin1`
(
  IN `sl` VARCHAR(500)
)
BEGIN
    INSERT INTO testTable (ColDefaultCharset)
    VALUES ( sl );

END

代码:

<cfprocessingdirective pageEncoding="UTF8">
<cfsavecontent variable="text">
На берегу пустынных волн
Стоял он, дум великих полн,
</cfsavecontent>

<!--- Note: For CF10, use cf_sql_nvarchar --->
<cfstoredproc procedure="testWithUTF8" datasource="MySQL" result="procResult">
    <cfprocparam cfsqltype="cf_sql_varchar" value="#text#">
</cfstoredproc>
<cfdump var="#procResult#">

<cfstoredproc procedure="testWithLatin1" datasource="MySQL" result="procResult">
    <cfprocparam cfsqltype="cf_sql_varchar" value="#text#">
</cfstoredproc>
<cfdump var="#procResult#">

DSN 设置:

  • 驱动程序:MySQL 5
  • 高级设置 > 连接字符串:characterEncoding=UTF8

相关文章