How can I pass text or strings using SQLite JDBC? - sqlite

I am having this problem using JDBC.
I can create a table called food.db with text fields breakfast, lunch, dinner. When I call the following....
statement.executeUpdate("create table food (breakfast string, lunch string, dinner string)");
breakfast = JOptionPane.showInputDialog("What was your breakfast?");
lunch = JOptionPane.showInputDialog("What was your lunch?");
dinner = JOptionPane.showInputDialog("What was your dinner?");
statement.executeUpdate("insert into food values(\'"+breakfast+"\', \'"+lunch+"\' ,\'"+dinner+"\')");
That last statement, however, results in an error. For whatever reason, it says that whatever I type in for "breakfast" (for example, oatmeal) is not a column, even though I know that I can use SQLite's syntax in this way to update columns.
Also I have checked the argument to executeUpdate(), and the syntax with single quotes and everything matches up...I have tried text and string column fields, get the same error for both.

Try this
change string to VARCHAR(SIZE) OR TEXT
statement.executeUpdate("CREATE TABLE food (breakfast VARCHAR(25), lunch VARCHAR(25), dinner VARCHAR(25))");
String breakfast = JOptionPane.showInputDialog("What was your breakfast?");
String lunch = JOptionPane.showInputDialog("What was your lunch?");
String dinner = JOptionPane.showInputDialog("What was your dinner?");
statement.executeUpdate("INSERT INTO food (breakfast, lunch , dinner) VALUES ('"+breakfast+"', '"+lunch+"' ,'"+dinner+"')");

Change your CREATE TABLE to
statement.executeUpdate("create table food (breakfast text, lunch text, dinner text)");
Your INSERT INTO statement is escaping single ' quotes which isn't required. Change to
statement.executeUpdate("insert into food values('"+breakfast+"', '"+lunch+"' ,'"+dinner+"')");
There's no string data type in SQLite but it doesn't give an error because SQLite's SQL isn't strongly typed. The column affinity takes over and treats any unknown data type as NUMERIC. Better switch the column data type to TEXT or VARCHAR.

Related

MariaDB Bitemporal Table future dated update not working as expected

As of version 10.4.3 of mariaDB bitemporal tables are supported natively by mariadb.
https://mariadb.com/kb/en/bitemporal-tables/
For an application, I want to create a bitemporal person database.
I have the following setup.
CREATE TABLE IF NOT EXISTS person
(
id INT UNSIGNED,
firstName VARCHAR(255),
lastName VARCHAR(255),
maritalStatus VARCHAR(255),
validFrom DATE NOT NULL,
validTo DATE NOT NULL,
systemFrom TIMESTAMP(6) AS ROW START INVISIBLE,
systemTo TIMESTAMP(6) AS ROW END INVISIBLE,
PERIOD FOR application_time(validFrom, validTo),
PERIOD FOR system_time(systemFrom, systemTo),
UNIQUE (id, application_time WITHOUT OVERLAPS)
)
WITH SYSTEM VERSIONING;
CREATE INDEX IF NOT EXISTS idx_validFrom ON person (validFrom);
CREATE INDEX IF NOT EXISTS idx_validTo ON person (validTo);
I am creating a bitemporal table person with an application_time which is the business timeline and a system_time which is the system time line. Both are defined as periods.
INSERT INTO zone.person (id,firstName, lastName, maritalStatus, validFrom, validTo)
VALUES (1,'John','Doe','married','2022-10-10','9999-12-31');
Here I am inserting a new Person who is married and this entry is valid from 2022-10-10 till the end of time.
UPDATE zone.person FOR PORTION OF application_time
FROM '2023-10-10' TO '9999-12-31'
SET maritalStatus = 'divorced'
WHERE id = 1;
Now the customer tells me that he will be divorced on '2023-10-10' so I updated the value from married to divorced with the timeframe.
SELECT * FROM person
WHERE '2023-10-10' BETWEEN person.validFrom AND person.validTo
If I query now the business state on '2023-10-10' the result is:
person
id
firstName
lastName
maritalStatus
validFrom
validTo
1
John
Doe
divorced
2023-10-10
9999-12-31
1
John
Doe
married
2022-10-10
2023-10-10
As you can see I get two values but from a business perspective, there could only be one valid maritalStatus at a specific time (date). I would expect one value here. We can see that on the future dated update the validToDate of the initial insert is terminated to the 2023-10-10. But in my opinion, this is wrong shouldn't it be terminated to the 2023-10-09?
Do I understand this implementation wrong or how can I setup mariadb to work this way?

How do you write a when clause with a comparison of several columns in SQLite?

