What happens if I drop some "special" SQLite tables - c++

First, some background info, maybe someone suggests some better way then I try to do. I need to export SQLite database into text file. For that I have to use C++ and chosen to use CppSQLite lib.
That I do is collecting create queries and after that export every table data, the problem is that there are tables like sqlite_sequence and sqlite_statN. During import I cannot create these tables because these are special purpose, so the main question, would it affect stability if these tables are gone?
Another part of question. Is there any way to export and import SQLite database using CppSQLite or any other SQLite lib for C++?
P.S. Solution to copy database file is not appropriate in this particular situation.

Object names beginning with sqlite_ are reserved; you cannot create them directly even if you wanted to. (But you change the contents of some of them, and you can drop the sqlite_stat* tables.)
The sqlite_sequence table is created automatically when a table with an AUTOINCREMENT column is created.
The record for the actual sequence value of a table is created when it is needed first.
If you want to save/restore the sequence value, you have to re-insert the old value.
The sqlite_stat* tables are created by ANALYZE.
Running ANALYZE after importing the SQL text would be easiest, but slow; faster would be to create an empty sqlite_stat* table by running ANALYZE on a table that will not be analyzed (such as sqlite_master), and then inserting the old records manually.
All this is implemented in the .dump command of the sqlite3 command-line tool (source code in shell.c):
SQLite version 3.8.4.3 2014-04-03 16:53:12
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> create table t(x integer primary key autoincrement);
sqlite> insert into t default values;
sqlite> insert into t default values;
sqlite> analyze;
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t(x integer primary key autoincrement);
INSERT INTO "t" VALUES(1);
INSERT INTO "t" VALUES(2);
ANALYZE sqlite_master;
INSERT INTO "sqlite_stat1" VALUES('t',NULL,'2');
DELETE FROM sqlite_sequence;
INSERT INTO "sqlite_sequence" VALUES('t',2);
COMMIT;
sqlite>

Related

Unable to add duplicate entry through informatica

I am using Informatica to finally write in the oracle table after performing certain logical operations on the data.
The problem is that if a certain ID was already previously processed and is present in the target table then it is not inserted again.
Please suggest a workaround.
Hi, This is because you might have same primary key in the source which is available in the target. Look into primary key columns and try loading them.
Altering your target table
alter table target_table_name drop constraint constraint name;

postgres - load from sql file (skip errors), leave existing ones and create non existing

I have an sql file(we can generate this in whatever way we want).
I want to load it fully initially, then want to update(delete, create) db based using logic.
Later, if I want to delete more, we can simply delete.
But, if we want to add more, then we need to import sql again. Before importing, I cant drop those tables because they are already foreign keys to others. So, I can only do this:
Run sql file somehow to add only non-available entries to database skipping available entries so I can skip errors ( duplicate key value violates unique ).
Import your data to a temporary table and then just use something like:
insert into real_table_name
select * from temporary_table_name
where id not in (select id from real_table_name);

how to check in sqlite3 whether number of columns are changed or not

Iam coding in c and using sqlite3 as database .I want to ask that how can we check whether no. of columns in a table got changed or not. Situation is like this that i am going to run the application with new executable according to which new columns will be added in the table.So when the DB will be created again application should check whether the table schema is same or not and according to the new schema it should create table.Iam developing application for a embedded enviroment(specifically for a device).
When iam changing the number of columns of table in db and running new executable in the device new tables are not getting created because of the presence of old tables but when iam deleting the old db and creating fresh tables then changes are coming.So how to handle this situation ?
Platform : Linux , gcc compiler
Thanks in advance
Pls guide me like this : (assuming Old DB is already present )
That firstly we have to check for the schema of Old DB and if there is any change in some of the tables(like some new columns added or deleted ) then create the new DB according to that .
Use Versioning and Explicit Column References
You can make use of database versioning to help assist with this sort of problem.
Create a separate table with only one column and one record to store the database version.
Whenever you upgrade your database, set the version number in the separate table.
Design your insert queries to specify the columns.
Define default values for new columns so that old programs insert default values.
Examples
UPDATE databaseVersion SET version=2;
Version 1 Query
INSERT INTO MyTable (id, var1, var2) VALUES (2, '5', '6');
Version 2 Query
INSERT INTO MyTable (id, var1, var2, var3) VALUES (3, '5', '6', '7');
This way your queries should still be compatible on the new DB when using the old program.

Verify the structure of a database? (SQLite in C++ / Qt)

I was wondering what the "best" way to verify the structure of my database is with SQLite in Qt / C++. I'm using SQLite so there is a file which contains my database, and I want to make sure that, when launching the program, the database is structured the way it should be- i.e., it has X tables each with their own Y columns, appropriately named, etc. Could someone point my in the right direction? Thanks so much!
You can get a list of all the tables in the database with this query:
select tbl_name from sqlite_master;
And then for each table returned, run this query to get column information
pragma table_info(my_table);
For the pragma, each row of the result set will contain: a column index, the column name, the column's type affinity, whether the column may be NULL, and the column's default value.
(I'm assuming here that you know how to run SQL queries against your database in the SQLite C interface.)
If you have QT and thus QtSql at hand, you can also use the QSqlDatabase::tables() (API doc) method to get the tables and QSqlDatabase::record(tablename) to get the field names. It can also give you the primary key(s), but for further details you will have to follow pkh's advice to use the table_info pragma.

SQLite - pre allocating database size

Is there a way to pre allocate my SQLite database to a certain size? Currently I'm adding and deleting a number of records and would like to avoid this over head at create time.
The fastest way to do this is with the zero_blob function:
Example:
Y:> sqlite3 large.sqlite
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table large (a);
sqlite> insert into large values (zeroblob(1024*1024));
sqlite> drop table large;
sqlite> .q
Y:> dir large.sqlite
Volume in drive Y is Personal
Volume Serial Number is 365D-6110
Directory of Y:\
01/27/2011 12:10 PM 1,054,720 large.sqlite
Note: As Kyle properly indicates in his comment:
There is a limit to how big each blob can be, so you may need to insert multiple blobs if you expect your database to be larger than ~1GB.
There is a hack - Insert a bunch of data into the database till the database size is what you want and then delete the data. This works because:
"When an object (table, index, or
trigger) is dropped from the database,
it leaves behind empty space. This
empty space will be reused the next
time new information is added to the
database. But in the meantime, the
database file might be larger than
strictly necessary."
Naturally, this isn't the most reliable method. (Also, you will need to make sure that auto_vacuum is disabled for this to work). You can learn more here - http://www.sqlite.org/lang_vacuum.html