Автоинкрементный сброс Android Studio Sqllite - PullRequest
0 голосов
/ 30 декабря 2018
db.execSQL("CREATE TABLE " +DBTable0+ "("+ROW2+" INTEGER PRIMARY KEY AUTOINCREMENT, "+ROW3+" VARCHAR NOT NULL, "+ROW0+" TEXT NOT NULL, "+ROW1+" VARCHAR NOT NULL)");

Вот команда создания таблицы моей базы данных.

Я хочу сбросить значения ROW2.

Например, у меня есть 5 записей в этой таблице.

1, save1, Это Save1, 11.25

2, save2, Это Save2, 23.48

3, save3, Это Save3, 09.45

4, save4, Это Save4, 11.55

5, save5, это Save5, 21.00

Я хочу удалить save2.Когда я удаляю это или другое удаление, я хочу сбросить индексы ROW2, поэтому

1, save1, это Save1, 11.25

2, save3, это Save3, 09.45

3, save4, Это Save4, 11.55

4, save5, Это Save5, 21.00

Как это ...

Как я могу это сделать.?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Чтобы сбросить rowid , назначенный для компенсации удаленных строк при использовании AUTOINCREMENT, вам необходимо внести два изменения: -

  1. Вам придется изменить (ОБНОВИТЬ) rowid или псевдоним rowid каждой строки, которая не соответствует следующей последовательности и
  2. , тогда вам придется изменить (ОБНОВИТЬ) соответствующую строкув системной таблице sqlite_sequence до самого высокого rowid .

Это совсем не рекомендуется и значительно усугубит неэффективность использования AUTOINCREMENT (когда есть очень хороший шанс, что вам не нужно использовать AUTOINCREMENT).

  • Автоинкремент SQLite включает
  • Ключевое слово AUTOINCREMENT накладывает дополнительные затраты ресурсов процессора, памяти, дискового пространства и дискового ввода-вывода, и следует избегать , если в этом нет особой необходимости.Обычно это не нужно.

На самом деле не стоит полагаться на rowid существовсе, что присваивает SQlite

  • (<column_name> INTEGER PRIMARY KEY (с или без AUTOINCREMENT) делает и псевдоним rowid ).

Вы говорите: -

Я хочу сбросить значения ROW2.

Я бы предложил переоценить ваше желание только хотетьэто, если на самом деле есть необходимость, которой, по всей вероятности, нет.

Затем вы говорите

Я выберу записи через ListViews.Затем я могу удалить и обновить записи на выбранном мной элементе.Поэтому, когда я удаляю любые записи в Middless.идентификаторы смешивают и удаляют ложные записи

Если вы используете CursorAdapter, например SimpleCursorAdapter, 4-й параметр onItemClick и onItemLongClick - это id .

Обратите внимание, что для использования CursorAdapter в Cursor, являющемся источником ListView, должен присутствовать столбец с именем _id , и этот столбец должен содержать rowid .Вы можете использовать BaseColumns._ID , который является константой со значением _id .

Как правило, вы определяете столбец в таблице как _id INTEGER PRIMARY KEY

В качестве альтернативы вы можете использовать rowid AS _id, *, в этом случае столбец _id будет дополнительным ко всем другим столбцам.

этот и другие параметры / пояснения для других адаптеров могутможно найти здесь

Рабочий пример

Однако, если вы настаиваете, то следующий пример выполняет то, о чем вы, я полагаю, спрашиваете.

Примечание этот пример делает то же самое ( эффективно ) для 2 таблиц.

  • Первая таблица table1 использует AUTOINCREMENT
  • Вторая таблица table2 не имеет AUTOINCREMENT, но результаты идентичны (другиеsqlite_sequence не изменяется, так как в этом нет необходимости, поскольку в sqlite_sequence нет ни строки, ни AUTOINCREMENT, ни кодируемой).

