Add a new entry with link in a table - java

I bought the deitel java how to program book. I am following one of their exercises.
In my program I am connected to a mysql books database. I was able to add a new author, edit author, new title. However, part d) is confusing to me. Am I suppose to alter the table and add a foreign key?
Here are the exercises from the book so you can see part d)
a) Add a new Author
b) Edit the existing information for an author
c) Add a new title for an author (Remember that the book must have entry in the AuthorISBN table.)
d) Add a new entry in the authorISBN table to link authors with titles.
Here is a screen shot of the database open in "toad"
If they mean to write a sql statement would I add a new AuthorID with a reference to title?
ALTER TABLE AuthorISBN ADD FOREIGN KEY (AuthorID) REFERENCES title (AuthorID);

You are not supposed to alter the table. I assume they have given you the structure of the tables (the screenshot) and you are supposed to add new entries in all parts of the exercise. In d) they want you to add an entry to the table AuthorISBN, so that two entries in Author and Title are logically connected.
AuthorISBN consists of two data fields. AuthorID and ISBN are foreign keys, so for every entry in the table AuthorISBN there has to be an adequate entry with the same AuthorID in the table Authors and a an entry with the same ISBN in Titles.
So in a) you add an author. The AuthorID is automatically incremented, so you have to retrieve the ID after you inserted the author. In c) you add a book by this author. But how you know later, which author wrote a specific book? Or you want to retrieve a list of all book by an author. Thats why you add in d) an entry to AuthorISBN.
So with JDBC you would do something like this:
Statement stmt = connection.createStatement();
String sql = "INSERT INTO AuthorISBN VALUES (" + authorID + ", '" + isbn + "')";
stmt.executeUpdate(sql);

Related

Building a list with some hierarchical elements

