我正在创建一个支票簿应用程序,并希望在应用交易后获取帐户的价值。然后,我想更新后续交易,以反映每次交易后的新金额。我在Android上使用SQLite。我想在时间轴的任何位置输入交易,如果以后出现任何交易,余额将被更新。这应该像网上银行的交易一样工作。
我尝试使用for循环,while循环等 我只是似乎无法访问正确的数据。
Transaction 1. $33.00. Balance $33.00
Transaction 2. $5.00. Balance $38.00
Transaction 3. $10.00. Balance $48.00
这是我正在开发的第一个完整应用程序,相对于一般而言还比较新。
即使指向正确方向的指针也将不胜感激。
答案 0 :(得分:1)
要在插入/更新/删除(甚至选择)时自动执行某些操作,可以使用将自动运行的TRIGGER。
SQL As Understood By SQLite - CREATE TRIGGER(建议您仔细阅读)
以下内容可能足够或作为基础。它可以处理您的测试数据(如下所示):-
CREATE TRIGGER IF NOT EXISTS adjust_balance_after_insert
AFTER INSERT ON transaction_table -- After an insert
BEGIN
-- Update the transaction table for this row (and any that are > (likely none))
UPDATE transaction_table
-- set the balance to be the new amount + the highest balance of the previous transaction
SET balance = new.amount + (
SELECT
CASE
WHEN
-- if no previous transaction then balance is 0 (may need to cater for a starting balance, although that could be the first transaction)
(SELECT max(balance) FROM transaction_table WHERE id = (new.id - 1) ORDER BY id DESC LIMIT 1) IS NULL THEN 0
ELSE
-- if there is a previous transaction then the balance is this amount + the balance (max(balance) could be just balance)
(SELECT max(balance) FROM transaction_table WHERE id = (new.id - 1) ORDER BY id DESC LIMIT 1)
END
)
WHERE id >= new.id ;
END;
以下是用于测试上述内容的SQL:-
DROP TABLE IF EXISTS transaction_table;
DROP TRIGGER IF EXISTS adjust_balanace_after_insert;
CREATE TABLE IF NOT EXISTS transaction_table (id INTEGER PRIMARY KEY AUTOINCREMENT, item TEXT, amount INTEGER, balance INTEGER);
-- The trigger
CREATE TRIGGER IF NOT EXISTS adjust_balanace_after_insert
AFTER INSERT ON transaction_table -- After an insert
BEGIN
-- Update the transaction table for this row (and any that are > (likely none))
UPDATE transaction_table
-- set the blanace to be the new amount + the highest balance of the previous transaction
SET balance = new.amount + (
SELECT
CASE
WHEN
-- if no previous transaction then balance is 0 (may need to cater for a starting balance, although that could be the first transaction)
(SELECT max(balance) FROM transaction_table WHERE id = (new.id - 1) ORDER BY id DESC LIMIT 1) IS NULL THEN 0
ELSE
-- if there is a previous transaction then the blanace is this amount + the blanace (max(balance) could be just balance)
(SELECT max(balance) FROM transaction_table WHERE id = (new.id - 1) ORDER BY id DESC LIMIT 1)
END
)
WHERE id >= new.id ;
END;
-- Test it
INSERT INTO transaction_table (item,amount) VALUES ('tv001',3300),('tv002',500),('tv003',1000);
SELECT * FROM transaction_table;
结果为:-
WHERE id < (new.id)
)。答案 1 :(得分:0)
这是android更新所有余额(可以更改为从特定交易中更新)的另一种可能更简单的方法。
该示例使用带有列的名为** transaction_table *的表
解决方案的症结是两种方法,它们用于获取先前的交易余额(getPreviousBalance
)和基于检索到的先前的平衡更新所有余额(updateBalances
)(如果没有先前的交易则为0)
SQLieOpenHelper(也称为Databasehelper)的子类是 TransactionHelper.java ,它是:-
public class TransactionHelper extends SQLiteOpenHelper {
public static final String DBNAME = "transaction.db";
public static final int DBVERSION = 1;
public static final String TB_TRANSACTION = "transaction_table";
public static final String COL_TRANSACTION_TIMESTAMP = "timestamp";
public static final String COl_TRANSACTION_ITEM = "item";
public static final String COL_TRANSACTION_AMOUNT = "amount";
public static final String COl_TRANSACTION_BALANCE = "balance";
SQLiteDatabase mDB;
public TransactionHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_sql = "CREATE TABLE IF NOT EXISTS " + TB_TRANSACTION + "(" +
COL_TRANSACTION_TIMESTAMP + " TEXT PRIMARY KEY DEFAULT CURRENT_TIMESTAMP, " +
COl_TRANSACTION_ITEM + " TEXT, " +
COL_TRANSACTION_AMOUNT + " INTEGER, " +
COl_TRANSACTION_BALANCE + " INTEGER " +
")";
db.execSQL(crt_sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long insertTransaction(String item, long amount, String timestamp) {
long rv = -1;
ContentValues cv = new ContentValues();
cv.put(COL_TRANSACTION_TIMESTAMP,timestamp);
cv.put(COl_TRANSACTION_ITEM,item);
cv.put(COL_TRANSACTION_AMOUNT,amount);
rv = mDB.insert(TB_TRANSACTION,null,cv);
updateBalances(); //<<<<<<<<<< Update the balances
return rv;
}
public void logLedger(String description) {
Cursor csr = mDB.query(TB_TRANSACTION,null,null,null,null, null,COL_TRANSACTION_TIMESTAMP + " ASC");
Log.d("LEDGER", "Displaying Ledger - " + description);
while (csr.moveToNext()) {
Log.d(
"LEGDER",
"Date = " +
csr.getString(csr.getColumnIndex(COL_TRANSACTION_TIMESTAMP)) +
" Item = " +
csr.getString(csr.getColumnIndex(COl_TRANSACTION_ITEM)) +
" Amount = " +
String.valueOf(csr.getLong(csr.getColumnIndex(COL_TRANSACTION_AMOUNT))) +
" Balance = " +
String.valueOf(csr.getLong(csr.getColumnIndex(COl_TRANSACTION_BALANCE)))
);
}
csr.close();
}
private void updateBalances() {
String whereclause = COL_TRANSACTION_TIMESTAMP + "=?";
String[] whereargs = new String[1];
Cursor csr = mDB.query(TB_TRANSACTION,null,null,null,null,null,COL_TRANSACTION_TIMESTAMP + " ASC");
mDB.beginTransaction();
while (csr.moveToNext()) {
long balance_to_apply = csr.getLong(csr.getColumnIndex(COL_TRANSACTION_AMOUNT)) + getPreviousBalance(csr.getString(csr.getColumnIndex(COL_TRANSACTION_TIMESTAMP)));
ContentValues cv = new ContentValues();
cv.put(COl_TRANSACTION_BALANCE,String.valueOf(balance_to_apply));
whereargs[0] = csr.getString(csr.getColumnIndex(COL_TRANSACTION_TIMESTAMP));
mDB.update(TB_TRANSACTION,cv,whereclause,whereargs);
}
csr.close();
mDB.setTransactionSuccessful();
mDB.endTransaction();
}
private long getPreviousBalance(String datetime) {
long rv = 0;
String[] columns = new String[]{COl_TRANSACTION_BALANCE};
String whereclause = COL_TRANSACTION_TIMESTAMP + "<?";
String[] whereargs = new String[]{datetime};
Cursor csr = mDB.query(TB_TRANSACTION,columns,whereclause,whereargs,null,null,COL_TRANSACTION_TIMESTAMP + " DESC","1");
if (csr.moveToFirst()) {
rv = csr.getLong(csr.getColumnIndex(COl_TRANSACTION_BALANCE));
}
csr.close();
return rv;
}
}
根据活动 MainActivity.java 进行的测试:-
public class MainActivity extends AppCompatActivity {
TransactionHelper mTAHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTAHlpr = new TransactionHelper(this);
mTAHlpr.insertTransaction("T001",10000,"2018-01-01 10:30:00");
mTAHlpr.insertTransaction("T002",20000,"2018-01-01 11:30:01");
mTAHlpr.insertTransaction("T003",30000,"2018-01-01 12:30:45");
mTAHlpr.logLedger("After 3 rows inserted");
mTAHlpr.insertTransaction("T004",100000,"2017-01-01 09:00:00");
mTAHlpr.logLedger("Another First row inserted");
mTAHlpr.insertTransaction("T005",200000,"2018-01-01 10:32:00");
mTAHlpr.logLedger("Row inserted after 2nd");
}
}
结果(分类帐):-
11-16 22:32:41.630 1387-1387/so53291104.so53291104 D/LEDGER: Displaying Ledger - After 3 rows inserted 11-16 22:32:41.630 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 10:30:00 Item = T001 Amount = 10000 Balance = 10000 11-16 22:32:41.630 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 11:30:01 Item = T002 Amount = 20000 Balance = 30000 11-16 22:32:41.630 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 12:30:45 Item = T003 Amount = 30000 Balance = 60000 11-16 22:32:41.638 1387-1387/so53291104.so53291104 D/LEDGER: Displaying Ledger - Another First row inserted 11-16 22:32:41.638 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2017-01-01 09:00:00 Item = T004 Amount = 100000 Balance = 100000 11-16 22:32:41.638 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 10:30:00 Item = T001 Amount = 10000 Balance = 110000 11-16 22:32:41.638 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 11:30:01 Item = T002 Amount = 20000 Balance = 130000 11-16 22:32:41.638 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 12:30:45 Item = T003 Amount = 30000 Balance = 160000 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEDGER: Displaying Ledger - Row inserted after 2nd 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2017-01-01 09:00:00 Item = T004 Amount = 100000 Balance = 100000 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 10:30:00 Item = T001 Amount = 10000 Balance = 110000 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 10:32:00 Item = T005 Amount = 200000 Balance = 310000 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 11:30:01 Item = T002 Amount = 20000 Balance = 330000 11-16 22:32:41.646 1387-1387/so53291104.so53291104 D/LEGDER: Date = 2018-01-01 12:30:45 Item = T003 Amount = 30000 Balance = 360000