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 select
usa.
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 SELECT
consulta 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 temptable
ou RENAME table
ou 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.