问题描述
我正在尝试将旧应用程序从 HsqlDB 1.8.0.10 迁移到最新版本 2.5.1。
一切顺利,但旧应用程序为静态 Java 方法添加了两个 <View style={styles.action}>
<FontAwesome name="user-o" color="#05375a" size={24} />
<TextInput placeholder="Your Full Name" style={styles.textInput} autoCapitalize="none" onCh</View>
<Text style={styles.textFooter}>Email</Text>
<View style={styles.action}>
<MaterialIcons name="alternate-email" color="#05375a" size={24} />
<TextInput placeholder="Entered Automatically" style={styles.textInput} editable={false} selectTextOnFocus={false} value={fullName.replace(/\s/g,'.') + '@sameemail.com'} onChangeText={text => setEmail({ fullName },{ text })} />
</View>
:
ALIAS
与
statement.execute("CREATE ALIAS BigBitAnd FOR \"org.somedomain.ClassName.bigBitAnd\"");
statement.execute("CREATE ALIAS BigMod FOR \"org.somedomain.ClassName.bigMod\"");
我尝试将其转换为函数定义,如下所示:
public static long bigBitAnd(long a,long b) {
return a & b;
}
public static long bigMod(long a,long b) {
return a % b;
}
函数已成功创建,但当它们通过 statement.execute("CREATE FUNCTION BIGBITAND(a BIGINT,b BIGINT) RETURNS BIGINT LANGUAGE JAVA DETERMINISTIC NO sql EXTERNAL NAME 'CLAsspATH:org.somedomain.ClassName.bigBitAnd'");
statement.execute("CREATE FUNCTION BIGBITAND(a BIGINT,b BIGINT) RETURNS BIGINT LANGUAGE JAVA DETERMINISTIC NO sql EXTERNAL NAME 'CLAsspATH:org.somedomain.ClassName.bigMod'");
应用于任何语句时,查询失败并显示“一般错误”(S1000)。谷歌搜索告诉我这可能是因为某处的 NumberFormatException 发生的。
出于测试目的,我还尝试了 hsqldb 2.3.6。由于 NullPointerException,它也因“一般错误”而失败。
我的函数声明是否有问题,或者函数调用与 hsql 1.8 别名不同?
更新:我尝试用 PreparedStatement.executeQuery()
调用替换所有出现的 BIGBITAND
,错误不再发生。但是,这会导致其他问题,因为据我所知,BIGAND
不适用于 BIGAND
。
BIGINT
自定义函数似乎不会导致一般错误。
更新 2:使用 HsqlDB 2.4.0 版,我获得了更详细的堆栈跟踪:
BIGMOD
解决方法
我找到了一个解决方法:
准备将 ?
占位符作为函数参数的语句时,HSQLDB 连接器尝试解析 ?
占位符的类型,但失败了。
一种解决方法是在准备语句之前手动替换 ?
占位符。不是很干净,但至少它有效。
有时无法正确确定 CASEWHEN 表达式的类型或类型不完全正确。您始终可以将函数参数(包括变量占位符 ?
)转换为您需要的类型。例如:
BIGBITAND(CAST( CASEWHEN(BIGMOD(p.val,2)=0,p.val+1,p.val-1) AS BIGINT),CAST(? AS BIGINT) ) != 0
附言非特定的“一般错误”是在引擎报告实际错误时引起的,即:"routine signature not found for: PUBLIC.BIGBITAND(DECIMAL,null) in statement .."
。由于自动类型扩展,表达式 p.val+1
的数据类型为 DECIMAL。这会导致引擎查找不存在的例程签名。