【问题标题】:Sybase ASE to HSQLDB JUnit java.sql.SQLSyntaxErrorException: type not found or user lacks privilegeSybase ASE 到 HSQLDB JUnit java.sql.SQLSyntaxErrorException:找不到类型或用户缺少权限
【发布时间】:2018-10-03 06:10:16
【问题描述】:

在我继承的一个项目中,有一个prepared statement定义为:

<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 convert 语句:

    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(&lt;type definition&gt;, &lt;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) 时我还缺少什么吗?

【问题讨论】:

    标签: java junit prepared-statement hsqldb sap-ase


    【解决方案1】:

    回答我自己的问题,以帮助可能对类似遭遇感到困惑的其他人:

    在尝试语法/方言修饰符(参见 OP)后,我发现 this list of HSQLDB built it in functions,其中“图像”不是 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>
    

    而这——就像一个魅力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-06
      • 2019-01-15
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      相关资源
      最近更新 更多