mdr*_*drg 9 java oracle bigdecimal oracle10g ora-01438
在我的应用程序中,我将数字处理为BigDecimal并将它们存储为NUMBER(15,5).现在我需要正确检查Java是否BigDecimal值适合列,以便我可以生成正确的错误消息而不执行SQL,捕获异常并验证供应商错误代码.我的数据库是Oracle 10.3,这样的错误导致错误1438.
经过一些谷歌搜索,我发现没有这样的代码,所以我想出了自己的.但是我对这段代码真的不满意......很简单,但同时又简单到足以怀疑它的正确性.我用很多值,随机和边界测试它,它似乎工作.但是由于我对数字非常不满意,我想要一些更强大且经过良好测试的代码.
//no constants for easier reading
public boolean testBigDecimal(BigDecimal value) {
if (value.scale() > 5)
return false;
else if (value.precision() - value.scale() > 15 - 5)
return false;
else
return true;
}
Run Code Online (Sandbox Code Playgroud)
编辑:最近的测试没有超出规模的数字的例外,只是默默地舍入,我不知道没有和我做这些第一次测试之间有什么不同.这样的舍入是不可接受的,因为应用程序是财务的,并且任何舍入/截断必须是显式的(通过BigDecimal方法).除了例外之外,这种测试方法必须确保数字对于期望的精度而言不是太大,即使是非有效数字.对于迟到的澄清感到抱歉.
谢谢你的时间.
我仍然对这个问题感到好奇.我的代码仍在运行,我没有得到正确或失败情况的一些"证据",或者这种测试的一些标准代码.
所以,我正在给它一个赏金,希望得到任何这些.
以下正则表达式也可以解决问题:
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static void main(String[] args) {
BigDecimal b = new BigDecimal("123123.12321");
Matcher m = p.matcher(b.toString());
System.out.println(b.toString() + " is valid = " + m.matches());
}
}
Run Code Online (Sandbox Code Playgroud)
这可能是测试代码的另一种方法,也可能是代码.正则表达式需要0到10位数之间,可选地后跟一个小数点和0到5位数.我不知道是否需要一个标志,就像我想的那样.像[+-]{0,1}
前面这样的东西可以做到.
这是一个更好的类,也许是一个带有部分测试集的测试类.
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static boolean isValid(String s) {
BigDecimal b = new BigDecimal(s);
Matcher m = p.matcher(b.toPlainString());
return m.matches();
}
}
Run Code Online (Sandbox Code Playgroud)
package thop;
import junit.framework.TestCase;
/**
* Created by IntelliJ IDEA.
* User: tonyennis
* Date: Sep 22, 2010
* Time: 6:01:15 PM
* To change this template use File | Settings | File Templates.
*/
public class BigTest extends TestCase {
public void testZero1() {
assertTrue(Big.isValid("0"));
}
public void testZero2() {
assertTrue(Big.isValid("0."));
}
public void testZero3() {
assertTrue(Big.isValid("0.0"));
}
public void testZero4() {
assertTrue(Big.isValid(".0"));
}
public void testTooMuchLeftSide() {
assertFalse(Big.isValid("12345678901.0"));
}
public void testMaxLeftSide() {
assertTrue(Big.isValid("1234567890.0"));
}
public void testMaxLeftSide2() {
assertTrue(Big.isValid("000001234567890.0"));
}
public void testTooMuchScale() {
assertFalse(Big.isValid("0.123456"));
}
public void testScientificNotation1() {
assertTrue(Big.isValid("123.45e-1"));
}
public void testScientificNotation2() {
assertTrue(Big.isValid("12e4"));
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,由于没有人提出其他解决方案,我将保留代码不变。
我无法使这个精度/规模测试失败,并且它总是与正则表达式解决方案匹配,所以也许两者都是正确的(我测试了边界并使用超过 5M 的随机生成的值)。我将使用精度/比例解决方案,因为它的速度快了 85% 以上,如果它失败,我将替换它。
感谢您的回复托尼。
我之前的“答案”,出于历史目的仍然在这里,但我正在寻找真正的答案=)
归档时间: |
|
查看次数: |
8621 次 |
最近记录: |