I'm making a SQLite database where I want to have three tables: Users, Books and Bought. Users exists of the columns username, password, name, street, housenumber, postcode and country, where username is the primary key. Books exists of the columns ISBN, year, title, genre, price, author, publisher, summary, numberofpages and amountinstock, where ISBN and year are the primary key. And Bought exists of the columns username, ISBN, year, amount and time, where username, ISBN and year are foreign keys.
I want to add a trigger in such a way that when there will be added a tuple to Bought the SQL will check whether there's enough of that book in stock and if so then it will change the stock number of that book in Books and add the order to Bought.
I've tried already something, but it still gives me a syntax error around the when clauses, but I do not know why.
Here is the insert trigger that I made:
CREATE TRIGGER BoughtInStockTrigger
BEFORE INSERT ON Bought
FOR EACH ROW
WHEN (NEW.amount <= (SELECT SUM(amountinstock) FROM Books B WHERE B.ISBN = NEW.ISBN AND B.year = NEW.year))
BEGIN
UPDATE Books
SET amountinstock = amountinstock - NEW.amount
WHERE ISBN = NEW.ISBN AND year = NEW.year;
END
WHEN (NEW.amount > (SELECT SUM(amountinstock) FROM Books B WHERE B.ISBN = NEW.ISBN AND B.year = NEW.year))
BEGIN
ROLLBACK;
END;
Where did I make a syntax mistake?

how to create a dynamic database ?

I want to create a dynamic database
with needed as step or flow on this basis..
how can i create database this by through store query or any other way.
I want to need a programmatically.
1)HEALTHY RECIPES CATEGORIES table
1)BreakFast
2)Lunch
3)Dinner
4)chicken & turkey
5)Dessert
...........
2) Breakfast table....
- orange and vanilla protein oatmeal
-chili-chocolote protein oatmeal
.....
3) - orange and vanilla protein oatmeal table
-Ingredients
-directions
Thanks All to in Advance...
I understand that you'd like to use SQLite. Run SQLite client (Sqliteman or similar), create a new database and run the below as a script:
create table category (
category_id integer not null primary key,
name varchar(80) not null
);
create table meal (
meal_id integer not null primary key,
name varchar(80) not null,
directions text
);
create table meal_category (
meal_category_id integer primary key,
meal_id integer not null references meal,
category_id integer not null references category
);
You can then insert data like this:
insert into category (category_id, name) values (1, 'Breakfast');
insert into category (category_id, name) values (2, 'Lunch');
insert into meal (meal_id, name) values (1, 'Orange and vanilla protein oatmeal');
insert into meal (meal_id, name) values (2, 'Chili-chocolote protein oatmeal');
insert into meal_category (meal_category_id, meal_id, category_id) values (1, 1, 1); -- meal 1 is a breakfast
insert into meal_category (meal_category_id, meal_id, category_id) values (2, 2, 1); -- meal 2 is a breakfast
And query it like this:
select m.name || ' is ' || c.name from meal m
join meal_category mc on m.meal_id = mc.meal_id
join category c on mc.category_id = c.category_id;
It's the simplest design. You may want to add additional fields and some indexes - please check tutorials on SQL how to do it. Anyway the above will give you a working SQLite database.
You may need table "ingredient" which will keep data of anything which can be used for a recipe (egg, flour, water etc) and "meal_ingredient" which will tell if an ingredient should be present in a meal. Text of the recipe can be kept in meal.recipe field.
Note that there are different ways to design a database and typically you should provide a detailed specification of the system which will use the database to have a good design.
It's best if you think what the database will be used for, what kind of data you want to get from it and then read on SQL and do some experiments on your own. For example, if you want to be able to look for any meal which uses flour, it's best to have ingredients in a separate table, linked to meal - just like a category is linked to a meal, it's called a "many to many relationship". But if you don't care about such a functionality, both recipe and a list of ingredients could be put in meal.recipe field. Design of the database should reflect your needs and the part of reality you want to have a model of.

SQLite select statement to extract part of string

