Відповіді:
У вас є два варіанти. По-перше, ви можете просто додати новий стовпець із наступним:
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
По-друге, і складніше, але насправді було б розмістити стовпець там, де ви цього хочете, було б перейменувати таблицю:
ALTER TABLE {tableName} RENAME TO TempOldTable;
Потім створіть нову таблицю з стовпцем, що відсутній:
CREATE TABLE {tableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);
І заповнити його старими даними:
INSERT INTO {tableName} (name, qty, rate) SELECT name, qty, rate FROM TempOldTable;
Потім видаліть стару таблицю:
DROP TABLE TempOldTable;
Я б більше віддав перевагу другому варіанту, оскільки він дозволить вам повністю перейменувати все, якщо потрібно.
PRAGMA foreign_keys = ON;
(див. sqlite.org/foreignkeys.html#fk_enable )
Ви не додаєте стовпчики між іншими стовпцями в SQL, ви просто додаєте їх. Де вони розміщені, повністю залежить від СУБД. Правильне місце для того, щоб стовпці виходили у правильному порядку, - це коли ви select
їх.
Іншими словами, якщо ви хочете, щоб вони були в порядку {name,colnew,qty,rate}
, ви використовуєте:
select name, colnew, qty, rate from ...
Для SQLite потрібно використовувати alter table
, наприклад:
alter table mytable add column colnew char(50)
SELECT * FROM mytable
?
select *
. Іноді це зручно для програм, які хочуть виявляти таблиці, але для переважної більшості застосувань вам слід чітко вказати, що ви хочете, а отже, і порядок, у якому ви цього хочете.
SQLite має обмежену підтримку ALTER TABLE, яку можна використовувати для додавання стовпця в кінець таблиці або для зміни імені таблиці.
Якщо ви хочете внести більш складні зміни в структуру таблиці, вам доведеться відтворити таблицю. Ви можете зберегти наявні дані до тимчасової таблиці, скинути стару таблицю, створити нову таблицю, а потім скопіювати дані назад з тимчасової таблиці.
Наприклад, припустимо, у вас є таблиця з назвою "t1" із назвами стовпців "a" і "c" і що ви хочете вставити стовпчик "b" з цієї таблиці. Наступні кроки ілюструють, як це можна зробити:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,c);
INSERT INTO t1_backup SELECT a,c FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b, c);
INSERT INTO t1 SELECT a,c FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
Тепер ви готові вставити нові дані на зразок:
UPDATE t1 SET b='blah' WHERE a='key'
INSERT INTO t1 SELECT a,c FROM t1_backup;
викликає помилку: "таблиця t1 має 3 стовпчики, але було надано 2 значення: ВСТАВИТЬСЯ В t1 SELECT a, c ВІД t1_backup;". Правильна лінія повинна бутиINSERT INTO t1 (a,c) SELECT a,c FROM t1_backup;
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
UPDATE {tableName} SET COLNew = {base on {type} pass value here};
Це оновлення потрібно для обробки нульового значення, вводячи значення за замовчуванням, як потрібно. Як і у вашому випадку, вам потрібно зателефонувати за SELECT
запитом, і ви отримаєте порядок стовпців, як уже написано paxdiablo :
SELECT name, colnew, qty, rate FROM{tablename}
і на мій погляд, назва вашого стовпця, щоб отримати значення від курсору:
private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));
тож якщо індекс змінить вашу програму, не виникне жодних проблем.
Це безпечний шлях в тому сенсі , що в іншому випадку, якщо ви використовуєте CREATE temptable
або RENAME table
або CREATE
, там буде висока ймовірність втрати даних , якщо не звертатися обережно, наприклад , в тому випадку , якщо ваші транзакції відбуваються в той час як батарея на кінець.
Я зіткнувся з тією ж проблемою, і другий метод, запропонований у прийнятій відповіді, як зазначено в коментарях, може бути проблематичним при роботі з іноземними ключами.
Моє вирішення полягає в тому, щоб експортувати базу даних у файл sql, переконуючись, що оператори INSERT містять назви стовпців. Я роблю це за допомогою браузера DB для SQLite, який має для цього зручну функцію. Після цього вам просто потрібно відредагувати оператор створення таблиці та вставити новий стовпець там, де ви хочете, і відтворити db.
У * nix подібних системах - це лише щось, що відповідає лінії
cat db.sql | sqlite3 database.db
Я не знаю, наскільки це можливо при дуже великих базах даних, але в моєму випадку це спрацювало.