Limitación del número de filas en SQLite
Tengo una situación en la que sólo quiero limitar sólo 50 filas en una tabla. Si el usuario inserta una nueva fila después de eso, entonces la primera fila (que se insertó primero) debería eliminarse y se inserta una nueva fila, de modo que el recuento permanezca igual. Sé que puedo tener un campo rowid y mientras que inserta el nuevo expediente puedo comprobar si hay ya 50 filas así que suprima el rowid más pequeño y después inserte el nuevo. Pero sólo quiero saber si hay alguna solución mejor para que no tenga que hacer 3 operaciones de base de datos (1. consulta #of filas, 2. eliminar mínimo, 3. insertar)
- SQL eliminar de una tabla + un jointable?
- Sqlite android extraer contactos con número de teléfono
- No se puede crear la base de datos SQLite de SQL: error PRAGMA
- Filtrar el parámetro ListView por 'selección' en CursorLoader
- Condición de consulta múltiple en Android usando ORMLITE
- La base de datos SQLite de Android está bloqueada
- ¿Es posible mover el DB interno a la tarjeta SD?
- SQLiteDatabase.execSQL no funciona como se esperaba para la consulta INSERT INTO
- Malo rendimiento de SQLite en almacenamiento externo en Android
- Actualizar archivo apk en Google Play
- Cómo escribir una base de datos en un archivo de texto en android
- Insertar 1000000 filas en la base de datos sqlite3
- Varios Table SQLite DB Adapter (s) en Android?
Conozco un camino que funciona, pero es un poco feo. Se basa en restricciones cuidadosamente construidas y en la siembra de la base de datos. Por brevedad, estoy usando sólo cinco filas en lugar de 50.
create table test ( row_num integer primary key check ((round(row_num) = row_num) and (row_num between 1 and 5)), other_columns char(1) not null default 'x', row_timestamp timestamp not null unique default current_timestamp );
La expresión round(row_num = row_num)
garantiza que tiene números enteros en la columna row_num. De lo contrario, SQLite le permitiría insertar 1.54 o 'wibble' allí.
La columna other_columns
es sólo un marcador de posición para sus datos reales.
insert into test (row_num, row_timestamp) values (1, '2015-01-01 08:00:01'), (2, '2015-01-01 08:00:02'), (3, '2015-01-01 08:00:03'), (4, '2015-01-01 08:00:04'), (5, '2015-01-01 08:00:05');
Los valores de marca de tiempo reales realmente no significan nada. No todavía, de todos modos. La creación de la base de datos de este modo significa que, de ahora en adelante, sólo tendrá que ejecutar instrucciones de actualización. Si la tabla estuviera vacía para empezar, tendría que lidiar con diferentes lógica para inserciones y actualizaciones. Por ejemplo, tendría que contar las filas para averiguar si insertar o actualizar.
create trigger update_timestamp after update on test for each row begin update test set row_timestamp = strftime('%Y-%m-%d %H:%M:%f', 'now') where row_num = OLD.row_num; end;
El trigger "update_timestamp" hace que SQLite mantenga la marca de tiempo con fracciones de segundo ( %f
). Puede depender de si el SO subyacente soporta precisión fraccionada.
create trigger no_deletes after delete on test for each row begin -- There might be a more elegant way to prevent deletes. -- This way just inserts exactly what a delete statement deletes. insert into test (row_num, other_columns, row_timestamp) values (OLD.row_num, OLD.other_columns, OLD.row_timestamp); end;
Ahora puede actualizar los datos. Actualiza sus propios datos, que aquí es sólo el marcador de posición other_columns
, y SQLite se encarga del resto.
update test set other_columns = 'b' where row_timestamp = (select min(row_timestamp) from test); select * from test order by row_timestamp desc;
Row_num other_columns row_timestamp Unesdoc.unesco.org unesdoc.unesco.org 1 b 2015-03-08 12: 43: 21.926 5 x 2015-01-01 08:00:05 4 x 2015-01-01 08:00:04 3 x 2015-01-01 08:00:03 2 x 2015-01-01 08:00:02
- Cómo asignar "Development Key Hash" para un dispositivo y no un emulador
- Separar un proyecto de Android en varias bibliotecas de dependientes