create table with constraints from another table in sqlite? - sqlite

I want create table from another table with constraint?
I used this query "create table destination as select * from source;" fro table creation.
But its copy only the column name in table without column constraint.

There is a special table named sqlite_master, holding the full CREATE TABLE statement for each table (it's modified as appropriate during ALTER TABLE).
I would make my application retrieve that CREATE TABLE statement:
SELECT sql FROM sqlite_master WHERE type='table' AND name='source';
Then I would replace the table name right after CREATE TABLE tokens, and execute the result as a new sqlite query.
I don't think that it's possible to do in sqlite's pure SQL without extensions.

Related

How to save query results to a new sqlite?

I want to save the results of my sqlite query in a new sqlite file. in other words, I want to have a new sqlite database with the data which resulted from my query on my previous data set.
All I have found on the internet was how to export the query results to csv or sql. but I want my new data set to be sqlite.
Also, is there any way to save the query results on the same data set (like what we do in excel)? Thank you!
You can ATTACH another database file to an existing connection and create or insert data into a table in that other database.
Something like:
ATTACH DATABASE 'other.db' AS other;
CREATE TABLE other.foo AS SELECT * FROM main.foo; -- create and populate a table
INSERT INTO other.bar SELECT * FROM main.foo; -- insert into an existing table
DETACH other;

Add constraint to existing SQLite table

I'm using SQLite, which doesn't support adding a constraint to an existing table.
So I can't do something like this (just as an example):
ALTER TABLE [Customer]
ADD CONSTRAINT specify_either_phone_or_email
CHECK (([Phone] IS NOT NULL) OR ([Email] IS NOT NULL));
Are there any workarounds for this scenario?
I know:
I can add a constraint for a new table, but it isn't new (and it's generated by my ORM, EF Core)
I can do a "table rebuild" (rename table, create new one, copy old data, drop temp table) but that seems really complex
Ideas
Can I somehow make a copy of the table into a new table, with some schema changes?
Or "get" the schema somehow, and edit it in a SQL script, then add a table with that schema?
To make a copy of a table with some schema changes, you have to do the creation and the copying manually:
BEGIN;
CREATE TABLE Customer_new (
[...],
CHECK ([...])
);
INSERT INTO Customer_new SELECT * FROM Customer;
DROP TABLE Customer;
ALTER TABLE Customer_new RENAME TO Customer;
COMMIT;
To read the schema, execute .schema Customer in the sqlite3 command-line shell.
This gives you the CREATE TABLE statement, which you can edit and execute.
To change the table in place, you can use a backdoor.
First, read the actual table definition (this is the same as what you would get from .schema):
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'Customer';
Add your CHECK constraint to that string, then enable write access to sqlite_master with PRAGMA writable_schema=1; and write your new table definition into it:
UPDATE sqlite_master SET sql='...' WHERE type='table' AND name='Customer';
Then reopen the database.
WARNING: This works only for changes that do not change the on-disk format of the table. If you do make any change that changes the record format (such as adding/removing fields, or modifying the rowid, or adding a constraint that needs an internal index), your database will blow up horribly.

Same attributes, different tables in one database in SQLite

I am just new in SQLite and I have this assignment in creating database schema using the said program.
I just want to ask if it is allowed to give a same attributes present in different tables inside a single database. Let me give the SQLite statements of two tables in one database.
BEGIN TRANSACTION;
/* Create a table called Employee */
CREATE TABLE Employee(Name text, Phone_number varchar);
/* Create a table called Company */
CREATE TABLE Company(Name text, Country text);
I am referring to attribute Name which appears twice in two tables. Will it affect or distorts some of the SQL queries execution in the database?
If you had tried it (in the command-line shell or on SQLFiddle), you would have found out that it is allowed.
However, it can affect your queries.
When you join these two tables, you have to explicitly specifiy which table's column you want:
CREATE TABLE Employee(ID, CompanyID, Name, Phone_number);
CREATE TABLE Company(ID, Name, Country);
SELECT Company.Name,
Employee.Name,
Phone_number
FROM Company
JOIN Employee ON Company.ID = Employee.CompanyID;
On the other hand, if you have a foreign key relationship, using the same name in both tables allows you to simplify the join condition:
CREATE TABLE Employee(EmployeeID, CompanyID, Name, Phone_number);
CREATE TABLE Company(CompanyID, Name, Country);
SELECT Company.Name,
Employee.Name,
Phone_number
FROM Company
JOIN Employee USING (CompanyID);

SQLite regular table and table for fts

I have table news (id, news_id, news_title) and I creat FTS table:
CREATE VIRTUAL TABLE news_search USING fts4 (news_title, tokenize=porter);
I use trigger to keep table NEWS and news_search in sync:
CREATE TRIGGER IF NOT EXISTS insert_news_trigger
AFTER INSERT ON news
BEGIN
INSERT OR IGNORE INTO news_search (news_title) VALUES (NEW.news_title);
END;
Question: how to use search? When I do MATCH in news_search table it returns me only records from this table, but I need *news_id* from news table. May be I should add *news_id* column to news_search table?
What is the proper way to use fts in sqlite?
Read the documentation; FTS tables also have a rowid column (also called docid) that you can set explicitly to the same value as the corresponding key of the original table.
Assuming that news.id is the rowid (i.e., INTEGER PRIMARY KEY), you should change your trigger to also copy that ID value into the news_search table.
You can the use that to look up the original record:
SELECT *
FROM news
WHERE id IN (SELECT docid
FROM news_search
WHERE news_title MATCH '😸')

I need to alter a sqlite3 table to add FTS3

I need the ability to add FTS3 to a sqlite3 table after it was created, not as it is created. Does anyone know the ALTER syntax to accomplish this?
SQLite does not support altering a table from a normal table to an FTS3 table. All you can do with ALTER TABLE is change the table name or add columns.
You will have to use CREATE VIRTUAL TABLE to make the FTS3 table and then copy the data.

Resources