LOAD XML LOCAL INFILE 'file1.xml'
INTO TABLE my_table
ROWS IDENTIFIED BY '<product>'"
Is it possible to use this function to update a table?
I used REPLACE INTO TABLE my_table but that only added new rows and it did not update the existing rows.
LOAD XML LOCAL INFILE 'file1.xml'
REPLACE
INTO TABLE my_table
ROWS IDENTIFIED BY '<product>'"
See: http://dev.mysql.com/doc/refman/5.5/en/load-xml.html
Note that:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 12.2.5, “INSERT Syntax”.
Probably MySQL is unable to delete the exiting rows due to foreign key restrictions.
You can fix this by:
SET FOREIGN_KEY_CHECKS=0;
...load xml
SET FOREIGN_KEY_CHECKS=1;
Related
For an mysql v8.0.18 project with mariaDb 10.4.10
I would like add to my existing table an unique constraint for multi columns
ALTER TABLE 'new_purchasseorder' ADD UNIQUE ('created', 'fk_customer_id', 'fk_removal_id', 'fk_recipient_id')
but would like no check for old datas
something like that:
where id > 3869
i also tried the SET FOREIGN_KEY_CHECKS=0; but nor working in this case.
is it possible ?
My table looks like:
You can't do this with a unique constraint as far as I know, because, as you have already discovered, such a constraint will be applied to the entire table, regardless of id value. One workaround might be to use a before insert trigger, which does the assertion:
DELIMITER //
CREATE TRIGGER contacts_before_insert
BEFORE INSERT ON new_purchasseorder FOR EACH ROW
BEGIN
IF EXISTS (SELECT 1 FROM new_purchasseorder
WHERE created = NEW.created AND
fk_customer_id = NEW.fk_customer_id AND
fk_removal_id = NEW.fk_removal_id AND
fk_recipient_id = NEW.fk_recipient_id)
THEN
signal sqlstate '45000';
END IF;
END; //
DELIMITER ;
This insert trigger would cause any insert incoming with what your unique index defines as duplicate data to fail with an error, effectively blocking that insert.
A better long term (and easier) strategy might be to just fix your old data so that it can pass the requirements of the unique constraint.
Starting version 8.0.13, MySQL supports functional key parts - basically indexes on expression. Assuming that all 4 columns are non-nullable, you can do:
create unique index idx_new_purchaseorder on new_purchaseorder (
(
case when id > 3869
then concat_ws('$$', created, fk_customer_id, fk_removal_id, fk_recipient_id)
end
)
)
The case expression filters on id values, and generates a concatenated string that should be unique for rows that comply to the filter. I used some fancy characters to avoid "fake" duplicates.
Demo on DB Fiddle
On MySQL 5.7, I used to populate the "point" column of a table with LOAD DATA INFILE and a SET clause, i.e.
LOAD DATA INFILE 'myfile.txt'
REPLACE INTO TABLE mytable
(#x, #y)
SET geom = Point(#x, #y);
This worked just fine.
I upgraded to MySQL 8.0.12, and I now get an error ERROR 1364 (HY000): Field 'geom' doesn't have a default value.
Has something changed in the way LOAD DATA INFILE handles SET clauses ?
Thanks !
This bug has been confirmed in 8.0.12.
The only workaround I found was :
Drop the geom column
Load data into the (x, y) columns
Recreate the geom column without a not null constraint
Update the geom column
Alter the column to add the not null constraint
Simply method is to create table without spatial (point/geo) fields and load data as text, next load data from this (temporary) table to target table like below:
load data to temporary table with simply types of columns
insert to target table from temporary table converting needed columns to spatial.
I'm using Mysql in phpMyAdmin,where i have to delete a entry from tableA if i insert a row with same primary key.I thought to do it in trigger of tableA BEFORE INSERT
For Ex,
if the tableA contains
1 Hai Hello
here 1 is the primary key
And now if i insert a row 1 Bye Hello then the trigger BEFORE INSERT will delete the old entry and then the new row (2nd) will be inserted. But Mysql has restriction of not being able to update a table inside a trigger defined for that same table.
It gives the error
#1442 - Can't update table 'tableA' in stored
function/trigger because it is already used by statement which invoked
this stored function/trigger.
So i changed my way, i called a procedure from trigger BEFORE INSERT of tableA and in that procedure i do the task what i thought to do in trigger. But unfortunately i'm getting the same error.
In trigger BEFORE INSERT i simply called the procedure as
CALL proce1(new.Reg_No);
In procedure i have done this
DECLARE toup integer;
select count(*) into toup from tableA where Reg_No=reg;/*Here Reg_No is primary key */
if toup > 0 then
delete from tableA where Reg_No=reg;
end if;
Need some other Idea to achieve this. Help Me.....
I don't like to use triggers so much because they are hard to manage somethimes. Also they will cause you a downgrade in performance. I am not against trigger as they can be handy in some cases.
In your case have you though of using REPLACE(....) or INSERT INTO .... ON DUPLICATE KEY UPDATE or even INSERT INTO IGNORE .....
REPLACE(....) will delete a record if a record is found and insert a new one with the same ID.
INSERT INTO .... ON DUPLICATE KEY UPDATE will allow you to override existing field if a duplicate is found.
INSERT INTO IGNORE ..... will allow you to ignore the new inserted row if one already exists
Since you mentioned in the comments that you are importing records from a file, then try to use LOAD DATA INFILE logic which will allow you to REPLACE field on duplicate
LOAD DATA LOCAL INFILE 'x3export.txt'
REPLACE INTO TABLE x3export
UPDATE items SET name = 'haha' WHERE id = '12'
I'm curious if update also inserts the values if the where condition fails. I've read on w3schools that update only updates existing data on the database but on my script it's automatically inserting rows with the data. I am wondering if it might be a bug in the script or that's just how UPDATE works on mysql.
No. If, in your example, there's no entry with id = 12 in the database, the query will return "no rows affected". An update will never create a new entry in MySQL.
EDIT: although update won't create a new entry, it may include default/automatic values set up in your database schema (current timestamp, for instance).
NO. Update does not insert a value if the value doesn't exist in table. Please check if the script checks if the status of the update and makes another call to DB to insert the data.
Your SQL should do the following -
Update all records in the items table that have an id of 12 by setting their name to 'haha'
Update won't insert records if they don't exist, it will only update existing records in the table.
Short answer: No.
Long Answer: If your column doesn't exist you will get an error. If your where condition column doesn't exist you get error too. If your where condition value doesn't exist, it do nothing.
I use a temp table to review the data update conditions, you can refer
UPDATE table1
SET
column1 = 'things'
WHERE
IDcolumn = 'id' AND
(NOT EXISTS (SELECT * FROM (SELECT * FROM table1) AS temp WHERE temp.column1 = N'things'))
i got to execute loads of the following queries
UPDATE translations SET translation = (SELECT description FROM content WHERE id = 10) WHERE id = 1;
Now, i use the load data infile to do inserts and replacements but what i want in esense is to update just 1 field for each row in that table with out messing with the keys. What could be the syntax for this, note that the queries affect existing rows only.
Thanx
Use CREATE TEMPORARY TABLE to create a temporary table.
Then use LOAD DATA INFILE to populate that temporary table.
Then execute your UPDATE translations SET translation = ... to set the 1 field from a SELECT of the temporary table, JOINed with the real table. example syntax below:
UPDATE realTable, tmpTable
SET realTable.price = tmpTable.price
WHERE realTable.key = tmpTable.key