Check if similar row with same ID is already inserted into table? - java

I have a Car table with columns carID, brand, color, price. I'm copying carID and color to another table Detail which have columns carID, finish, color (with carID being a foreign key from Car table and the finish column is not NULL).
I have an SQL Prepared Statement:
public void insertToDetail(int carID, String finish){
String sql = "INSERT INTO detail (carID, finish, color) SELECT ?, ?, color FROM car WHERE carID = ?;";
PreparedStatement psmt = connect.prepareStatement(sql);
psmt.setString(1, carID);
psmt.setInt(2, finish);
psmt.setInt(3, carID);
psmt.executeUpdate();
psmt.close();
}
How may I check if an exact same carID value is not already inserted into my Detail table?
I tried something like:
"INSERT INTO detail (carID, finish, color)
SELECT ?, ?, color FROM car
WHERE NOT EXISTS {
SELECT carID
FROM detail
WHERE carID = ?
} ;";
And it gave me the error:
MySQLSyntaxError You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near '{ SELECT carID FROM detail WHERE carID = 123 }' at
line 1

The query you are trying to write is:
INSERT INTO detail (carID, finish, color)
SELECT ?, ?, color
FROM car
WHERE NOT EXISTS (SELECT carID
FROM detail
WHERE carID = ?
) ;
However, NOT EXISTS is the wrong approach. Let the database do the checking. So create a unique index:
CREATE UNIQUE INDEX unq_detail_carid on detail(carID);
This will generate duplicate car ids in the table. An insert will return an error if a duplicate is generated.
To prevent the error, use ON DUPLICATE KEY UPDATE:
INSERT INTO detail (carID, finish, color)
SELECT ?, ?, color
FROM car
ON DUPLICATE KEY UPDATE carID = VALUES(carID);

Your sql have syntax error,need to change {} to () and remove ; at the end
so change
"INSERT INTO detail (carID, finish, color) SELECT ?, ?, color FROM car WHERE NOT EXISTS {
SELECT carID FROM detail WHERE carID = ?;";
to
"INSERT INTO detail (carID, finish, color) SELECT ?, ?, color FROM car WHERE NOT EXISTS (
SELECT carID, finish, color FROM detail WHERE carID = ?)";

Related

How to add to INSERT INTO PRIMARY KEY AND FOREIGN KEY

