我有一个Java函数来规范化一个字符串:
public static Object normalizeString(String source) {
if (source==null) return null;
String cleaned = source.replaceAll("[\\n\\r\\t]", "");
cleaned = Normalizer.normalize(cleaned, Normalizer.Form.NFD);
cleaned = cleaned.replaceAll("[^\\p{ASCII}]", ""); // on vire tout ce qui n'est pa ascii
cleaned = cleaned.strip();
return cleaned;
}
在我的应用程序中,我在两个地方调用它:
在升级SQL脚本中:
alter table entry add infostr1S VARCHAR_IGNORECASE null;
CREATE ALIAS normalizeString FOR "com.zparkingb.zploger.Compute.NormalizationSupport.normalizeString";
update entry set infostr1S = normalizeString(infostr1) where infostr1 is not null;
在AFTER INSERT和BEFORE UPDATE触发器中:
public class TriggerUpdateEntry implements Trigger {
// ...
public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException {
if (newRow == null) {
return;
}
// Normalisation of the searchable strings on INSERT et UPDATE
newRow[34] = NormalizationSupport.normalizeString((String) newRow[20]); //instr1
}
}
当TRIGGER正常工作时,UPDATE不工作:所有清理过的列都包含一个奇怪的字符串,看起来像“aced0005740011523230305f4475206c6f7572642e677078"。
[编辑]:更多关于它何时起作用,何时不起作用的调查:
- 在BEFORE UPDATE触发器激活的情况下,所有值都是正确的。
- 使用BEFORE UPDATE触发器dropped,所有值都不正确。
这意味着,IMO,
CREATE ALIAS normalizeString FOR "com.zparkingb.zploger.Compute.NormalizationSupport.normalizeString";
update entry set infostr1S = normalizeString(infostr1) where infostr1 is not null;
不能正常工作。
这是否与调用脚本或定义函数的方式有关?
for (Path scriptPath : scripts) {
try (Statement st = archive.getConnection().createStatement()) {
logger.info("Executing update script " + scriptPath);
st.execute("RUNSCRIPT FROM '" + scriptPath + "'");
logger.debug("Script " + scriptPath + " executed");
} catch (SQLException ex) {
throw new DBException("Execution of script " + scriptPath + " failed", ex);
}
}
有没有人已经遇到过这种情况?
PS:我使用的是H2.1.4.196(最新版本的旧文件格式)和Java 11
1条答案
按热度按时间t3irkdon1#
该错误是由返回签名为
Object
的归一化函数引起的。当从java调用时,没有问题,因为实际返回类型是
String
。但是,当从H2作为别名函数调用时,Object
返回签名会使H2感到困惑,然后将值序列化为“aced000574001152323030”类型的字符串。将返回签名显式更改为
String
可以防止混淆并解决问题: