开发者社区> 问答> 正文

PostgreSQL,SQL_ASCII转码问题.

数据库的字符编码为SQL_ASCII,
客户端的字符编码为UTF8,
通过Npgsql写入时数据库中出现中文乱码,

我看api上说SQL_ASCII不验证字符格式的吗,写什么存什么,不知道为什么会自动转成乱码呢,
第一次使用PostgreSQL,跟别的公司做接口,他们提供的数据库字符编码就是SQL_ASCII,还不能更改.
有什么办法解决乱码问题吗.

展开
收起
一纸荒年丶 2016-03-20 12:20:17 12081 0
1 条回答
写回答
取消 提交回答
  • 公益是一辈子的事, I am digoal, just do it. 阿里云数据库团队, 擅长PolarDB, PostgreSQL, DuckDB, ADB等, 长期致力于推动开源数据库技术、生态在中国的发展与开源产业人才培养. 曾荣获阿里巴巴麒麟布道师称号、2018届OSCAR开源尖峰人物.

    首先不建议使用SQL_ASCII作为服务端的编码。
    因为你必须知道存进去的是什么编码,才能解出来。并且有些编码是存不进去的(例如编码中用到了sql_ascii中的转义码的)

    插入数据:
    sql_ascii作为服务端编码时

    1. 服务端存储的是客户端的编码,不进行转码。
    2. 当客户端编码不是sql_ascii时,有可能能存进去,也有可能存不进去。(编码中用到了sql_ascii中的转义码的存不进去)

    sql_ascii作为客户端编码时

    1. 服务端不进行编码合法性检测,服务端不进行编码转换,直接存数据库中.

    取数据:
    sql_ascii作为服务端编码时

    1. 当需要提取存储在sql_ascii编码数据库中的数据时,必须以原编码去取,否则可能出现乱码。

    sql_ascii作为客户端编码时

    1. 直接返回,不进行编码检测和转换.

    合法性检测代码如下:

    /*
     * Convert any encoding to server encoding.
     *
     * See the notes about string conversion functions at the top of this file.
     *
     * Unlike the other string conversion functions, this will apply validation
     * even if encoding == DatabaseEncoding->encoding.  This is because this is
     * used to process data coming in from outside the database, and we never
     * want to just assume validity.
     */
    char *
    pg_any_to_server(const char *s, int len, int encoding)
    {
            if (len <= 0)
                    return (char *) s;              /* empty string is always valid */
    
            if (encoding == DatabaseEncoding->encoding ||
                    encoding == PG_SQL_ASCII)
            {
                    /*
                     * No conversion is needed, but we must still validate the data.
                     */
                    (void) pg_verify_mbstr(DatabaseEncoding->encoding, s, len, false);
                    return (char *) s;
            }
    
            if (DatabaseEncoding->encoding == PG_SQL_ASCII)
            {
                    /*
                     * No conversion is possible, but we must still validate the data,
                     * because the client-side code might have done string escaping using
                     * the selected client_encoding.  If the client encoding is ASCII-safe
                     * then we just do a straight validation under that encoding.  For an
                     * ASCII-unsafe encoding we have a problem: we dare not pass such data
                     * to the parser but we have no way to convert it.  We compromise by
                     * rejecting the data if it contains any non-ASCII characters.
                     */
                    if (PG_VALID_BE_ENCODING(encoding))
                            (void) pg_verify_mbstr(encoding, s, len, false);
                    else
                    {
                            int                     i;
    
                            for (i = 0; i < len; i++)
                            {
                                    if (s[i] == '\0' || IS_HIGHBIT_SET(s[i]))
                                            ereport(ERROR,
                                                            (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
                                             errmsg("invalid byte value for encoding \"%s\": 0x%02x",
                                                            pg_enc2name_tbl[PG_SQL_ASCII].name,
                                                            (unsigned char) s[i])));
                            }
                    }
                    return (char *) s;
            }
    
            /* Fast path if we can use cached conversion function */
            if (encoding == ClientEncoding->encoding)
                    return perform_default_encoding_conversion(s, len, true);
    
            /* General case ... will not work outside transactions */
            return (char *) pg_do_encoding_conversion((unsigned char *) s,
                                                                                              len,
                                                                                              encoding,
                                                                                              DatabaseEncoding->encoding);
    }
    2019-07-17 18:34:58
    赞同 1 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖大会:开源 PolarDB 架构演进、关键技术与社区建设 立即下载
2023云栖大会:和客户一起玩转PolarDB新特性 立即下载
2023云栖大会:PolarDB for AI 立即下载