This should be an easy one for someone with more SQLite experience than myself.
I need a select statement to get the name out of the following example string:
{"email":"12345678#facebook.com","user_key":"FACEBOOK:12345678","name":"John Smith"}
The output I need is John Smith.
The number of characters before the name is not always the same so a simple substr command won't work. It needs to be dynamic so it can locate where the name starts and then spit it out. I think ltrim or rtrim may help, but even after researching those commands, I don't understand them very well. Also, SQLite doesn't offer instr or position, which might have been helpful, too!
Edit: the schema for this table is as follows:
CREATE TABLE messages (msg_id TEXT PRIMARY KEY, thread_id TEXT, action_id INTEGER, subject TEXT, text TEXT, sender TEXT, timestamp_ms INTEGER, timestamp_sent_ms INTEGER, attachments TEXT, shares TEXT, msg_type INTEGER, affected_users TEXT, coordinates TEXT, offline_threading_id TEXT, source TEXT, channel_source TEXT, is_non_authoritative INTEGER, pending_send_media_attachment STRING, handled_internally_time INTEGER, pending_shares STRING, pending_attachment_fbid STRING, client_tags TEXT, send_error STRING, send_error_message STRING, send_error_timestamp_ms INTEGER, publicity TEXT, tracking TEXT );
CREATE INDEX messages_offline_threading_id_index ON messages ( offline_threading_id );
CREATE INDEX messages_timestamp_index ON messages ( thread_id, timestamp_ms DESC );
CREATE INDEX messages_type_index ON messages ( thread_id, msg_type, timestamp_ms );
The string I have above that I'm working with is from the sender column.
I don't know the language you're using but most of them support user defined functions (http://www.sqlite.org/c3ref/create_function.html) and you could do
select jsonGetName(columnWithJsonText) from messages where ...
It's like a callback to your programming language where you defined which C/Java/PHP function gets called when using jsonGetName() in sqlite.
In that function (in your language of choice) you decode the json string and return the name property.

Pl/SQL procedure with single Parameter

I have create the following tables...
CREATE TABLE Actor
(Actor_ID CHAR(5),
lastName CHAR(24),
firstName CHAR(24),
/
CREATE TABLE Movie
(movieID CHAR(3) ,
title CHAR(36),
year NUMBER,
/
CREATE TABLE Role
(roleID CHAR(5),
roleName CHAR(36),
actorID CHAR(5),
movieID CHAR(3))
/
CREATE TABLE Quote
(quoteID CHAR(4),
quoteCHAR CHAR(255))
/
CREATE TABLE RoleQuote
(roleID CHAR(5),
quoteID CHAR(4))
/
Then i created this schemas....
CREATE TYPE ACTOR_QUOTE_TYPE AS OBJECT (
Movie_Title CHAR(36),
Year NUMBER,
Role CHAR(36),
Quote CHAR(255)
)
/
CREATE TYPE AQ_NT AS TABLE OF ACTOR_QUOTE_TYPE
/
CREATE TABLE ACTOR_QUOTES (
ACTORID CHAR(5),
QUOTES AQ_NT
) NESTED TABLE QUOTES STORE AS ACTOR_QUOTES_NT
/
I need to create a procedure with a single parameter(ACTORID is procedure parameter) and insert all the quotes in all the movies for any ACTORID, into the row(s) (an actor may have many movies and many quotes, some may have no quotes!) of the QUOTES nested table in the ACTOR_QUOTES table for any ACTORID.
How do i do it ?
Thanks
So far i tried this, i am not sure it is correct or not.
CREATE OR REPLACE PROCEDURE Populate_Movies_Quote
AS
CURSOR Quote_cursor (ActorID in CHAR) IS
SELECT ActorID, Quote, Movie_Title from Actor_Quotes, AQ_NT where Quotes.ActorID=ActorID;
BEGIN
FOR row IN Quote_cursor
LOOP
INSERT INTO ACTOR_QUOTES (ActorID, quotes) values (row.ActorID, AQ_NT(Actor_Quote_Type));
END LOOP;
END Populate_Movies_Quote ;
/
Show erros
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1 PL/SQL: SQL Statement ignored
4/55 PL/SQL: ORA-04044: procedure, function, package, or type is not
allowed here
6/1 PL/SQL: Statement ignored
6/10 PLS-00306: wrong number or types of arguments in call to
'QUOTE_CURSOR'
This certainly looks familiar. I take it someone else is stuck with Paul Judges Assignment too.
Without doing this for you here's the basic strategy I took.
First just write a select query that returns Movie Title, Movie Year, Role Name, and the Quote for a given Actor ID in that order. Forget about the procedure for now just get this select statement working. It means joining all the tables in the where clause.
If you achieve that then you basically have all the data that needs to be inserted into the nested table.
You can access the nested table for insertion by using the table function. So something like:
INSERT INTO TABLE(SELECT QUOTES FROM Actor_Quotes WHERE ActorID = Actor_ID)
Where "Actor_ID" is the name of your procedures parameter. PL/SQL actually lets you insert into a table values directly from a select statement. You just have to ensure the values returned by the select statement match the order and type that your insert statement is expecting. This is pretty handy as it means there is no need for a cursor loop. So essentially all you have to do is place the select statement I said to write earlier directly below the above insert statement and you should be sorted. Make sure you use the same Actor_ID Parameter in your select query though.

Resources