Respostas:
Você tem duas opções. Primeiro, você pode simplesmente adicionar uma nova coluna com o seguinte:
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
Segundo, e mais complicado, mas na verdade colocaria a coluna onde você deseja, seria renomear a tabela:
ALTER TABLE {tableName} RENAME TO TempOldTable;
Em seguida, crie a nova tabela com a coluna ausente:
CREATE TABLE {tableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);
E preencha com os dados antigos:
INSERT INTO {tableName} (name, qty, rate) SELECT name, qty, rate FROM TempOldTable;
Em seguida, exclua a tabela antiga:
DROP TABLE TempOldTable;
Eu preferiria muito a segunda opção, pois ela permitirá que você renomeie completamente tudo, se necessário.
PRAGMA foreign_keys = ON;(consulte sqlite.org/foreignkeys.html#fk_enable )
Você não adiciona colunas entre outras colunas no SQL, apenas as adiciona. Onde eles são colocados depende totalmente do DBMS. O lugar certo para garantir que as colunas saiam na ordem correta é quando você as selectusa.
Em outras palavras, se você os quiser na ordem {name,colnew,qty,rate}, use:
select name, colnew, qty, rate from ...
Com o SQLite, você precisa usar alter table, um exemplo:
alter table mytable add column colnew char(50)
SELECT * FROM mytable?
select *. Às vezes, é útil para programas que desejam descobrir tabelas, mas, para a grande maioria dos usos, você deve especificar explicitamente o que deseja e, portanto, a ordem em que deseja.
O SQLite limitou o suporte a ALTER TABLE que você pode usar para adicionar uma coluna ao final de uma tabela ou alterar o nome de uma tabela.
Se você deseja fazer alterações mais complexas na estrutura de uma tabela, precisará recriar a tabela. Você pode salvar os dados existentes em uma tabela temporária, soltar a tabela antiga, criar a nova tabela e copiar os dados novamente da tabela temporária.
Por exemplo, suponha que você tenha uma tabela chamada "t1" com os nomes das colunas "a" e "c" e que deseje inserir a coluna "b" nessa tabela. As etapas a seguir ilustram como isso pode ser feito:
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;
Agora você está pronto para inserir seus novos dados da seguinte forma:
UPDATE t1 SET b='blah' WHERE a='key'
INSERT INTO t1 SELECT a,c FROM t1_backup;causa o erro: "a tabela t1 tem 3 colunas, mas foram fornecidos 2 valores: INSERT IN t1 SELECT a, c FROM t1_backup;". A linha correta deve serINSERT 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};
Esta atualização é necessária para manipular o valor nulo, inserindo um valor padrão conforme necessário. Como no seu caso, você precisa chamar a SELECTconsulta e obterá a ordem das colunas, como o paxdiablo já disse:
SELECT name, colnew, qty, rate FROM{tablename}
e na minha opinião, o nome da sua coluna para obter o valor do cursor:
private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));
portanto, se o índice mudar, seu aplicativo não enfrentará problemas.
Essa é a maneira segura no sentido de que, caso contrário, se você estiver usando CREATE temptableou RENAME tableou CREATE, haveria uma grande chance de perda de dados se não fosse tratado com cuidado, por exemplo, no caso em que suas transações ocorrem enquanto a bateria está acabando.
Eu estava enfrentando o mesmo problema e o segundo método proposto na resposta aceita, conforme observado nos comentários, pode ser problemático ao lidar com chaves estrangeiras.
Minha solução alternativa é exportar o banco de dados para um arquivo sql, certificando-se de que as instruções INSERT incluam nomes de colunas. Eu faço isso usando o DB Browser for SQLite, que tem um recurso útil para isso. Depois disso, basta editar a instrução create table e inserir a nova coluna onde desejar e recriar o banco de dados.
Em sistemas do tipo * nix é apenas algo parecido com o
cat db.sql | sqlite3 database.db
Não sei se isso é viável com bancos de dados muito grandes, mas funcionou no meu caso.