Основной код находится в помощнике по базам данных (подкласс SQLiteOpenHelper), а именно DBHelper.java : -

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TBL_TABLE1 = "table1";
    public static final String TBL_TABLE2 = "table2";
    public static final String COL_TABLE_COL1 = "col1";
    public static final String COL_TABLE_COL2 = "col2";
    public static final String COL_TABLE_COL3 = "col3";

    private static final String crt_table1_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE1 + "(" +
            COL_TABLE_COL1 + " INTEGER PRIMARY KEY AUTOINCREMENT," +
            COL_TABLE_COL2 + " TEXT NOT NULL," +
            COL_TABLE_COL3 + " TEXT NOT NULL" +
            ")";
    private static final String crt_table2_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE2 + "(" +
            COL_TABLE_COL1 + " INTEGER PRIMARY KEY," +
            COL_TABLE_COL2 + " TEXT NOT NULL," +
            COL_TABLE_COL3 + " TEXT NOT NULL" +
            ")";

    SQLiteDatabase mDB;

    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onConfigure(SQLiteDatabase db) {
        super.onConfigure(db);
        db.disableWriteAheadLogging();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(crt_table1_sql);
        db.execSQL(crt_table2_sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public void insert(String col2, String col3) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE_COL2,col2);
        cv.put(COL_TABLE_COL3,col3);
        mDB.beginTransaction();
        mDB.insert(TBL_TABLE1,null,cv);
        mDB.insert(TBL_TABLE2,null,cv);
        mDB.setTransactionSuccessful();
        mDB.endTransaction();
    }

    public void deleteByValues(String col2, String col3) {
        String whereclause = COL_TABLE_COL2 + "=? AND " + COL_TABLE_COL3 + "=?";
        String[] args = new String[]{col2,col3};
        mDB.beginTransaction();
        mDB.delete(TBL_TABLE1,whereclause,args);
        mDB.delete(TBL_TABLE2,whereclause,args);
        rationaliseCol1Values();
        mDB.setTransactionSuccessful();
        mDB.endTransaction();
    }

    private void rationaliseCol1Values() {
        ContentValues cv = new ContentValues();
        Cursor csr = mDB.query(TBL_TABLE1,null,null,null,null,null,COL_TABLE_COL1 + " ASC");

        int rowcount = csr.getCount();
        long expected_id = 1;
        long current_id;
        String where_clause = COL_TABLE_COL1 + "=?";
        String[] args = new String[1];

        while (csr.moveToNext()) {
            current_id = csr.getLong(csr.getColumnIndex(COL_TABLE_COL1));
            if (current_id != expected_id) {
                cv.clear();
                cv.put(COL_TABLE_COL1,expected_id);
                args[0] = String.valueOf(current_id);
                mDB.update(TBL_TABLE1,cv,where_clause,args);
                mDB.update(TBL_TABLE2,cv,where_clause,args);
            }
            expected_id++;
        }
        // Now adjust sqlite_sequence
        where_clause = "name=?";
        args[0] = TBL_TABLE1;
        cv.clear();
        cv.put("seq",String.valueOf(rowcount));
        mDB.update("sqlite_sequence",cv,where_clause,args);
    }

    public void logTableRows(int stage) {

        String tablenamne_column = "tablename";    
        Cursor[] csr = new Cursor[] {
                mDB.query(TBL_TABLE1,new String[]{"'table1' AS " + tablenamne_column + ",*"},null,null,null,null,null),
                mDB.query(TBL_TABLE2,new String[]{"'table2' AS " + tablenamne_column + ",*"}, null,null,null,null,null)
        };
        MergeCursor csr3 = new MergeCursor(csr);
        StringBuilder sb = new StringBuilder("Data in both tables consists of " + String.valueOf(csr3.getCount()) + " rows :-");

        while (csr3.moveToNext()) {
            sb.append(
                    "\n\tTableName = " + csr3.getString(csr3.getColumnIndex(tablenamne_column)
                    )
            ).append(" " + COL_TABLE_COL1 + " value is " + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL1))
            ).append(" " + COL_TABLE_COL2 + " value is " + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL2))
            ).append(" " + COL_TABLE_COL3 + " value is" + csr3.getString(csr3.getColumnIndex(COL_TABLE_COL3))
            );
        }
        Log.d("DATA4STAGE" + String.valueOf(stage),sb.toString());
    }
}
  • Управление ядром rowid (поэтому псевдоним, т.е. COL1 ) выполняется рациональный методCol1Values ​​() метод.Само по себе это вызывается как часть метода deleteByValues ​​.
    • если бы существовал метод для удаления в соответствии с id aka COL1 , то это также вызвало бы метод рациональный_Col1Values ​​() ).
  • logTableRows просто существует, так что таблицы могут быть выведены в журнал.

Операция вызова, использованная для тестирования выше, была:-

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlpr = new DBHelper(this);
        manipulateSomeData();
    }

    private void manipulateSomeData() {
        mDBHlpr.logTableRows(0);
        mDBHlpr.insert("TEST001","TESTING001");
        mDBHlpr.insert("TEST002","TESTING001");
        mDBHlpr.insert("TEST003","TESTING001");
        mDBHlpr.insert("TEST004","TESTING001");
        mDBHlpr.insert("TEST005","TESTING001");
        mDBHlpr.insert("TEST006","TESTING001");
        mDBHlpr.insert("TEST007","TESTING001");
        mDBHlpr.insert("TEST008","TESTING001");
        mDBHlpr.insert("TEST009","TESTING001");
        mDBHlpr.logTableRows(1);

        mDBHlpr.deleteByValues("TEST005","TESTING001");
        mDBHlpr.logTableRows(2);
        mDBHlpr.deleteByValues("TEST008","TESTING001");
        mDBHlpr.logTableRows(3);
        mDBHlpr.deleteByValues("TEST003","TESTIN001");
        mDBHlpr.logTableRows(4);
    }
}
  • Это: -
    1. выводит список строк (ни одного при первом запуске).
    2. Добавляет 9 строк, причем COL2 является уникальным (снова только при первомвыполнить).
    3. перечислить все 9 строк (1-й запуск).
    4. удаляет все строки, имеющие значения "TEST005" в COL2 И"TESTING001" в COL3.
    5. перечисляет строки (обратите внимание, как поддерживается последовательность COL1).
    6. удаляет все строки со значениями "TEST008" в COL2 И"TESTING001" в COL3.
    7. перечисляет строки (обратите внимание, как поддерживается последовательность COL1).
    8. удаляетлюбые строки, имеющие значения «TEST003» в COL2 И «TESTIN001» в COL3. Нет из-за опечатки (отсутствует G)
    9. перечисляет строки (обратите внимание, как поддерживается последовательность COL1).

