inserting data iff there are no duplicated datas in mysql db - mysql

<insert id="insertStockOrderAbusingList" parameterType="java.util.List">
INSERT IGNORE INTO iruda_trade.stock_order_abusing (
market_day,
uid,
stock_account_id,
order_number,
symbol,
conclusion_quantity,
order_type,
created_at
) VALUES
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.transactionDate},
#{item.uid},
#{item.stockAccountId},
#{item.transactionNumber},
#{item.symbol},
#{item.filledVolume},
#{item.transactionType},
#{item.clientTimeStamp}
)
</foreach>
</insert>
I'm trying to insert the datas in mySQL DB. if transactionDate, transactionNumber, and uid from parameters are same with market_day, order_number, uid from stock_order_abusing table columns at the same time, then there will be no insertion or insertion should be ignored. There are no pk(primary key) to compare. All the methods in google are telling me that I should have primary key to prevent duplicated insertion. Are there any ways to deal with this problem?

You can use INSERT IGNORE syntax if you want to take no action when there's a duplicate record.
here is full syntax guide

If you have access to the database structure, you can create unique indexes on the
"uid" field. In this way, the database prevents double entry of data
CREATE UNIQUE INDEX index_name
ON table_name (index_column1, index_column2,...);

Related

How to increment id without auto increment?

