我正在使用Java和Spring的JdbcTemplate类在Java中构建一个查询Postgres数据库的SQL查询。但是,我在执行包含外来/重音字符的查询时遇到问题。
例如(修剪)代码:
JdbcTemplate select = new JdbcTemplate( postgresDatabase );
String query = "SELECT id FROM province WHERE name = 'Ontario';";
Integer id = select.queryForObject( query, Integer.class );
将检索省id,但如果我做了name = 'Québec'
,那么查询将无法返回任何结果(此值在数据库中,因此问题不在于它丢失)。
我认为问题的根源是我需要使用的数据库将默认客户端编码设置为SQL_ASCII,根据this,它会阻止自动字符集转换。 (Java环境编码设置为'UTF-8',而我被告知数据库使用'LATIN1'/'ISO-8859-1')
当resultSets包含带有外来字符的值作为上一个具有类似性质的问题的解决方案时,我能够手动指示编码。
例如:
String provinceName = new String ( resultSet.getBytes( "name" ), "ISO-8859-1" );
但是现在外来字符是查询本身的一部分,这种方法还没有成功。 (我想,因为查询必须在执行之前保存在String中,然后将其分解为字节,然后更改编码只会使字符进一步混乱。)
有没有办法绕过这个而不必更改数据库的属性或重建它?
PostScript:我在编写标题时在StackOverflow上找到this function,它似乎不起作用(我可能没有正确使用它,但即使它确实有效,它似乎也不会是最好的解决方案。):
编辑:我已经为此选择了自己的答案,因为它将是我现在使用的;但是,如下面的评论所述,我很乐意看到其他可能更好的建议,只要我有权访问数据库。
答案 0 :(得分:3)
如果从Java连接编码UTF-8并且数据库是ISO-8859-1,那么您应该在最初连接到DB之后运行此SQL命令:
SET client_encoding = 'UTF8';
PostgreSQL然后将所有输入解释为UTF-8,然后在服务器端将其转换为ISO-8859-1。你不应该做那些事情。
答案 1 :(得分:2)
嗯好吧,在浏览了postgreSQL文档之后,我在String Functions and Operators部分找到了一个解决方案。
我使用convert(string bytea, src_encoding name, dest_encoding name)
功能并设法获得魁北克省的省ID。
实施例
String query = "SELECT id FROM province WHERE name = convert( 'Québec', 'UTF-8', 'ISO-8859-1' );";
答案 2 :(得分:0)
实际上,如果您的数据库是“SQL_ASCII”编码的,它基本上理解ASCII而不是其他任何东西。这意味着“Québec”这个词已经“按照提供”存储,意思是“按照一组字节提供,根据此时处理插入或更新sql命令的工具所使用的编码”。因此,当您尝试选择此类值时,必须使用相同的编码,但您必须事先知道它是哪一个。
处理完第一个问题后,您需要一种方法来表达您的请求应该使用此编码。
假设它已经存储了ISO-8859-1编码。
我不确定它是否可行,但我会尝试这样的事情:
String myReq = "SELECT id FROM province WHERE name = 'Québec';";
byte[] iso8859sequence = myReq.getBytes("ISO-8859-1");
String myReqAscii = new String(iso8859sequence, "US-ASCII");
Integer id = select.queryForObject( query, Integer.class );