I have a SQL table describing books in the online library. it looks like this:
create table if not exists BOOKS (
BOOK_ID char(36) default (UUID()) not null,
TITLE varchar(255) not null,
URL varchar(512),
PUBLISHED_ON date,
ISBN varchar(24),
ANNOTATION text,
COMMENTARY text,
RATING tinyint,
SERIES_ID char(36),
SERIES_VOL_NUM tinyint,
constraint BOOK_PK primary key (BOOK_ID),
constraint FK_BOOKS_SERIES foreign key (SERIES_ID) references BOOKS (BOOK_ID)
);
Foreign key to itself needed as books might be linked to a series (like Harry Potter has 7 books and James Bond series has over 40). The hierarchy might be 2, 3 and very rare cases 4 level deep.
I have created Java class Book reflecting the information in the table and another class
public class Series extends Book {
#JsonInclude(JsonInclude.Include.NON_NULL)
private List<Book> volumes;
// setters and getters omitted
}
When I am retrieving book info per given criteria, I am getting a plain list of all books and now I do need to build a list that will contain some hierarchy. I.e. I need to present it like following:
Book1
Book2
Series1
Volume 1 of S1
Volume 2 of S1
Part 1 of V2S1
Part 2 of V2S1
Volume 3 of S1
Book3
Book4
Series2
Volume1 of S2
Volume2 of S2
etc.
It is not a tree ( in that case I'd use recursion) and I am wrecking my brain on how to do it effectively. If someone can give me a hint, I will appreciate it.

How to search and copy information from two tables in SQLite on Java?

Beginner here.
I have this problem: I have two tables in my database. Table Customers and table Parcels. The program should find a customers id number from table Customers, when the user types the customers name. Then copy the customers id to table Parcels under column "customer_id".
Here is what I have done, but NetBeans gives me the Index out of bound exception. I have also tried another way, but then the program thinks I am trying to access a column by the name of the users feed. (I have created the tables in another if clause) What should I do differently? Here is my code:
} if (feed.equals("4")) {
System.out.println("Add tracking number: ");
String tn = input.nextLine();
PreparedStatement a = db.prepareStatement("INSERT INTO Parcels(tracknumb,cust_id) VALUES(?,?)", Statement.RETURN_GENERATED_KEYS);
a.setString(1, u);
System.out.println("Add customer name: ");
String nameid = input.nextLine();
PreparedStatement y = db.prepareStatement("SELECT id FROM Customers WHERE name= ?");
y.setString(2, nameid);
ResultSet rl = y.executeQuery(nameid);
if(rl.next()) {
int id = rl.getInt(nameid);
a.setInt(2, id);
I'm pretty sure the problem is within your SQL requests.
You're trying to insert ? into one of your values in the database, but keep in mind that ? is something unknown to the SQLite database.
If you're trying to insert an empty value, insert NULL. If you're trying to insert something from somewhere else, try {0}, and add , yourValue.
Try this out and see if it works.
Note: If you still want to use questions marks within your database, type \"?\" or '?'. This way, if you've configured your table to use strings or chars, this will work.

SQL: delete items from table based on their ID, which also appears in another table

long story short, I have a coupon system project.
in it I have companys, coupons and customer.
all of their data is save in an SQL DB, based on apache derby.
for example:
a company exist on the company table. has id, name, password, email
a coupon exist on the coupon table. has id, title, price, etc..
only a company can create a coupon, and what it does, not only it is created on the coupon table mentioned above, it is also populating a second 'index' table, joining company's and coupons= company_coupon. has company_id, coupon_id
now everything else in the project is working beautifully, and the tables are checked by my teachers and everything is configured correctly.
what I'm trying to do next, and just cant seem to figure out the syntax for is:
when I delete a company, I also want to delete every coupon this company has created, from the coupon table. this I do by searching the company_coupon table for company_id matches, and deleting based on the coupon_id paired with them.
I'm trying this statment:
String sql = "DELETE FROM coupon INNER JOIN company_coupon ON id = company_coupon.coupon_id WHERE company_coupon.company_id = "
sql += companyObject.getId();
<-- method is getting an object and I have access to it's id, but I tried hard coding a specific company id and still..
the same error keeps coming back in different variations:
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "INNER" at
line 1, column 8.
I searched online here and elsewhere, was advised to add an 'alias' after the DELETE. got the same error, pointing at that extra word:
"DELETE c FROM coupon INNER JOIN company_coupon ON id = company_coupon.coupon_id WHERE company_coupon.company_id = " ---->>
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "c" at
line 1, column 8.
any ideas? :(
You might need two delete statements:
delete from company where id=1;
delete from company_coupon where id_company=1;
If your database supports cascade deletes on foreign keys, you might need just one delete statement.
Take a look at: http://sqlfiddle.com/#!7/86102/6 (click "Run SQL" and scroll down to the bottom of the result, try changing the sql yourself)
Solved:
String sql = "DELETE FROM customer_coupon WHERE coupon_id IN (SELECT company_coupon.coupon_Id FROM company_coupon WHERE company_coupon.company_id = ";
sql += comp.getId();
sql += ")";

I want to display foreign keys in one table from other tables, but I get foreign key mismatch error

I'm very new to SQL and I want the contracts_tb (query details below) is to display and link the foreign id keys referred from:
med_idref (referred from med_id (INTEGER), PRIMARY KEY o mediaadv_tb),
mediatitle_ref (title (TEXT), mediaadv_tb),
mediatype_red (mtype (TEXT), mediaadv_tb),
cus_idref (cus_id (INTEGER),PRIMARY KEY of customer_tb),
cus_companyref (referred from company (TEXT), in customer_tb)
All to be linked and displayed to contracts_tb. When I add/replace values from mediaadv_tb and customer_tb, I get this problem:
foreignkey mismatch
Also, do I have to make or assign a parent table?
Query:
DROP TABLE IF EXISTS customer_tb;
CREATE TABLE IF NOT EXISTS customer_tb (
cus_id INTEGER PRIMARY KEY,
company TEXT,
firstname TEXT,
middlename TEXT,
lastname TEXT,
gender TEXT,
dob TEXT,
dateregistered TEXT,
contactno TEXT,
emailaddress TEXT,
description TEXT,
refpic INTEGER,
cuspic BLOB
);
DROP TABLE IF EXISTS mediaadv_tb;
CREATE TABLE IF NOT EXISTS mediaadv_tb (
med_id INTEGER PRIMARY KEY,
mtype TEXT,
duration TEXT,
title TEXT,
dateadded TEXT,
desription TEXT,
previewimg BLOB,
filepath TEXT
);
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
media_typeref TEXT REFERENCES mediaadv_tb(mtype),
media_titleref TEXT REFERENCES mediaadv_tb (title),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
Error :-
contracts_tb
mediaadv_tb
I believe that your issue is because the foreign keys defined that reference the media_typeref and the media_titleref columns are invalid as they do not have, or are part of a, UNIQUE indexes (no indexes). SQLite Foreign Key Support - 3. Required and Suggested Database Indexes
The referenced id columns, as they are INTEGER PRIMARY KEY, are implicitly UNIQUE indexes.
Furthermore the two columns (typeref and titleref) themself aren't even needed as the media_idref column would be used to identify the reference and thus would hold the respective values. Copying those values into the contracts table would be contrary to normalisation and may even create major headaches (e.g. if a value changed you'd have to find all other uses and also change them).
As such I'd suggest that the contracts_tb be created using :-
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
Re comment :-
What i'm making is a Java NetBeans SQLite database program, where by
using the Contracts frame, whevenr one makes a new contract, there
will be a combobox that restricts the user to only put the existing
ids or names that is referred in the contracts_tb then provides the
choices. Is it possible sir?
Yes.
More specifically:-
Assume that you have customers Fred, Bert and Harry (id's 1,2 and 3 respectively). And that you have mediaadv's M1, M2 and M3 (id's 10,11 and 12 (not 1,2 and 3 to help distinguish between mediaadv and customers)).
Additionally I'll assume the suggested contracts_tb table as opposed to the original in the question (i.e. 2 columns dropped as suggested)
The when inserting a new contract, you present a list (combobox) of the customers e.g.
Fred
Bert
Harry
(this list could be generated from a query such as:-
SELECT cus_id,firstname FROM customer_tb; i.e. all existing customers)
If you wanted Fred James Bloggs then you could use :-
SELECT cus_id,firstname||' '||middlename||'lastname' AS fullname FROM customer_tb;.
Likewise a list of the existing mediaadv could be generated from a query such as:-
SELECT med_id, description FROM mediaadv_tb; e.g.
so the combobox would have:-
M1
M2
M3
Now if the contract were for Bert (id 2) and M1 (id 10) then you build SQL something like :-
INSERT INTO contracts_tb VALUES(null,2,10,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
1st value is null i.e. no value, so as contract_id is an alias of the rowid it will be generated.
2 is the id of the customer (hence why cus_id was in the query as you need the id as it's the value you are going to store)
10 is the id of the mediaadv (again hence why med_id was in the query as you need the id as it's the value you are going to store).
the other values are what they should be.
Note the above use of INSERT requires that all columns be given. You can skip columns by specifying a list of the columns e.g. INSERT INTO contracts_tb (customer_idref,media_idref) VALUES(2,10);
As a customer with an cus_id of 2 (Bert) exists then the constraint that customer_idref is an existing id in the customer_tb is good/met and there is no conflict.
Likewise as there is a row in mediaadv_tb that has an med_id of 10 this constraint is good/met and there is no conflict.
However say the SQL were :-
INSERT INTO contracts_tb VALUES(null,2,100,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
Then as there is no med_id of 100 the constraint saying that media_idref must reference a value of 100 (in this instance) in the mediaadv_tb, column med_id, then the constraint will not be met and the insert will fail.
So again Yes, I believe that what you want is feasible.
Note a foreign key is only a constraint it doesn't bind/associate columns or join tables.

Updating a SQL table

I am doing a Java program in which I am reading input from some files and if it contains any string that I have in my list I have to update the table with name and its count.
First i created a table as follows
create table mobile(name varchar2(20),count int,primary key(name));
for instance,if I read string like "Sony unviels its new phone", table must be updated with name as sony count as 1.
what my doubt is initially it is an empty table. Can we update it as I said.
Thanks in advance....
First table creation
CREATE TABLE mobile
(
t_name VARCHAR (20),
t_count NUMBER,
PRIMARY KEY (t_name)
);
And insert statement
INSERT INTO mobile
VALUES ('Sony', 1);
Single statement for insert and update
MERGE INTO mobile t
USING (SELECT *
FROM mobile
WHERE LOWER (t_name) = 'sony') s
ON (t.t_name = s.t_name)
WHEN MATCHED
THEN
UPDATE SET t.t_count = t_count+1
WHEN NOT MATCHED
THEN
INSERT (t_name, t_count)
VALUES ('sony', 1);
Either you prepopulate you table with your given word list so something like
CREATE TABLE mobile(
name varchar2(20),
count_column int,
primary key(name)
);
INSERT INTO mobile (name, count_column) VALUES
('Sony', 0);
or you are adding some magic to your Java code which is deciding whether to do an UPDATE or an INSERT.
As an simple would look like theoretical
UPDATE mobile SET count_column to count_column+1 where name = 'Sony';
this will fail if there is none entry given.
You will have to execute an UPSERT like query , since oracle doesn't have it, you have to do a workaround to resolve this. please check this .

Categories