May be my question is silly, But I didn\'t find any Solution for this. Actually, I want to Store Big Price Amount i.e.
9999999999.99
The defined column type affinity TEXT
, REAL
, NUMERIC
, VARCHAR
, RUMPLESTILTSKIN
(yes it works), has little impact; the exception being if the type is either INTEGER PRIMARY KEY
or INTEGER PRIMARY KEY AUTOINCREMENT
in which case the column is an alias of the SQLITE column rowid and cannot be used. ROWIDs and the INTEGER PRIMARY KEY
Basically any column, except a rowid, can store any type of value as per
Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class. Datatypes In SQLite Version 3
The link also explains how column types are converted to one of the 5 column types :-
RuMpleStilskin (case independent) will be converted to NUMERIC, as per :-
What is of primary importance is how you retrieve the data, although the column's affinity can affect how the data is stored (the storage class) as per :-
A column with TEXT affinity stores all data using storage classes NULL, TEXT or BLOB. If numerical data is inserted into a column with TEXT affinity it is converted into text form before being stored.
A column with NUMERIC affinity may contain values using all five storage classes. When text data is inserted into a NUMERIC column, the storage class of the text is converted to INTEGER or REAL (in order of preference) if such conversion is lossless and reversible. For conversions between TEXT and REAL storage classes, SQLite considers the conversion to be lossless and reversible if the first 15 significant decimal digits of the number are preserved. If the lossless conversion of TEXT to INTEGER or REAL is not possible then the value is stored using the TEXT storage class. No attempt is made to convert NULL or BLOB values.
A string might look like a floating-point literal with a decimal point and/or exponent notation but as long as the value can be expressed as an integer, the NUMERIC affinity will convert it into an integer. Hence, the string '3.0e+5' is stored in a column with NUMERIC affinity as the integer 300000, not as the floating point value 300000.0.
A column that uses INTEGER affinity behaves the same as a column with NUMERIC affinity. The difference between INTEGER and NUMERIC affinity is only evident in a CAST expression.
A column with REAL affinity behaves like a column with NUMERIC affinity except that it forces integer values into floating point representation. (As an internal optimization, small floating point values with no fractional component and stored in columns with REAL affinity are written to disk as integers in order to take up less space and are automatically converted back into floating point as the value is read out. This optimization is completely invisible at the SQL level and can only be detected by examining the raw bits of the database file.)
A column with affinity BLOB does not prefer one storage class over another and no attempt is made to coerce data from one storage class into another. Datatypes In SQLite Version 3
For floating point or double you should retrieve the data using the Cursor
methods getFloat
or getDouble
and then format the result, if converting it to a string, accordingly.
Note! this assumes that the flaws/loss of precision with double or float are not relevant.
If you store the value as a string and the column affinity is TEXT or BLOB then the result is loss-less and is perhaps the best way to store large (see results to determine what is large) numbers.
Consider a table with 5 columns defined with column types/affinities REAL, TEXT, INTEGER, NUMERIC and BLOB
as per :-
CREATE TABLE prices (
_id INTEGER PRIMARY KEY,
PRICE1 REAL,
PRICE2 TEXT,
PRICE3 INTEGER,
PRICE4 NUMERIC,
PRICE5 BLOB
)
Now consider these 3 basic methods to - a) insert a double value into all 5 PRICE? columns - b) insert a string value into all 5 PRICE? columns - c) get all rows as a cursor :-
public void insertRowFromDouble(double price) {
ContentValues cv = new ContentValues();
cv.put(PRICES_PRICE1_COL,price);
cv.put(PRICES_PRICE2_COL,price);
cv.put(PRICES_PRICE3_COL,price);
cv.put(PRICES_PRICE4_COl,price);
cv.put(PRICES_PRICE5_COL,price);
mDB.insert(TBNAME,null,cv);
}
public void insertRowFromString(String price) {
ContentValues cv = new ContentValues();
cv.put(PRICES_PRICE1_COL,price);
cv.put(PRICES_PRICE2_COL,price);
cv.put(PRICES_PRICE3_COL,price);
cv.put(PRICES_PRICE4_COl,price);
cv.put(PRICES_PRICE5_COL,price);
mDB.insert(TBNAME,null,cv);
}
public Cursor getAllRows() {
return mDB.query(TBNAME,null,null,null,null,null,null);
}
and then consider the following code, which :-
getDouble
method formatted according to the DecimalFormat
and then the getString
method.:-
final DecimalFormat df = new DecimalFormat("#0.000000");
mDBPricesHlpr = new PriceDBHelper(this);
mDBPricesHlpr.getWritableDatabase().delete(PriceDBHelper.TBNAME,null,null);
mDBPricesHlpr.insertRowFromDouble(999999999999999999999999999999999999999.99);
mDBPricesHlpr.insertRowFromDouble(12345678901.123456);
mDBPricesHlpr.insertRowFromDouble(9999999999.99);
mDBPricesHlpr.insertRowFromDouble(0.01);
mDBPricesHlpr.insertRowFromDouble(45678.45);
mDBPricesHlpr.insertRowFromString("999999999999999999999999999999999999999999999999999999999999999999999999999.99");
mDBPricesHlpr.insertRowFromString("12345678901.123456");
mDBPricesHlpr.insertRowFromString("8888888888.88");
mDBPricesHlpr.insertRowFromString("0.02");
mDBPricesHlpr.insertRowFromString("56789.56");
Cursor csr = mDBPricesHlpr.getAllRows();
while (csr.moveToNext()) {
Log.d("PRICEINFO_GETDBL"," Processing Row " + csr.getPosition() +
"\n\tPRICE1=" + df.format(csr.getDouble(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE1_COL))) +
"\n\tPRICE2=" + df.format(csr.getDouble(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE2_COL))) +
"\n\tPRICE3=" + df.format(csr.getDouble(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE3_COL))) +
"\n\tPRICE4=" + df.format(csr.getDouble(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE4_COl))) +
"\n\tPRICE5=" + df.format(csr.getDouble(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE5_COL)))
);
Log.d("PRICEINFO_GETSTR", " Processing Row " + csr.getPosition() +
"\n\tPRICE1=" + csr.getString(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE1_COL)) +
"\n\tPRICE2=" + csr.getString(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE2_COL)) +
"\n\tPRICE3=" + csr.getString(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE3_COL)) +
"\n\tPRICE4=" + csr.getString(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE4_COl)) +
"\n\tPRICE5=" + csr.getString(csr.getColumnIndex(PriceDBHelper.PRICES_PRICE5_COL))
);
}
The resultant output is :-
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 0
PRICE1=1000000000000000000000000000000000000000.000000
PRICE2=1000000000000000000000000000000000000000.000000
PRICE3=1000000000000000000000000000000000000000.000000
PRICE4=1000000000000000000000000000000000000000.000000
PRICE5=1000000000000000000000000000000000000000.000000
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 0
PRICE1=1e+39
PRICE2=1.0e+39
PRICE3=1e+39
PRICE4=1e+39
PRICE5=1e+39
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 1
PRICE1=12345678901.123500
PRICE2=12345678901.123500
PRICE3=12345678901.123500
PRICE4=12345678901.123500
PRICE5=12345678901.123500
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 1
PRICE1=1.23457e+10
PRICE2=12345678901.1235
PRICE3=1.23457e+10
PRICE4=1.23457e+10
PRICE5=1.23457e+10
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 2
PRICE1=9999999999.990000
PRICE2=9999999999.990000
PRICE3=9999999999.990000
PRICE4=9999999999.990000
PRICE5=9999999999.990000
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 2
PRICE1=1e+10
PRICE2=9999999999.99
PRICE3=1e+10
PRICE4=1e+10
PRICE5=1e+10
01-11 10:39:30.626 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 3
PRICE1=0.010000
PRICE2=0.010000
PRICE3=0.010000
PRICE4=0.010000
PRICE5=0.010000
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 3
PRICE1=0.01
PRICE2=0.01
PRICE3=0.01
PRICE4=0.01
PRICE5=0.01
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 4
PRICE1=45678.450000
PRICE2=45678.450000
PRICE3=45678.450000
PRICE4=45678.450000
PRICE5=45678.450000
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 4
PRICE1=45678.4
PRICE2=45678.45
PRICE3=45678.4
PRICE4=45678.4
PRICE5=45678.4
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 5
PRICE1=1000000000000000000000000000000000000000000000000000000000000000000000000000.000000
PRICE2=1000000000000000000000000000000000000000000000000000000000000000000000000000.000000
PRICE3=1000000000000000000000000000000000000000000000000000000000000000000000000000.000000
PRICE4=1000000000000000000000000000000000000000000000000000000000000000000000000000.000000
PRICE5=1000000000000000000000000000000000000000000000000000000000000000000000000000.000000
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 5
PRICE1=1e+75
PRICE2=999999999999999999999999999999999999999999999999999999999999999999999999999.99
PRICE3=1e+75
PRICE4=1e+75
PRICE5=999999999999999999999999999999999999999999999999999999999999999999999999999.99
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 6
PRICE1=12345678901.123500
PRICE2=12345678901.123500
PRICE3=12345678901.123500
PRICE4=12345678901.123500
PRICE5=12345678901.123500
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 6
PRICE1=1.23457e+10
PRICE2=12345678901.123456
PRICE3=1.23457e+10
PRICE4=1.23457e+10
PRICE5=12345678901.123456
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 7
PRICE1=8888888888.880000
PRICE2=8888888888.880000
PRICE3=8888888888.880000
PRICE4=8888888888.880000
PRICE5=8888888888.880000
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 7
PRICE1=8.88889e+09
PRICE2=8888888888.88
PRICE3=8.88889e+09
PRICE4=8.88889e+09
PRICE5=8888888888.88
01-11 10:39:30.630 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 8
PRICE1=0.020000
PRICE2=0.020000
PRICE3=0.020000
PRICE4=0.020000
PRICE5=0.020000
01-11 10:39:30.634 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 8
PRICE1=0.02
PRICE2=0.02
PRICE3=0.02
PRICE4=0.02
PRICE5=0.02
01-11 10:39:30.634 3680-3680/? D/PRICEINFO_GETDBL: Processing Row 9
PRICE1=56789.560000
PRICE2=56789.560000
PRICE3=56789.560000
PRICE4=56789.560000
PRICE5=56789.560000
01-11 10:39:30.634 3680-3680/? D/PRICEINFO_GETSTR: Processing Row 9
PRICE1=56789.6
PRICE2=56789.56
PRICE3=56789.6
PRICE4=56789.6
PRICE5=56789.56
So :-
For row 0 (999999999999999999999999999999999999999.99 stored via a double) using getDouble the column type is insignificant, but for getString there is a subtle difference when the column type is TEXT. However, precision loses the value (see caveat above).
For row 1 (12345678901.123500 stored via a double) getDouble is fine for 15 significant figures. With getString all but the TEXT column lose out due to precision loss.
For row 2 (9999999999.99 stored via a double) is very much the same findings as for row 1.
For row 3 (0.01 stored via a double) is fine.
For row 4 (45678.45 stored via double) precision loss is an issue for getString except when it is a TEXT column.
For rows 5-9 the data is stored via a string, TEXT and BLOB columns accurately store the value in all cases with no precision loss. Otherwise the results are similar.