So i have two tables: locations and employees i want locations_id to be the same in employees.locations_id, I am trying to make it all in one statement
the erros is this You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO employees(employees_id, locations_id) VALUES('e1598','')' at line 1
String sql = " INSERT INTO locations( locations_id , username, password, id, type_of_id, first_name, last_name, phone, email, date_of_birth, address, sex ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
**Error here --->** + "INSERT INTO employees(employees_id,locations_id) VALUES (?,SELECT locations_id FROM locations INNER JOIN employees ON locations.locations_id =employees.locations_id)";
try {
MicroModelGUI micro = new MicroModelGUI();
PreparedStatement consulta = micro.connection.prepareStatement(sql);
consulta.setString(1, tflid.getText());
consulta.setString(2, tfuser.getText());
consulta.setString(3, tfpass.getText());
consulta.setString(4, tfid.getText());
consulta.setString(5, tftoid.getText());
consulta.setString(6, tffirst.getText());
consulta.setString(7,tflast.getText());
consulta.setString(8,tfphone.getText());
consulta.setString(9,tfemail.getText());
consulta.setString(10,tffdn.getText());
consulta.setString(11,tfaddress.getText());
consulta.setString(12,tfsex.getText());
consulta.setString(13,tfeid.getText());
int resultado = consulta.executeUpdate();
You should be using an INSERT INTO ... SELECT here:
INSERT INTO employees (employees_id, locations_id)
SELECT ?, l.locations_id
FROM locations l
INNER JOIN employees e ON l.locations_id = e.locations_id;
To the ? placeholder you would bind a value from your Java code. Note that while your version of SQL might support putting a scalar subquery into a VALUES clause, it is likely that your exact version would cause an error, as it would return more than one row.

I am trying to only insert a new record into the database if that record doesn't already exist but it isn't working

Here is my code to check to see if a record already exists in the system before entering ther new record to the sql database.
String sql = "INSERT INTO Stock (name, cost_price, selling_price, numberinstock, supplier) VALUES (?, ?, ?, ?,?) "
+ "Select name"
+ " from Stock"
+ "Where not exists (select * from Stock"
+ "where name = "+NameTextField+")";
I am using Java, my sql and a derby database.
What I am trying to do is when a new item is entered into the system, the sql statement will check to see if that items is already in the system.
What is wrong with this sql statement
You cannot do what you want using insert . . . values. So use insert . . . select instead. The code should look like this:
INSERT INTO Stock(name, cost_price, selling_price, numberinstock, supplier)
Select ?, ?, ?, ?, ?
from sysibm.sysdummy1
Where not exists (select * from Stock where name = "+NameTextField+");
However, you should pass the second reference to name as a parameter, just like all the others:
INSERT INTO Stock(name, cost_price, selling_price, numberinstock, supplier)
Select ?, ?, ?, ?, ?
from sysibm.sysdummy1
Where not exists (select 1 from Stock where name = ?);
try using trigger
Create Trigger Modified_Order_Trigger
On Orders
After Update --as per youe need "insert, delete, update"
AS
Insert Into tablename (tables fileds)
SELECT tablefileds
FROM INSERTED

query to add data into "CLOB" column

"INSERT into FOLDET (FOLDER_ID, FIELD_NAME, OP_VALUE, "
+ "FIELD_VALUE, FOLDER_FIELD_TYPE, DISPLAY_FLAG ) values \n"
+ "( ?, ?, ?, ?, ?, ?) \n" ;
we use the above query to insert values into the table FOLDET
for column FIELD_VALUE the datatype is varchar(32000) , if the string length is greater than 32000 , we want to store the string in new column of CLOB type eg:- say if the new column name is FLD_VAL_EXT of CLOB type added to the table FOLDET
i want a query to add the string to the new column if the value is greater than "32K"
The Oracle JDBC tutorial covers this well: Blob Insert Example
Basically setup the Clob by writing to its character stream before insert.

SQL INSERT with loop with multiple rows

I'm trying to insert skeleton data into a database using jdbc.
So far my code is:
Statement st=con.createStatement();
String sql = "INSERT INTO student (studentid, titleid, forename, familyname, dateofbirth) "
+ "VALUES (1, 1, 'forename1', 'surname1', '1996-06-03');";
I need to create 100 entries for this and I'm not too sure how to go about doing it.
All I want is the student id, titleid, forename and familyname to increment by 1 until it reaches 100 entries with those rows filled in, date of birth doesn't need to be altered. I'm asking how to do a loop for this
General answer - You should use PrepareStatement instead of Statement and execute as batch.
Common way to insert multiple entry or execute
String sql = "INSERT INTO student (studentid, titleid, forename, familyname, dateofbirth) "
+ "VALUES (?, ?, ?, ?, ?);";
ps = connection.prepareStatement(SQL_INSERT);
for (int i = 0; i < entities.size(); i++) {
ps.setString(1, entity.get...());
...
ps.addBatch();
}
ps.executeBatch();
Important Note:
Why you should use PrepareStatement Over Statement
SQL Injection Example
There are two ways to do this. You can put your insert query inside a loop or you can put your loop inside an insert query. I have found that the better method depends on the database engine (but I've never used postresql) and the number of records you want to insert. You could bump up against the maximun query length or number of parameters or something.
The following code sample is ColdFusion, but it is intended to show the general idea of having a loop inside a query. You would have to write equivalent code in java.
<cfquery>
insert into yourtable
(field1
, field2
, etc)
select null
, null
, null
from SomeSmalllTable
where 1 = 2
<cfloop>
union
select <cfqueryparam value="#ValueForField1#">
, <cfqueryparam value="#ValueForField#">
, etc
</cfloop>
</cfquery>

One-to-many query while limiting based on distinct primary key

I have a table like this:
create table images (
image_id serial primary key,
user_id int references users(user_id),
date_created timestamp with time zone
);
I then have a tag table for tags that images can have:
create table images_tags (
images_tag_id serial primary key,
image_id int references images(image_id),
tag_id int references tags(tag_id)
);
To get the results I want, I run a query like this:
select image_id,user_id,tag_id from images left join images_tags using(image_id)
where (?=-1 or user_id=?)
and (?=-1 or tag_id in (?, ?, ?, ?)) --have up to 4 tag_ids to search for
order by date_created desc limit 100;
The problem is, I want to limit based on the number of unique image_ids because my output will look like this:
{"images":[
{"image_id":1, "tag_ids":[1, 2, 3]},
....
]}
Notice how I group the tag_ids into an array for output, even though the SQL returns a row for each tag_id and image_id combo.
So, when I say limit 100, I want it to apply to 100 unique image_ids.
Maybe you should put one image on each row? If that works, you can do:
select image_id, user_id, string_agg(cast(tag_id as varchar(2000)), ',') as tags
from images left join
images_tags
using (image_id)
where (?=-1 or user_id=?) and
(?=-1 or tag_id in (?, ?, ?, ?)) --have up to 4 tag_ids to search for
group by image_id, user_id
order by date_created desc
limit 100;
If that doesn't work, then use a CTE:
with cte as (
select image_id, user_id, tag_id,
dense_rank() over (order by date_created desc) as seqnum
from images left join
images_tags
using (image_id)
where (?=-1 or user_id=?) and
(?=-1 or tag_id in (?, ?, ?, ?)) --have up to 4 tag_ids to search for
)
select *
from cte
where seqnum <= 100
order by seqnum;
Select 100 qualifying images first, and then join images_tags.
Use an EXISTS semi-join to satisfy the condition on images_tags and take care to get the parentheses right.
SELECT i.*, t.tag_id
FROM (
SELECT i.image_id, i.user_id
FROM images i
WHERE (? = -1 OR i.user_id = ?)
AND (? = -1 OR EXISTS (
SELECT 1
FROM images_tags t
WHERE t.image_id = i.image_id
AND t.tag_id IN (?, ?, ?, ?)
))
ORDER BY i.date_created DESC
LIMIT 100
) i
LEFT JOIN images_tags t
ON t.image_id = i.image_id
AND (? = -1 OR t.tag_id in (?, ?, ?, ?)) -- repeat condition
This should be faster than a solution with window functions and CTEs.
Test performance with EXPLAIN ANLAYZE. As always run a couple of times to warm up cache.

Categories

Resources