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 '😸')
Related
I have a table with two columns (ldap, name). I want to be able to full text search any of those columns with the library FTS4. Here I have a couple of statements I'm using to create the virtual table but when I create a statement using Match the result is empty although it should return data.
CREATE VIRTUAL TABLE IF NOT EXISTS sales_rep USING FTS4(ldap,name, content="__sales_rep");
CREATE TRIGGER IF NOT EXISTS __sales_rep___after_insert AFTER INSERT ON __sales_rep BEGIN INSERT INTO sales_rep (ldap, name) VALUES (new.ldap, new.name);END;
I am inserting a row (ldap, name) VALUES ('test', 'Bryan');
But using
SELECT * FROM sales_rep where name MATCH 'Bry';
The result is empty
Inserting data in an external content FTS table requires to provide explicitly a value for the docid, which should be the rowid of the content table.
In your case you need to change the trigger :
CREATE TRIGGER __sales_rep___after_insert
AFTER INSERT ON __sales_rep
BEGIN
INSERT INTO sales_rep (docid, ldap, name)
VALUES (new.rowid, new.ldap, new.name);
END;
I have two SQLite files, each of them has one table and the same table design. One Column is set as Primary Key. I want to copy all data from ItemsB into ItemsA. All data should be updated. The ItemsB Table is the newer one.
I've tried:
ATTACH DATABASE ItemsB AS ItemsB;
INSERT INTO ItemsA.PMItem (ItemID,VarID,Name1) SELECT ItemID,VarID,Name1 FROM ItemsB.PMItem;
Obviously this can't work due the Primary Key (which is the column VarID).
Then I tried it with ON CONFLICT:
ON CONFLICT (VarID) DO UPDATE SET Name1=excluded.Name1
But this won't work either.
Example Table:
CREATE TABLE PMItem (
ItemID INTEGER,
VarID INTEGER PRIMARY KEY,
Name1 TEXT
);
You need a WHERE clause with an always true condition, to overcome the ambiguity that is raised when ON CONFLICT is used after a SELECT statement:
INSERT INTO PMItem (ItemID,VarID,Name1)
SELECT ItemID,VarID,Name1
FROM ItemsB.PMItem
WHERE 1
ON CONFLICT(VarID) DO UPDATE
SET Name1 = EXCLUDED.Name1;
This should be an easy one. I need the SQL to insert into a table that has only one column and it is and autoincrement field.
Similar to this post but SQLite (I am new to SQLite).
Inserting rows into a table with one IDENTITY column only
create table ConnectorIDs
(
ID integer primary key AUTOINCREMENT
);
--none of the following work
INSERT INTO ConnectorIDs VALUES(DEFAULT);
INSERT ConnectorIDs DEFAULT VALUES;
Yes this is strange and if you care here is the reason, if you want to tell me a better way. I have several different item tables that all can have many-to-many links between them but sparse. Instead of having n! bridge tables, or one bridge table with a "Type" that I can't guarantee truly maps to the correct table. I will have one ConnectorID table and each item with have a connectorID key. Then I can have one bridge table.
Insert a null value:
INSERT INTO ConnectorIDs VALUES(NULL);
From the docs:
If no ROWID is specified on the insert, or if the specified ROWID has a value of NULL, then an appropriate ROWID is created automatically.
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.
I currently have a diagnosis table. I want to make the code and description fields searchable using FTS. As I understand it though, FTS tables don't support indexes and I need to be able to lookup Diagnosis by diagnosisID very quickly. Am I going to have to create a second virtual table with all of the data duplicated just for full text searching or am I missing a solution where I dont have to duplicate all of my diagnosis codes and descriptions?
CREATE TABLE Diagnosis (
diagnosisID INTEGER PRIMARY KEY NOT NULL,
code TEXT,
collect INTEGER NOT NULL,
description TEXT
);
Turns out an FTS table has a hidden rowid field, which you can populate when you are entering data:
sqlite> create virtual table test1 using fts3;
sqlite> insert into test1 values ("This is a document!");
sqlite> insert into test1(docid,content) values (5,"this is another document");
sqlite> select rowid,* from test1;
1|This is a document!
5|this is another document
You could create an integer field in your standard table that refers to the FTS table by rowid, and move the columns you wish to make text-searchable into the FTS table.
All the info you need here :)