I have a task to update existing multiple product-related tables with new entries if product name doesn't exist (no update). Thing is that this is one time action so product name column is not and will not be set as unique, primary, etc (and it is not possible for me to change it anyway).
I would be delighted if i could access the database remotely and use PHP, but due to security reasons i have access only to PhpMyAdmin on that server.
After googling for couple of hours i realized that either all results are about single INSERT IGNORE or similar constructions, or they are too complicated for me non-mysql brain to understand or solutions just won't work (like IF statement throws syntax error on that 5.5.8 MySQL server.
So thing is - there are 7 tables with all kinds of information on product (product, variant, image, category, product relation to category, prices, discounts). I have to check if product name doesn't exist and if true then insert new entries in all 7 tables. Additionaly i should create new product category entry if such doesn't exist (again, by name, not id)
In my humble opinion it would be like this:
IF (SELECT ProductName from `product` where ProductName='Pony') IS NULL THEN
INSERT INTO `product` VALUES ('', 'Pony');
#productId = (SELECT LAST_INSERT_ID());
INSERT INTO `category` (Name) SELECT 'Everything Nice' FROM `category` WHERE NOT EXISTS (SELECT Name FROM `category` WHERE Name='Everything Nice') LIMIT 1;
SET #categoryId = (SELECT CategoryId FROM `category` WHERE Name='Everything Nice');
INSERT INTO `product_rel_category` VALUES (#productId, #categoryId);
INSERT INTO `variant` VALUES ('', 'Nice');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
INSERT INTO `variant` VALUES ('', 'Sweet');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
INSERT INTO `variant` VALUES ('', 'Pink');
#variantId = (SELECT LAST_INSERT_ID());
INSERT INTO `product_rel_variant` VALUES (#productId, #variantId);
... etc ...
ENDIF;
MySQL yells about syntax on IF in such query. I also tried working all kinds of procedures, but since I know only 'insert, update, select, delete', there is nothing much i can compose now.
So do you have an advise on solution on how i can make multiple INSERT/SELECT queries if a value in one table doesn't exist.
Sincerely thanks.
Related
I use my SQL for my app.
Say I have a table of all registered users for my app.
say I have users at hand and I want to filter (or select) from my database the only ones that are registered.
For example my data base have user1,user2......user100
and input user set : user3,user5,user10,user999,user2000 so the output of the query will be : user3,user5 and user 10 only.
Thank you in advance
You seem to want in:
select t.*
from t
where user_id in ('user3', 'user5', 'user10', 'user999', 'user2000')
This will return only the matching users.
The format the user is passing these values is very important here. I am assuming that you have different rows of information. If in that case, you could make use of the below code.
Declare #MyTableVar table
(User_ID VARCHAR(32) primary key)
INSERT #MyTableVar VALUES ('user3')
INSERT #MyTableVar VALUES ('user5')
INSERT #MyTableVar VALUES ('user10')
INSERT #MyTableVar VALUES ('user999')
INSERT #MyTableVar VALUES ('user2000')
SELECT *
FROM #MyTableVar
WHERE User_ID NOT IN (SELECT USER_ID FROM database.schema.table_name)
If your user is passing values in the same row you can convert them to multiple rows using CROSS APPLY. Example can be seen here
Kartheek
Hello i'll give you guys an example of the database tables that are being a pain so i got 3 conected tables yeah trying to make a list into a database anyway i'm having trouble writing a insert query for it
vogelsoort
id|naam|idhooftoonder|
now idhoofdtoonder references to the id a connection table to sort of translate a list to a mysql database (the logic of the table will be added underneath)
hoofdtoonder
|pkey|Id|idondersoorten
now idhoofdtoonder references to a the following table its id
ondersoort
id|naam
I'm sorry for asking this also i'm not experienced enough yet in mysql
edit: the question is since i've tried with a simple insert query it overwrote existing data that i'm looking for help with an insert without overwriting existing id's and connections since (idhootoonder references to hooftonder(id) and hooftoonder idontersoorten references to ondersoort(id) but not all data in ondersoort is connected to the same vogelsoort and i need an insert query that doesn't overide existing connections
You need 3 insert-statements, one for each table.
You may use TRANSACTION to do it safely.
You need to use LAST_INSERT_ID() function (your PK fields must been auto_increment for this), docs: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id
START TRANSACTION;
INSERT INTO ondersoort (id, naam) VALUES (NULL, 'data');
INSERT INTO hoofdtoonder (pkey, Id, idondersoorten) VALUES (NULL, NULL, LAST_INSERT_ID());
INSERT INTO vogelsoort (id, naam, idhooftoonder) VALUES (NULL, 'data', LAST_INSERT_ID());
COMMIT;
I have read all most of the answers and even tried them. But this is my case where I'm inserting record from a .csv file into the database. I want to insert a record if it does not exist.
Here is my query
INSERT INTO retailer(retailerCode, contact, shopName, address,
retailerType, lastVisit, officeID, createDate)
VALUES ('', '$emapData[1]', '$emapData[2]', '$emapData[3]',
'$emapData[4]', '', '$id', CURDATE())
WHERE NOT EXISTS (SELECT retailerID
FROM retailer
WHERE contact = '$emapData[1]')
Here $emapData is a PHP array that saves the records of the .csv file. The insert statement works fine without this part
WHERE NOT EXISTS (SELECT retailerID
FROM retailer
WHERE contact = '$emapData[1]')
But my goal is not achieved.
You cannot use WHERE with INSERT in that way.
What you can do:
As #Sylwit suggested, create unique index on contact and use INSERT IGNORE
alter table retailer add unique (contact)
Use INSERT INTO SELECT syntax
INSERT INTO retailer(retailerCode,contact,shopName,address,retailerType,lastVisit,officeID,createDate)
select '','$emapData[1]','$emapData[2]','$emapData[3]','$emapData[4]','','$id', CURDATE()
from retailer
WHERE NOT EXISTS (SELECT retailerID FROM retailer WHERE contact='$emapData[1]')
I am trying to insert multiple rows into two tables connected by a foreign key that is autoincrement. I can't seem to find a good solution.
Tables:
eav_attribute_option
option_id (PK, Autoincrement)
attribute_id
sort_order
eav_attribute_option_value
value_id (PK, Autoincrement)
option_id (FK)
store_id
value
I want to do this:
insert into eav_attribute_option(attribute_id) values(100,101,102,103,...);
insert into eav_attribute_option_value(option_id,store_id,value) values
(1,0,"English"),(1,1,"German"),(2,0,"English1"),(2,1,"German2")
What would be the best approach to this, I can't seem to find a good one. :
Get next autoincrement then insert with it (need to lock table between)
Insert first part, then retreive PK values, build second part and insert (data incomplete for some time, what happens on error in second part?)
Some way to insert with join if it's possible?
Edit:
Just to clarify, I am looking to use the least amount of queries possible. I know I can do last inserted id, but I don't want to kill the server with thousands of inserts.
You can try something like this:
insert into eav_attribute_option (attribute_id) values(100);
insert into eav_attribute_option_value (option_id, store_id, value)
values (LAST_INSERT_ID(), 0, "English");
But you will need to insert the rows one by one. Consider doing a loop in your application.
$count = count('Count post value'); // $_POST value count
for($a=0;$a<$count;$a++)
{
$insert = 'insert into eav_attribute_option(attribute_id,sort_order) values (value1,value2)';
mysql_query($insert);
$insert_id = mysql_insert_id();
$insert2 = 'insert into eav_attribute_option_value(option_id,store_id,value) values
($insert_id,0,"English")';
mysql_query($insert2);
}
I'm dealing with a relational table and I've been wondering if there's a way to lower the number of queries I need to make when inserting data to the tables..
Here are the queries I currently use:
I insert the "main" values.
INSERT INTO products
(title, description, status, url)
VALUES
('some title', 'description of doom', 1, 'some-title');
We make it insert the value only if it doesn't exist already.
INSERT IGNORE INTO values
(value)
VALUES
('example value');
Since I'm not sure if the query was actually inserted, I get the id..
SELECT id
FROM
values
WHERE
value = 'example value';
Where "?" is the ID I got from the last query.
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, ? );
This means that each extra value I need to add will cost 3 queries. So my question is: Is there a more efficient way to do this?
You can do this to at least drop one of the queries:
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, (SELECT id
FROM values
WHERE value = 'example value') );
I basically am replacing the '?' with a sub select of the second query to get the id.
"Is there a more efficient way to do this?"
No. Not really. Creating three things takes three inserts.
You should be able to tell whether the insert succeeded with the ROW___COUNT() function from inside MySQL. If calling from another language (e.g. PHP), the mysql_query or equivalent function will return the row count.
You could use an INSERT INTO ... ON DUPLICATE KEY UPDATE statement.
This does, however, require that the primary key be one of the values for the insert, so it doesn't work on tables with an auto-increment.