MYSQL select by URL - mysql

I have a table looks like this:
id url title
1 http://afef.com/abc/def/gje/qkd hello
2 http://afe.com/?a=3&b=2&fse=3 hello
3 http://stackoverflow.com/fefw/sefac/fsg hello-world
from here id is primary key and auto_increment, and url is unique, but title can be duplicated.
From this point of view, when I add new URL to this table, like :
INSERT IGNORE INTO table (url, title)
VALUES ('http://abcd.com/affefef/sfsaa/?a=3', 'this is title')
Then, if it is new URL to insert, it doesn't matter. But if it is duplicated URL, it will be ignored and I can't know what the duplicated URL's id is.
The id must not be changed.
Is there any solutions to know id when I INSERT duplicated URL with one query ?

Conditionally checking would help in getting duplicate ID
Check this code:
mysql.query("SELECT id FROM table WHERE url = 'http://abcd.com/affefef/sfsaa/?a=3", function(error, result, field) {
if(error) {
exist(error); //No error
} else if (result) {
if (result.length > 0){
console.log("Id exist:" + result['id']);
}else{
// write your insert statement here
}
}
});

In one query only, I think it's not possible. But you can use the Mysql function "last_insert_id" to retrieve the id which has been inserted. Checking it, you would be able to see if it's a new one or not.
See http://www.mysqltutorial.org/mysql-last_insert_id.aspx
You can also have a look at "insert on duplicate". With this syntax it will update the field if it exists or inserts a new one if the key isn't found.
https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

Related

How to use placeholders while inserting data in MySql database using nodejs?

let r={ email:faker.internet.email() } ;
connection_var.query("insert into users set ?",r, function(err,res){
if(err) throw err;
console.log(res);
} );
connection_var.end();
I wrote this code to insert a fake email addr in already existing database and into the users table just the problem is I am not fully able to understand what and how does the " SET ?" work and how is it relating to r and what if r has more than 1 key-value pairs
? is a placeholder. It gets replaced with all the keys and values in the object passed as the next argument. So if you have
let r = {col1: 1, col2: "abc", col3: 999};
the query will become
insert into users set col1 = 1, col2 = 'abc', col3 = 999
You have 2 separated things here
First is the SET clause (for the insert) that from the documentation:
A SET clause indicates columns explicitly by name, together with the value to assign each one.
link: https://dev.mysql.com/doc/refman/8.0/en/insert.html
The other part is the ? the according to the documentation of mysqljs:
... you can use ? characters as placeholders for values you would like to
have escaped
link: https://github.com/mysqljs/mysql
So, the SET indicates the assignment list of the insert and the ? escapes the values.

Update a record with nested objects giving duplicate key error

I need to update a user profile, I'm taking the whole profile, allowing the user to edit what he wants then send the whole profile again to the server to save whatever values updated, but it didn't work.
User {
Address {
Country {
// fields
},
// fields
},
Settings {
// fields
},
username: string,
email: string,
}
to avoid complications, I want to send the whole record, save it all, update whatever updated or save the old values again for the fields that did not update.
I tried this:
// Update User data
func (r *RepositoryUserCrud) Update(uid int, user models.User) (int, error) {
var err error
// 1, did not work, getting Error 1062: Duplicate entry for email
err = r.db.Debug().Model(&models.User{}).Where("id = ?", unit(uid)).Updates(user).Error
// 2, did not work, getting Error 1062: Duplicate entry for email
err = r.db.Save(&user).Error;
// 3, I tried to skip the duplicate key error by using {onConflict: DoNothing}
err = r.db.Debug().Clauses(r.db.Model(&models.User{})
.Where("id = ?", uint(uid)))
.OnConflict{DoNothing: true}
.Updates(user)
}
Any suggestions on how to make this work?
In case the change has happend in the deeply nested objects, how to apply the changes to their tables? or should I do this manually?
it turns out that the email field is primary key, and I'm not passing the ID as part of the updated record, so it's basically trying to create a new record with the same email.
so this code worked, but make sure to provide the ID with the record itself.
err = r.db.Debug().Model(&models.User{}).Where("id = ?", unit(uid)).Updates(user).Error
I also needed to update the linked rows from other tables manually.

How can I send a POST request without sending an auto incrementing primary key in express

I am writing a simple API which I have been testing using Postman. I have an auto incrementing primary key (CustomerTypeID) for my "customer_type" table stored in MySQL. For practical reasons I need to be able to create records in this table without sending a CustomerTypeID. When I send the following POST request using Postman:
{
"CustomerType": "testing"
}
The updated table shows a new row with CustomerTypeID of 2 and a CustomerType of NULL.
Below is a snippet of code in my Express API which shows this specific query and how the routing for this POST request works.
var db = require('../dbconnection.js');
var CustomerType = {
addCustomerType:function(CustomerType,callback) {
return db.query("INSERT INTO customer_type (CustomerType) VALUES (?)", [CustomerType.CustomerType], callback);
}
};
module.exports = CustomerType;
I know that I could change the query to say
INSERT INTO customer_type (CustomerTypeID, CustomerType) VALUES (?,?);
and that would fill both columns. But, I do not know how to leave out the CustomerTypeID column as it will be a number that the end user will have no way of knowing.
It turns out that the syntax for the last query I gave is correct. I used the same POST request as before:
{
"CustomerType": "testing"
}
And by using the SQL query that includes CustomerTypeID, MySQL knew to just increment the value of CustomerTypeID since it was not given a value in the POST request. When I ran the same POST again with this query I received a new row with both a CustomerTypeID and a CustomerType.

