在我继承的项目中,有一个准备好的语句定义为:
<select id="GET_FILE_BY_FILE_ID" parameterType="long" resultType="com.employer.my.File" statementType="PREPARED">
SELECT
file_id fileId,
file_name name,
file_type type,
CASE WHEN file_data_long is null THEN convert (image, file_data_short) ELSE file_data_long END AS fileData
FROM FILES_TABLE
WHERE file_id = #{id}
</select>
此 SQL 语句在运行时运行良好,带有 Sybase ASE
数据库。
但是执行它的 JUnit(作为构建的一部分)不断失败
java.sql.SQLSyntaxErrorException: type not found or user lacks privilege: FILE_DATA_SHORT
我将此错误跟踪到 CASE THEN 转换语句:
CASE WHEN file_data_long is null THEN convert (image, file_data_short) ELSE file_data_long END AS fileData
也就是说,以下准备好的语句不会产生所述错误:
<select id="GET_FILE_BY_FILE_ID" parameterType="long" resultType="com.employer.my.File" statementType="PREPARED">
SELECT
file_id fileId,
file_name name,
file_type type,
file_data_short fileData
FROM FILES_TABLE
WHERE file_id = #{id}
</select>
怀疑这可能与convert
有关,我遇到了this SO answer这表明要使用非 HSQLDB 方言运行 HSQLDB,必须首先在 HSQLDB 上启用该语法兼容模式。
在 this SO answer 中发现了类似的提示.
这样我就可以在 the hsqldb.org doc 中找到 Sybase 特定指令。 :
“使用 SET DATABASE SQL SYNTAX MSS TRUE 或等效的 URL 属性 sql.syntax_mss=true 启用对 CONVERT(<type definition>, <expression)
函数(参数顺序已切换)的支持”
嗯,我就是这样做的,添加 sql.syntax_mss=true
到项目的 HSDLDB 属性:
HSQLDB(org.hsqldb.jdbc.JDBCDriver.class, org.hsqldb.jdbc.JDBCDataSource.class, "jdbc:hsqldb:mem:mymemdb;sql.syntax_mss=true", new TestMapperHsqlDB(), true)
但这并没有帮助:在运行 JUnit 测试时我仍然遇到可怕的异常(只有那时。该查询在运行时或从 DBeaver 运行良好)。
您知道在尝试使此功能同时适用于运行时 (Sybase/ASE) 和 JUnit (HSDLDB) 时我可能会遗漏什么吗?
最佳答案
回答我自己的问题,为了那些可能因类似遭遇而困惑的其他人的利益:
尝试语法/方言修饰符(参见OP)后,我发现this list of HSQLDB built it in functions ,其中“image”不是 HSQLDB 支持的类型,因此 convert
没有成功的机会...
这促使我寻找一种解决方案/解决方法,其中 SQL 本身会根据运行它的数据库而略有不同:
<select id="GET_FILE_BY_FILE_ID" parameterType="long" resultType="com.employer.my.File" statementType="PREPARED">
SELECT
file_id fileId,
file_name name,
file_type type,
<if test="_databaseId == 'SYBASE'">
CASE WHEN file_data_long is null THEN convert (image, file_data_short) ELSE file_data_long END AS fileData
</if>
<if test="_databaseId == 'HSQLDB'">
CASE WHEN FFT.file_data_long is null THEN FFT.file_data_short ELSE FFT.file_data_long END AS fileData
</if>
FROM FILES_TABLE FFT
WHERE file_id = #{id}
</select>
这就像一个魅力。
关于java - Sybase ASE 到 HSQLDB JUnit java.sql.SQLSyntaxErrorException : type not found or user lacks privilege,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49976982/