Вывод результатов в журнал: -

2018-12-31 12:43:21.618 2269-2269/so53976714.so53976714 D/DATA4STAGE0: Data in both tables consists of 0 rows :-
2018-12-31 12:43:21.657 2269-2269/so53976714.so53976714 D/DATA4STAGE1: Data in both tables consists of 18 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST005 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 8 col2 value is TEST008 col3 value isTESTING001
        TableName = table1 col1 value is 9 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST005 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 8 col2 value is TEST008 col3 value isTESTING001
        TableName = table2 col1 value is 9 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.666 2269-2269/so53976714.so53976714 D/DATA4STAGE2: Data in both tables consists of 16 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST008 col3 value isTESTING001
        TableName = table1 col1 value is 8 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST008 col3 value isTESTING001
        TableName = table2 col1 value is 8 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.675 2269-2269/so53976714.so53976714 D/DATA4STAGE3: Data in both tables consists of 14 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
2018-12-31 12:43:21.681 2269-2269/so53976714.so53976714 D/DATA4STAGE4: Data in both tables consists of 14 rows :-
        TableName = table1 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table1 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table1 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table1 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table1 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table1 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table1 col1 value is 7 col2 value is TEST009 col3 value isTESTING001
        TableName = table2 col1 value is 1 col2 value is TEST001 col3 value isTESTING001
        TableName = table2 col1 value is 2 col2 value is TEST002 col3 value isTESTING001
        TableName = table2 col1 value is 3 col2 value is TEST003 col3 value isTESTING001
        TableName = table2 col1 value is 4 col2 value is TEST004 col3 value isTESTING001
        TableName = table2 col1 value is 5 col2 value is TEST006 col3 value isTESTING001
        TableName = table2 col1 value is 6 col2 value is TEST007 col3 value isTESTING001
        TableName = table2 col1 value is 7 col2 value is TEST009 col3 value isTESTING001

ПРИМЕЧАНИЕ Использование вышеупомянутого НЕ рекомендуется

0 голосов
/ 30 декабря 2018

Смысл ключевого слова AUTOINCREMENT заключается в том, чтобы никогда не использовать повторно rowid.Он хранит самый высокий назначенный для таблицы, и при вставке новой строки, для которой явно не указан идентификатор строки в операторе вставки, выбирается число больше, чем сохраненное.Без AUTOINCREMENT он просто выбирает число, превышающее текущий максимальный идентификатор строки в таблице (и, если максимум - это максимально возможное 64-разрядное целое число со знаком, он выбирает несколько меньших случайным образом в надежде на отсутствие, прежде чем отказаться).

Если вы хотите перерабатывать числа строк, вы должны либо вручную найти пропущенные числа и явно использовать их в операторах UPDATE, либо не иметь столбец INTEGER PRIMARY KEY, и запустить VACUUM послеудаление строк.Без столбца INTEGER PRIMARY KEY, в котором есть псевдоним rowid, sqlite переставит их в этом случае.Или вы можете скопировать строки таблицы, за исключением столбца INTEGER PRIMARY KEY, в новую таблицу, чтобы получить новые значения строк.Все это ужасно неэффективные подходы и нежелательны.Живите с пробелами из удаленных строк.

Обязательное чтение для понимания rowid, INTEGER PRIMARY KEY столбцов и AUTOINCREMENT:

https://www.sqlite.org/rowidtable.html

https://www.sqlite.org/lang_createtable.html#rowid

https://www.sqlite.org/autoinc.html

Я выберу записи через ListViews.Затем я могу удалить и обновить записи на выбранном мной элементе.Поэтому, когда я удаляю любые записи в Middless.идентификаторы смешивают и удаляют ложные записи

Звучит так, будто вы предполагаете, что какая-то позиция списка совпадает с rowid строки?Не удивительно, что у тебя проблемы.Сохраняйте явное отслеживание rowid и используйте его при удалении запрошенных данных.Классический случай проблемы XY .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...