node-mysql: REPLACE into statement incrementing a current table value

I am using the MySQL driver for Node.js "node-mysql" but struggling with the syntax to do a REPLACE into and increment a counter. Here's what I have so far, note the count field is where I want to increment the current table value by 1:
connection.query('REPLACE INTO links SET ?', { symbol: statName, timestamp: now, count: count + 1 }, function(err, result) {
Can anyone advise on how to do this?
I found the solution in using INSERT with ON DUPLICATE KEY UPDATE:
connection.query('INSERT INTO links SET symbol = ?, timestamp = ?, title = ?, url = ? ON DUPLICATE KEY UPDATE count = count + 1', [statName, now, interaction.data.links.title[y], interaction.data.links.url[y]], function(err, results) {
if (err) console.log(err);
});
Please keep in mind that REPLACE is similar to INSERT not UPDATE.
Under the hood, REPLACE is mechanically a DELETE followed by an INSERT. It says so in the MySQL Documentation as follows:
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 13.2.5, “INSERT Syntax”.
REPLACE is a MySQL extension to the SQL standard. It either inserts, or deletes and inserts. For another MySQL extension to standard SQL—that either inserts or updates—see Section 13.2.5.3, “INSERT ... ON DUPLICATE KEY UPDATE Syntax”.
If you want to increment the count column, use INSERT INTO ... ON DUPLICATE KEY UPDATE.
Please make sure the JavaScript Engine can work with INSERT INTO ... ON DUPLICATE KEY UPDATE. If not, you must capture the count as newcount, increment newcount, and feed the number into the REPLACE
connection.query('REPLACE INTO links SET ?', { symbol: statName, timestamp: now, count: newcount }, function(err, result) {
Give it a Try !!!

Unable to remove the row from table in which foreign key exists in MVC

In my mvc application I have 2 tables named:
detail(srNo, ID, work), master(ID, name,plan) that are related with foreign key relation ship from detail to master using "ID" field.
"ID" field is primary key of master table.
"srNo" field is primary key of detail table.
From the "ID" field, this 2 tables are joined with foreign key relation ship.
Now the Problem is:
While adding any row to database, we are first make entry in master table , then in details table.
And sometimes due to some exception, when row is succesfully added in master table but can not add in detail table. Then I want to perform rollback from master table.
But when I want to delete the row with recently added ID value (grom linq to sql), which is added in master table it is giving me exception that forign key realtion ship is there .....
And at that time in detail table there is no row of that id field.
Thanks
Here is the code
master objmaster= new master();
objmaster.id =count;
objmaster.name= name1;
..
objEntities.AddObject("master", objmaster);
objEntities.SaveChanges();
try
{
detail objDetail = new detail()
master objMaster = (from r in objEntities.master where r.Id == count select r).First();
objDetail.master = objMaster;
// Suppose I get any (format, null pointer exception here)
objDetail.folow = sfields[0];
//In case of exception this below code will not be excecuted
objEntities.AddObject("detail", objDetail);
objEntities.SaveChanges();
}
catch(Exception ex)
{
//Here i want to delete the row which I have added in master table:
// I write the code for this
master objMasters= (from r in objEntities.master where r.Id == count select r).ToList();
objEntities.DeleteObject(objMasters);
objEntities.SaveChanges();
}
it seams that data is inserted in child table also. first you have to delete from detail table using deleteallonsubmit(detail) and then from the master table. can you explain what is meant by exception, is it error or your validation
public ActionResult CreateRec(Master _Master, IEnumerable<Detail> Detaildata,FormCollection collection)
{
MasterRepo _MasterRepo = new MasterRepo();
if (ModelState.IsValid)
{
if (_detail != null)
{
foreach (var objdetail in DetailData)
{
Detail _Detail = new Detail();
_Detail.FirstField = objdetail.FirstField;
_Detail.SecondField = objdetail.SecondtField;
_Master.Detail.Add(_Detail);
}
}
_MasterRepo.Save();
}
}
I think you need to submit both of them together so they are in the same transaction. Then there is no need to write rollback code as the master won't get inserted if the detail fails.
Try this instead:
master objmaster= new master();
objmaster.id =count;
objmaster.name= name1;
..
objEntities.AddObject("master", objmaster);
// == removed save changes call here ==
detail objDetail = new detail()
// == no need to reselect master from the database, you already have it
// == so just assign it, and that will take care of the references/foreign-key
objDetail.master = objMaster; // Suppose I get any (format, null pointer exception here)
objDetail.folow = sfields[0]; //In case of exception this below code will not be excecuted
objEntities.AddObject("detail", objDetail);
// == save at the end ==
objEntities.SaveChanges();