I am using "Voila Norbert" API and I would like to store results in a DB table like this :
email_Norbert (
id Integer(11) NOT NULL AUTO_INCREMENT,
idUser Integer(11) NOT NULL,
email VarChar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci,
score Integer(2),
existence TinyInt(1),
PRIMARY KEY (
id
)
Actually I use this query (as an example, I set values but it changes everytime for each idUser) :
INSERT INTO email_Norbert (idUser,email,score)
VALUES (2 ,'MyEmailHere',100)
ON DUPLICATE KEY UPDATE idUser = 2,email = 'MyEmailHere', score = 100
The insert run well but when the record already exist, I does add an other record.
What should I do ?
if you want subsequent inserts for same user to fail and instead update, add a unique index on the iduser column.
create unique index email_Norbert_u1 on email_Norbert(iduser)
Related
I'm learning SQL.
I'm trying to insert data. My MySQL database looks like this.
CREATE TABLE category (
category_id CHAR(100),
category_name VARCHAR(120) NOT NULL,
PRIMARY KEY (category_id)
)
I ran this command
INSERT INTO category (category_name) VALUES ("test");
But I got this error
ERROR 1364 (HY000): Field 'category_id' doesn't have a default value
Thank you in advance.
If you want to have an incrementing ID it would need to be an int. You Generally want to make ID's integers not chars to speed up lookup regardless.
CREATE TABLE IF NOT EXISTS category (
`category_id` INT NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(120) NOT NULL,
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4 COLLATE utf8mb4_unicode_ci;
That will let you insert without adding your own ID, and automatically generate unique ID's for the records.
Issue was you set your category_id field to not have a default value and also not allow null, which means you -have- to set a value for it in the insert. If you wanted to use your existing table you would need to do this:
INSERT INTO category (category_id, category_name) VALUES ("someid", "test");
I have a MYSQL table, with 5 columns in it:
id bigint
name varchar
description varchar
slug
Can I get MySQL to automatically generate the value of slug as a 256 Bit Hash of name+description?
I am now using PHP to generate an SHA256 value of the slug prior to saving it.
Edit:
By automatic, I mean see if it's possible to change the default value of the slug field, to be a computed field that's the sha256 of name+description.
I already know how to create it as part of an insert operation.
MySQL 5.7 supports generated columns so you can define an expression, and it will be updated automatically for every row you insert or update.
CREATE TABLE IF NOT EXISTS MyTable (
id int NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
description varchar(50) NOT NULL,
slug varchar(64) AS (SHA2(CONCAT(name, description), 256)) STORED NOT NULL,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
If you use an earlier version of MySQL, you could do this with TRIGGERs:
CREATE TRIGGER MySlugIns BEFORE INSERT ON MyTable
FOR EACH ROW SET slug = SHA2(CONCAT(name, description));
CREATE TRIGGER MySlugUpd BEFORE UPDATE ON MyTable
FOR EACH ROW SET slug = SHA2(CONCAT(name, description), 256);
Beware that concat returns NULL if any one column in the input is NULL. So, to hash in a null-safe way, use concat_ws. For example:
select md5(concat_ws('', col_1, .. , col_n));
Use MySQL's CONCAT() to combine the two values and SHA2() to generate a 256 bit hash.
CREATE TABLE IF NOT EXISTS `mytable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`description` varchar(50) NOT NULL,
`slug` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `mytable` (`name`,`description`,`slug`)
VALUES ('Fred','A Person',SHA2(CONCAT(`name`,`description`),256));
SELECT * FROM `mytable`
OUTPUT:
COLUMN VALUE
id 1
name Fred
description A Person
slug ea76b5b09b0e004781b569f88fc8434fe25ae3ad17807904cfb975a3be71bd89
Try it on SQLfiddle.
Is it possible to update only a single field with ON DUPLICATE KEY UPDATE in a table with multiple fields?
If I have a table with three fields; key, cats, dogs where key is the primary key is it possible to update a record on duplicate key, changing only one field, (for my example cats) without changing the value in the other non-key fields (dogs). This is without knowing what the value of dogs from outside of the database at the time of insertion (i.e. I have a variable holding cats value, but not one holding dogs value)
INSERT INTO `myTable` (`key`,`cats`) VALUES('someKey1','Manx') ON DUPLICATE KEY UPDATE `cats` = 'Manx';
At the moment when I run something like this and the key already exists in the table dogs is set to NULL even when it had a value previously.
Gordon is right, it does not work the way I described. If you see this, it is not caused by the ON DUPLICATE UPDATE statement, but something else. Here is the proof:
CREATE TABLE IF NOT EXISTS `myTable` (
`key` varchar(20) NOT NULL default '',
`cats` varchar(20) default NULL,
`dogs` varchar(20) default NULL,
PRIMARY KEY (`key`)
)
The run
INSERT INTO `myTable` (`key`, `cats`, `dogs`) VALUES
('someKey1', NULL, 'jack-russell');
Then run
INSERT INTO `myTable` (`key`,`cats`) VALUES
('someKey1','Manx') ON DUPLICATE KEY UPDATE `cats` = 'manx';
Then check the table
I think you should try to UPSERT.
Please examine this:
INSERT INTO `item` (`item_name`, items_in_stock) VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE `new_items_count` = `new_items_count` + 27
MySQL UPSERT
I have a table in which there is a column name with SP varchar(10) NOT NULL. I want that column always to be unique so i created unique index on that column . My table schema as follows :
CREATE TABLE IF NOT EXISTS `tblspmaster` (
`CSN` bigint(20) NOT NULL AUTO_INCREMENT,
`SP` varchar(10) NOT NULL,
`FileImportedDate` date NOT NULL,
`AMZFileName` varchar(50) NOT NULL,
`CasperBatch` varchar(50) NOT NULL,
`BatchProcessedDate` date NOT NULL,
`ExpiryDate` date NOT NULL,
`Region` varchar(50) NOT NULL,
`FCCity` varchar(50) NOT NULL,
`VendorID` int(11) NOT NULL,
`LocationID` int(11) NOT NULL,
PRIMARY KEY (`CSN`),
UNIQUE KEY `SP` (`SP`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=10000000000 ;
Now i want that if anybody tries to insert duplicate record then that record should be inserted into a secondary table name tblDuplicate.
I have gone through this question MySQL - ignore insert error: duplicate entry but i am not sure that instead of
INSERT INTO tbl VALUES (1,200) ON DUPLICATE KEY UPDATE value=200;
can i insert duplicate row into another table ?
what changes needed to be done in main table scheme or index column ?
**Note : Data will be inserted by importing excel or csv files and excel files generally contains 500k to 800 k records but there will be only one single column **
I believe you want to use a trigger for this. Here is the MySQL reference chapter on triggers.
Use a before insert trigger. In the trigger, check if the row is a duplicate (maybe count(*) where key column value = value to be inserted). If the row is a duplicate, perform an insert into your secondary table.
I using a MySQL server (5.5.27 - Community Server). I have a table with this definition:
CREATE TABLE IF NOT EXISTS tbl_messages (
`msg_id` VARCHAR(50) NOT NULL ,
`msg_text` VARCHAR(50) NULL ,
PRIMARY KEY (`msg_id`);
I write a trigger that, when I do an insert, the server sets the msg_id column with the current time including microseconds with this format "yyyymmddhhnnssuuuuuu". "u" is for microseconds.
I created a trigger:
create trigger tbl_messages_trigger
before insert on tbl_messages
for each row
BEGIN
SET NEW.msg_id = DATE_FORMAT(NOW(),'%Y%m%d%H%i%s%f');
END;$$
But the msg_id column only gets values like this: 20130302144818*000000*, with microseconds in zero. ¿Is it possible capture the microseconds?
TIA,
From the code provided I guess that you are trying to use microsecond to minimize probability of getting same msg_id for different rows.
Also, msg_id is the primary key, which should not present any object-specific data but only be unique. There is a good link about: http://en.wikipedia.org/wiki/Surrogate_key
The best way to deal with primary keys in MySql is AUTO_INCREMENT column attribute. If you need insert time for messages, you may provide column for it:
CREATE TABLE tbl_messages
(
`msg_id` bigint(20) NOT NULL AUTO_INCREMENT,
`msg_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`msg_text` VARCHAR(50) NULL,
PRIMARY KEY (`msg_id`)
);