这里有一点背景。我有一个使用SQL Server数据库的Java程序。这个Java程序在内部生成T-SQL:选择、更新、删除等。由于软件的新版本,数据库结构中时不时会出现新的列。在上一个版本中,DBA在一些表上添加了一些列。这些列以大写字母命名,但Java程序中的SQL语句使它们以小写字母命名。这是经过测试的,并且已经在生产环境中使用了大约100多台服务器。
但是有这样一个客户端,日志记录有一个错误的SQL语法,并且选择语句上的选择列不存在。问题是它确实存在。为了获得一些时间,我只是简单地并且只针对特定的客户端将列名更改为小写字母,并且问题得到了解决。
问题是这个解决方案没有效率,我仍然不知道为什么会出现那个问题。该程序的Java版本为jdk1.8.0_281,该客户端的SQL服务器为SQL server 2008 R2。(顺便说一下,还有其他客户端使用相同的版本没有任何问题。有客户端与所有以上版本的SQL Server工作正常) 日志详细信息:
org.springframework.jdbc。BadSqlGrammarException: PreparedStatementCallback;错误的SQL语法[SELECT * FROM table WHERE column1=?和column2 = ?column3 = ?和column4 = ?];嵌套异常是com.microsoft.sqlserver.jdbc.SQLServerException:无效列名'column1'.
有人知道发生了什么事吗?以及如何在不将列名更改为小写字母的情况下修复它?
这可能是由于数据库具有区分大小写的排序。快速演示:
create database foobar collate Latin1_General_CI_AI;
use foobar;
create table dbo.myTable (ID int);
select id from myTable;
/* succeeds because the database's collation is case-insensitive */
alter database foobar collate Latin1_General_CS_AI;
select id from myTable;
/* fails because the database's collation is now case-sensitive */
要检查您的数据库正在使用什么,请查看collation_name
列中的sys.databases
系统视图。这里有一个快速查询:
select d.name,
d.collation_name,
collation_description = c.[description]
from sys.databases as d
cross apply sys.fn_helpcollations() as c
where d.name = 'foobar'
and c.name = d.collation_name;
注意-通过省略数据库名称上的谓词,您可以获得实例上所有数据库的排序,从而允许您整体地解决问题(如果您确实想更改数据库的默认位置)。
同样与上面相关的是,更改默认数据库位置可能会对应用程序产生影响。在部署到生产环境之前进行彻底的测试。