Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java sql查询中的外来/重音字符_Java_Postgresql_Character Encoding_Spring - Fatal编程技术网

Java sql查询中的外来/重音字符

Java sql查询中的外来/重音字符,java,postgresql,character-encoding,spring,Java,Postgresql,Character Encoding,Spring,我正在使用Java和Spring的JdbcTemplate类在Java中构建一个查询Postgres数据库的SQL查询。但是,我在执行包含外来/重音字符的查询时遇到问题 例如,(修剪过的)代码: 将检索省id,但如果我取而代之的是name='魁北克',则查询将无法返回任何结果(该值在数据库中,因此问题不是缺少该值) 我相信问题的根源在于我需要使用的数据库的默认客户机编码设置为SQL_ASCII,这会阻止自动字符集转换。(Java环境编码设置为“UTF-8”,而我被告知数据库使用“LATIN1”/

我正在使用Java和Spring的JdbcTemplate类在Java中构建一个查询Postgres数据库的SQL查询。但是,我在执行包含外来/重音字符的查询时遇到问题

例如,(修剪过的)代码:

将检索省id,但如果我取而代之的是
name='魁北克'
,则查询将无法返回任何结果(该值在数据库中,因此问题不是缺少该值)

我相信问题的根源在于我需要使用的数据库的默认客户机编码设置为SQL_ASCII,这会阻止自动字符集转换。(Java环境编码设置为“UTF-8”,而我被告知数据库使用“LATIN1”/“ISO-8859-1”)

当结果集包含带有外来字符的值时,我能够手动指示编码,这是对以前类似性质问题的解决方案

例:

但是现在外来字符是查询本身的一部分,这种方法并没有成功。(我认为,由于查询在执行之前必须保存为字符串,因此将其分解为字节,然后更改编码只会进一步混淆字符。)

有没有一种方法可以解决这个问题,而不必更改数据库的属性或重建它

附言:我在StackOverflow上发现,在编写标题时,它似乎不起作用(我可能没有正确使用它,但即使它起作用,它似乎也不是最好的解决方案):


编辑:我已经选择了我自己的答案,因为它将是我现在使用的;但是,正如下面的评论中所提到的,只要我有权访问数据库,我很乐意考虑其他可能更好的建议。

事实上,如果您的数据库是“SQL\U ASCII”编码的,它基本上理解ASCII,而不理解其他内容。这意味着“魁北克”一词已“按规定”存储,意思是“根据此时处理数据库插入或更新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 );

嗯,好吧,在仔细阅读了postgreSQL文档之后,我在这一部分找到了一个解决方案

我使用了
convert(stringbytea、src\u编码名称、dest\u编码名称)
函数,并设法获得魁北克省的省id


如果您是从编码为UTF-8的Java连接,并且数据库是ISO-8859-1,那么您应该在最初连接到数据库之后运行此SQL命令:

SET client_encoding = 'UTF8';

PostgreSQL随后将所有输入解释为UTF-8,然后在服务器端将其转换为ISO-8859-1。除此之外,你不必做任何事情。

谢谢。我只能包含一个链接,因为我没有足够的信誉点x。xif db只使用
ISO-8859-1
编码,它是如何存储
魁北克省的
?ISO-8859-1存储口音没有问题,它覆盖了一组字符。目前它的数据库使用US-ASCII(我想现在是ASCII8),所以这意味着在给定的初始编码(希望是ISO8859)中表示单词“魁北克”的字节序列按原样存储。如果你想长期避免这种无意义的话,你真的应该修复数据库的服务器编码。嗯,我试过了,但没有得到任何结果。甚至尝试了“UTF-8”。(我假设您打算使用“myReqAscii”作为查询,而不是“query”)。尽管如此,我还是会修复所有层,使其始终使用UTF-8,或者至少使用支持应用程序处理的所有字符的一种相同字符编码(可能ISO-8859-1就足够了)。使用SQL函数和/或编程解决方法来处理字符串只会使其变得繁琐、不可维护和不可移植。我同意最好的方法是对所有层使用相同的字符编码,但我无法控制数据库,因此我必须按原样使用它。我写的这段代码是一个更大项目的一部分,如果我们同意将UTF-8用于所有其他目的的话。虽然我只是一名co-op的学生,所以我并不真的质疑这个决定,但我想我总能看到它是否绝对必要。如果其他人需要将数据库用于其他应用程序,这会导致问题吗?如果您手动将其设置为这样(即不是在postgresql.conf文件中作为默认值),然后,它仅在该特定会话/连接中处于活动状态。我能看到的唯一可能导致问题的情况是,如果您在多个应用程序之间共享一个数据库连接池,这些应用程序混合了拉丁语-1和UTF-8。我尝试了,但出现了以下错误:
服务器的client_编码参数更改为UTF8。JDBC驱动程序要求客户端_编码为UNICODE才能正确运行。
将其更改为UNICODE会停止错误,但同样的问题仍然存在,即无法获取id。好的,我没有意识到JDBC现在会将更改客户端_编码检测为错误。此外,“UNICODE”和“UTF8”在PostgreSQL方面是相同的,所以它不应该有什么区别。我将不得不进一步考虑这一点……好吧,我已经找到了完成工作的方法,所以不要让它给你带来太多麻烦。不过,我很乐意测试您希望提出的任何其他建议。
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 );
String query = "SELECT id FROM province WHERE name = convert( 'Québec', 'UTF-8', 'ISO-8859-1' );"; 
SET client_encoding = 'UTF8';