I have a table with id column as a number which have meanings. Different types of accounts start from different ranges. E.g Organisation 10000 <-> 100000, users 1000000 <-> 1kk. How can i properly increment ids on insert (with possible concurrency problem)?
If you were doing this in Oracle's table server, you would use different SEQUENCE objects for each type of account.
The MariaDB fork of MySQL has a similar kind of SEQUENCE object, as does PostgreSQL. So if you were using MariaDB you would do something like this.
CREATE SEQUENCE IF NOT EXISTS org_account_id MINVALUE=10000 MAXVALUE=999999;
CREATE SEQUENCE IF NOT EXISTS user_account_id MINVALUE=1000000;
Then to use a sequence in place of autoincrement you'll do something like this.
INSERT INTO tbl (id, col1, col2)
VALUES (NEXTVAL(user_account_id), something, something);
In MySQL you can emulate sequence objects with dummy tables containing autoincrement ids. It's a kludge. Create the following table (one for each sequence).
CREATE TABLE user_account_id (
sequence_id BIGINT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sequence_id`)
);
ALTER TABLE user_account_id AUTO_INCREMENT=1000000;
Then issue these queries one after the other to insert a row with a unique user id.
INSERT INTO user_account_id () VALUES ();
DELETE FROM sequence WHERE sequence_id < LAST_INSERT_ID();
SET #id:=LAST_INSERT_ID();
INSERT INTO tbl (id, col1, col2)
VALUES (#id, something, something);
After your insert into the dummy table, LAST_INSERT_ID() returns a unique id. The DELETE query merely keeps this dummy table from taking up too much space.
I recommend that you use a normal sequence-based bigint column. Then, on SELECT, add the base for the appropriate account type to the column.
PreparedStatement ps = con.prepareStatement("insert into emp(emp_code,emp_name,join_date,designation,birth_date,gender,mobile) values((select max(emp_code)+1 from emp),?,?,?,?,?,?)")
This query will definitely help..

Case WHEN error

this is my query
CASE
WHEN (SELECT COUNT(*) FROM `table` WHERE `ip`= 'myip' )=1
THEN UPDATE `table`
SET `last_active`=".date("Ymd").",`last_time`=".date("His")."
WHERE `ip`= 'myip';
ELSE (INSERT INTO `table`(ip)
VALUES("myip"));
END
but its not woking .the problem should be from here
(SELECT COUNT(*) FROM `table` WHERE `ip`= 'myip' )=1
how can I fix this ? or how to do this another way?
the date("Ymd") function is just the php function to return the date the problem isnt from that
thanks
I think you are trying to do this:
create unique index unq_table_ip on table(ip);
insert into table (ip)
values ('myip')
on duplicate key update last_active = curdate(),
last_time = curtime();
The unique index (or equivalently a unique constraint) guarantees that a given ip only appears once in the table. Let the database do this work for you -- this is called maintaining relational integrity.
Notes:
This assumes that last_active and last_time have default values in the table.
You should use the database time, not the application time for this purpose (after all, different clients could have different time values).
You should probably put the date/time values into a single datetime column, say last_active_datetime.
Define unique constraint on ip column and then use ON DUPLICATE KEY UPDATE:
insert into `table` (ip) values ("myup")
on duplicate key update
`last_active`=".date("Ymd").",`last_time`=".date("His")."

Insert on duplicate update

I have MySQL table and I need to make query INSERT ON DUPLICATE UPDATE. "id" is primary key, I dont need it for now.
I need to insert values "id2", "name", "city" into the table. If there is some row with the same values in "id2" and "name", then just update "city".
Please where am I wrong ?
$query = "INSERT INTO
`table`
(id2, name, city)
VALUES
( '$new_id2', '$new_name', '$new_city')
ON DUPLICATE KEY UPDATE
city='$new_city'
WHERE
`id2`='$new_id2' AND `name`='$new_name'
";
In order to use ON DUPLICATE KEY UPDATE you must create an index to enforce uniqueness across the two columns id2, name for MySQL to be able to detect duplication. This will create the index with an identifier called idx_uniq_id2_name
`
Before you attempt this, you must ensure that you do not already have more than one occurrence of the combination of id2, name anywhere in your table. You can verify that with:
-- Check for non-unique rows
SELECT id2, name FROM table GROUP BY id2, name HAVING COUNT(*) > 1
If that returns no rows, you can successfully create the multi-column index.
-- Create a multi-column unique index
ALTER TABLE `table` ADD UNIQUE INDEX `idx_uniq_id2_name` (`id2`, `name`);
After the index has been created, you must correct the syntax of your INSERT statement such that it has no WHERE clause (which is never allowed for an INSERT).
INSERT INTO `table`
(id2, name, city)
VALUES ('$id2', '$name', '$new_city')
ON DUPLICATE KEY UPDATE city = '$new_city';
Please be advised that your use of variables like $new_city in the SQL statement suggest you are not using prepare()/execute() with PDO or MySQLi in your code. I would recommend reviewing How can I prevent SQL injection in PHP for suggestions on how to improve the situation.

MySQL insert in one of two tables based on condition for one table

Consider two tables that have timestamp and data columns. I need to construct an SQL that does the following:
Insert data (unique timestamp and data column) in one table if timestamp value is not present in the table ("insert my data in table 1 for timestamp="12:00 1999-01-01" only if that timestamp is not present in table 1...)
Otherwise, insert very same data in different table without any checks, and overwrite if necessary (... otherwise insert same set of fields in table 2).
How I could possibly achieve this on SQL? I could do it using a client but this is way slower. I use MySQL
Run a query for your 2nd bullet first. i.e. insert data into table 2 if it is present in table 1
insert into table2 (data, timestamp)
select 'myData', '12:00 1999-01-01'
from table1
where exists (
select 1 from table1
where timestamp = '12:00 1999-01-01'
)
limit 1
Then run your the query for your 1st bullet i.e. insert into table1 only if the data doesn't already exist
insert into table1 (data, timestamp)
select 'myData', '12:00 1999-01-01'
from table1
where not exists (
select 1 from table1
where timestamp = '12:00 1999-01-01'
)
limit 1
Running both these queries will always only insert 1 row into 1 table because if the row exists in table1, the not exists condition of the 2nd query will be false and if it doesn't exist in table1, then the exists condition of the 1st query will be false.
You may want to consider creating a unique constraint on table1 to automatically prevent duplicates so you can use insert ignore for your inserts into table1
alter table table1 add constraint myIndex (timestamp);
insert ignore into table1 (data,timestamp) values ('myData','12:00 1999-01-01');
A regural INSERT statement can insert records into one table only. You have 2 options:
Code the logic within the application
Create a stored procedure within mysql and code the application logic there
No matter which route you choose, I would
Add a unique index on the timestamp column in both tables.
Attempt to insert the data into the 1st table. If the insert succeeds, everything is OK. If the timestamp exists, then you will get an error (or a warning depending on mysql confioguration). Your solution handles the error (in mysql see DECLARE ... HANDLER ...).
Insert the data into the 2nd table using INSERT INTO ... ON DUPLICATE KEY UPDATE ... statement, which will insert the data if the timestamp does not exists, or updates the record if it does.

SQL Insert from table to table prevented by duplicate primary key from source table

I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)