I am working with SQLite. I need to know a query that retrieves all KEYWORDS in SQLite. Ex:
For Oracle: select * from v$reserved_words
For MySQL: select * from mysql.help_keyword
Above query will show all keywords in the corresponding database. Like this, I need a query for SQLite. Anyone knows please let me know.
There is no way to dynamically retrieve the list of reserved words, with a system table or a pragma.
The documentation lists the (currently) 124 keywords. It seems that the actual list also depends on the compile-time options.
Related
I am sure I can solve this programmatically, but I am curious if I can do this in one query.
Context:
I will be querying multiple databases, some will have a table; 'table', others will instead have the table; 'table_v2'. I want to run the same SELECT statement on the table that exists. I know I can check if a table exists, but I want to know if I can do it all in one statement.
psuedo code summary of what I want to do in one statement:
if 'SELECT name FROM sqlite_master WHERE type='table' AND name=''table'; is not empty:
SELECT * FROM table;
else
SELECT * FROM table_v2;
I am beholden to constraints out of my control.
Thoughts:
Could I have the table name be a regex?
Can I run both SELECTS, ignore the failed result, and just return the success?
Generally, you can't do either. The query planner in SQLite needs to know the name of the table beforehand, and it must be valid so it can determine which paths to take.
You can use the loadable extension eval to build up the SQL query based off of the schema. Though, this exposes a variant of the same issue, since the query planner needs the table name, you need to build up the entire SQL statement, then run it, so you'll need two eval calls.
SELECT EVAL(
'SELECT * FROM ''' ||
EVAL('SELECT name FROM sqlite_master WHERE type=''table'' AND name IN (''table'', ''table_v2'');') ||
''';'
);
To use the eval function, you'll need to either build and load the extension as a library, or build it into your own custom build of SQLite itself.
Of course, I can't answer if you should do this.
I'm developing a Rust application for user registration via SSH (like the one working for SDF).
I'm using the SQLite3 database as a backend to store the information about users.
I'm opening the database file (or creating it if it does not exist) but I don't know the approach for checking if the necessary tables with expected structure are present in the database.
I tried to use PRAGMA schema_version for versioning purposes, but this approach is unreliable.
I found that there are posts with answers that are heavily related to my question:
How to list the tables in a SQLite database file that was opened with ATTACH?
How do I retrieve all the tables from database? (Android, SQLite)
How do I check in SQLite whether a table exists?
I'm opening the database file (or creating it if it does not exist)
but I don't know the approach for checking if the necessary tables
I found querying sqlite_master to check for tables, indexes, triggers and views and for columns using PRAGMA table_info(the_table_name) to check for columns.
e.g. the following would allow you to get the core basic information and to then be able to process it with relative ease (just for tables for demonstration):-
SELECT name, sql FROM sqlite_master WHERE type = 'table' AND name LIKE 'my%';
with expected structure
PRAGMA table_info(mytable);
The first results in (for example) :-
Whilst the second results in (for mytable) :-
Note that type is blank/null for all columns as the SQL to create the table doesn't specify column types.
If you are using SQLite 3.16.0 or greater then you could use PRAGMA Functions (e.g. pragma_table_info(table_name)) rather than the two step approach need prior to 3.16.0.
I am using DB Browser for SQLite. The documentation for SQLite's fts3 says "FTS is primarily designed to support Boolean full-text queries". I built a virtual table using fts4 and successfully executed a few WHERE ... MATCH queries. But the following attempts give errors:
SELECT id FROM histsearch WHERE id MATCH ("-1456" IN BOOLEAN MODE);
SELECT id FROM histsearch WHERE NOT EXIST id MATCH ("1457");
Is the problem in DB Browser or in SQLite? How else can I write this query so it will work?
SQLite's full text service (fts3) basically offers Boolean Mode by default, no search modifier needed. DB Browser uses fts's standard query syntax, so NOT is not supported. To exclude a term, do something like
SELECT * FROM indexed WHERE indexed MATCH 'sqlite -database';
Edit: however, you cannot only exclude search terms in fulltext search:
An FTS query may not consist entirely of terms or term-prefix queries with unary "-" operators attached to them.
You'll have to use NOT LIKE for that.
So I'm transferring an old filemaker database to MySQL and some repeating fields are causing me some problems. I've read that the ODBC standard support those fields, only when their types is "Text" and that each repetition is concatenated with a certain delimiter (see page 47 (PDF)). However, I just can't reproduce this. All I get is the first repetition.
If I export the database to the .csv format, the fields are correctly concatenated, so I'm not completely stuck, but if possible, I'd like to be able to obtain the same result with the ODBC connection. Thanks!
With JDBC and Filemaker 12 I can access the repeating field using brackets as it was table beginning with index 1.
It should be the same in ODBC.
Of course I recommend to normalize but it can help to know there is other options.
In my experience the documentation about repeating fields is a lie. :)
If you can get it to work, please, please post an answer. But I imagine you'll have to do the workaround using the csv export.
My recommendation regarding this would be to normalize the repeating fields to a separate table within FileMaker and then perform the transfer of the data. You can create a related table in FileMaker and then use a script to populate the table with the repeating field values. Let me know if you need assistance writing such a script.
I want to provide details about #Signix answer above. I was able to fetch repeating fields from JDBC but it's tricky. At page 30 of FileMaker "ODBC and JDBC Guide", it states:
Note FileMaker repeating fields are supported like arrays.
Example
INSERT INTO mytable(repField[3]) VALUES (‘this is rep 3’)
SELECT repField[1], repField[2] FROM mytable
This is the only documentation! So in theory you could use this query:
ResultSet resultSet = fmStatement.executeQuery("SELECT id, repField[1], repField[2] FROM mytable");
But the tricky part is getting the results. The only way seems to use the column index.
System.out.println(resultSet.getString("repField[1]")); // fails, throws FMSQLException
System.out.println(resultSet.getString("repField[2]")); // fails, throws FMSQLException
System.out.println(resultSet.getString("repField")); // returns repField[1]
System.out.println(resultSet.getString(2)); // returns repField[1]
System.out.println(resultSet.getString(3)); // returns repField[2]
I think the reason is because fields are being named without their bracket parts.
System.out.println(resultSet.getMetaData().getColumnName(1)); // returns "id"
System.out.println(resultSet.getMetaData().getColumnName(2)); // returns "repField"
System.out.println(resultSet.getMetaData().getColumnName(3)); // returns "repField"
So when using resultSet.getString("repField") it returns the first column value with that name. It's stupid but it works.
You can get a list of databases using
PRAGMA database_list
or a list of tables in the "main" database using
select name from sqlite_master where type='table'
but as I just wrote, it only returns the tables from the "main" DB only, and I don't see a way to know which tables are in the other DBs.
So how does one list the tables in the other DBs (which were attached later on)?
Thanks, --DD
PS: I can think of a work around of creating a separate sqlite* for each DB listed via the pragma database_list, and them doing the "select name from sqlite_master where type='table'" N times on those (since each one is the "main" one now), but this sounds like something that should be possible without resorting to the work-around, no???
Ah ah, found the answer by looking at the answer for How do I open an in-memory database file into sqlite3
Since there's a sqlite_master per DB, all I need to do is prefix sqlite_master with "DB_name." where DB_name corresponds to the name column returned by PRAGMA database_list.