First time using MySQL (this is in a node/react app) and am encountering an error trying to insert some values into a table. The specific error message I am getting is:
Error: ER_BAD_FIELD_ERROR: Unknown column 'name' in 'field list'
Here is my table:
const table =
"CREATE TABLE IF NOT EXISTS
posts(id int AUTO_INCREMENT,
name VARCHAR(30),
email VARCHAR(50),
content VARCHAR(500),
stamp VARCHAR(40),
PRIMARY KEY(id))";
and here is the query:
// Insert post 1
app.get("/addpost1", (req, res) => {
let post = {
name: "Joe Blogs",
email: "jblogs#gmail.com",
content:
"Interesting post Phil. It's great to see that a blog really can come alive when the comments update in real-time. The commenting system becomes a conversation platform.",
stamp: "July 30 2019"
};
let sql = "INSERT INTO posts SET ?";
let query = db.query(sql, post, (err, result) => {
if (err) throw err;
console.log(result);
res.send("Post 1 added...");
});
});
I am continually running into errors with this. Any help appreciated.
This is the right syntax:
INSERT INTO `table`(`column1`, `column2`) VALUES ([value-1],[value-2])
so in your code would be like:
INSERT INTO `posts` (`name`, `email`, `content`) VALUES ([name:], [email:], [content:])
Related
At the front-end, whenever I press submit an answer to a question, it'll create 1 result_ID that has these columns.
result_ID is auto-increment, question_ID is relation with the same question_ID from questions table.
If it's the first time the user chooses the answer, it'll create an answer_result (i parse in answer_ID) and answer_checkResult (value 1 or 0 to identify it's correct or incorrect), and a history_ID to identify each record separately.
History_ID is a different table that has the quiz_ID (to identify topic) and user_ID
example: History_ID 221 has 4 questions in there, and has 4 answers with 4 answer_result.
What I don't know is how can I create a situation if the row doesn't exist, it'll run INSERT INTO situation, and else if it already exists (because the user can change the answer multiple times in 1 question), it'll UPDATE. I've just created only the INSERT INTO option, but I don't know how to do the update in this model at the same time with INSERT INTO.
This is my history_result.model that I've created, I don't know how to create an if-else to update and create at the same time...
history_result.model
const HistoryResult = function (history_result) {
this.question_ID = history_result.question_ID;
this.answer_result = history_result.answer_result;
this.answer_checkResult = history_result.answer_checkResult;
this.history_ID = history_result.history_ID;
};
HistoryResult.create = async (newHistoryResult, result) => {
await db.query(
`INSERT INTO history_result SET question_ID = ?, answer_result = ?, answer_checkResult = ?, history_ID = ?`,
[
newHistoryResult.question_ID,
newHistoryResult.answer_result,
newHistoryResult.answer_checkResult,
newHistoryResult.history_ID,
],
(err, data) => {
if (err) {
result(err, null);
return;
} else {
return result(null, data);
}
}
);
};
And here's how I create the history_result controller
const HistoryResult = require("../models/history_result.model");
exports.createHistoryResult = async (req, res) => {
let { history_ID } = req.params;
let { question_ID, answer_result, answer_checkResult } = req.body;
let historyResult = new HistoryResult({
question_ID: question_ID,
answer_result: answer_result,
answer_checkResult: answer_checkResult,
history_ID: history_ID,
});
HistoryResult.create(historyResult, (err, data) => {
if (err) {
res.status(500).send({
message: err.message || "Error while creating result",
});
}
res.send(data);
});
};
Is there anyways I can achieve this? Thanks.
Yes, you can.
but first you have to make question_ID as PRIMARY KEY. And second parameter that you pass to db.query is object that contains history_result's attributes
INSERT INTO history_result
SET ?
ON DUPLICATE KEY UPDATE
answer_result = VALUES(answer_result),
answer_checkResult = VALUES(answer_checkResult),
history_ID = VALUES(history_ID)
db.query(query, objectHere, (err, data) => {
if (err) {
result(err, null);
return;
} else {
return result(null, data);
}
}))
First, please read the MySQL Insert or Update on duplicate-key update tutorial,
or this Official MySQL INSERT ... ON DUPLICATE KEY UPDATE Statement document
Now back to your question. As I understand, the question_ID and history_ID pair in the history_result table would be unique, as each user will only give one answer to a question in a quiz.
First you would need to create a unique index constraints of the pair (question_ID, history_ID) of your table.
ALTER TABLE history_result
ADD CONSTRAINT uc_question_history
UNIQUE (question_ID,history_ID);
And then issue an INSERT ON DUPLICATE KEY UPDATE statement to achive the effect.
INSERT INTO history_result
(
question_ID, answer_result, history_ID
)
VALUES
(14, 21, 12)
ON DUPLICATE KEY UPDATE
answer_result = 21;
If the question_ID = 14 and history_ID = 12 row already existed (scenario that user has already answer this question), it will trigger to update the answer_result. If not, it will insert a new record.
The DUPLICATE KEY constraint is met if a new row is a duplicate in UNIQUE index or PRIMARY KEY. In our case, it's the unique index of (question_ID, history_ID), hence the UPDATE statement will be invoked.
I am a beginner in mySQL and I am trying to create a user's table with information about the user (see code) and populate a column with details that I get from a new table that gets created.
Now I want to be able to put some information from the 'creditcards' table like number for example, to the 'users' table which includes a column 'creditcard', so that I can see each user's credit card number.
I am also comparing the name of the user with the name of the credit card owner so it populates the table according to the user.
I couldn't find any information about the specific problem I am having here.
Here's how I am trying to write:
con.query(createNewCreditCard, [name, type, number, expiration, svss], (err, results) => {
if (err) {
console.error(err);
} else {
const JoinCreditCard = 'INSERT INTO users (creditcard) SELECT number,name FROM creditcards WHERE users.name = creditcards.name';
const userCreateModel = `
CREATE TABLE IF NOT EXISTS users (
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
username VARCHAR(45) NOT NULL,
email VARCHAR(45) NOT NULL,
phonenumber VARCHAR(45) NOT NULL,
password VARCHAR(255) NOT NULL,
creditcard INT(11),
salt VARCHAR(255),
created_at DATE,
update_at DATE,
deleted_at DATE,
lastSignIn DATE,
PRIMARY key (id)
)
`;
const CreditCardModel = `
CREATE TABLE IF NOT EXISTS creditcards (
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR (25) NOT NULL,
type VARCHAR(10) NOT NULL,
number INT(12) NOT NULL,
expiration DATE,
svss INT(3) NOT NULL,
created_at DATE,
PRIMARY key (id)
)
`;
I am trying to create a user named ula and then a credit card with the name ula (and all other columns) which I am sending from postman.
The credit card part in nodejs looks like this:
const createCreditCard = async (req, res, next) => {
const {
name,
type,
number,
expiration,
svss
}: {
name: String,
type: String,
number: String,
expiration: String,
svss: String
} = req.body;
const createAt = new Date(Date.now());
try {
const createNewCreditCard = 'INSERT INTO creditcards (name, type, number, expiration, svss) VALUES (?,?,?,?,?)';
con.query(createNewCreditCard, [name, type, number, expiration, svss], (err, results) => {
if (err) {
console.error(err);
} else {
const JoinCreditCard = 'UPDATE users SET creditcard=' + number + ' WHERE name="' + name + '"';
console.log(results);
}
});
res.status(201).send({ success: true, message: 'New credit card was created', data: {name, type, number, expiration, svss} });
} catch (error) {
res.status(500).send({ success: false, message: 'Server error' });
}
await next;
}
The server returns 201, I go to mysql, open users, see column creditcard and its NULL.
Because the entry already exists in the database for users table, you should use UPDATE instead of INSERT.
An example that should work with your code (you already know name and number as vars because you just created the credit card info with them, no need to select them again):
con.query(createNewCreditCard, [name, type, number, expiration, svss], (err, results) => {
if (err) {
console.error(err);
} else {
const JoinCreditCard = 'UPDATE users SET creditcard=' + number + ' WHERE name="' + name + '"';
EDIT: this is the new code from your edit. You already use prepared statements, so forget my notice about that. I've updated the query to follow this. What was missing in your code is that you need to actually do the query! Only declaring the constant won't do anything to your database..
try {
const createNewCreditCard = 'INSERT INTO creditcards (name, type, number, expiration, svss) VALUES (?,?,?,?,?)';
con.query(createNewCreditCard, [name, type, number, expiration, svss], (err, results) => {
if (err) {
console.error(err);
} else {
console.log(results);
const JoinCreditCard = 'UPDATE users SET creditcard=? WHERE name=?';
con.query(JoinCreditCard, [number, name], (err, results) => {
if (err) {
console.error(err);
} else {
console.log(results);
}
});
}
});
res.status(201).send({ success: true, message: 'New credit card was created', data: {name, type, number, expiration, svss} });
} catch (error) {
res.status(500).send({ success: false, message: 'Server error' });
}
NOTE: you should know that using the name to reference the credit card will not allow you to have multiple credit cards for one user, and should be careful about users with the same name, or else this query will update both users. It would be safer to always use the user id field in the WHERE clause. (you should know it at this point)
THIS IS WHAT I RECOMMEND:
it's usually better that the creditcard in users only stores the id from the creditcards table. Like this, relations are on the primary key and it's more optimized (you need to get the id after the credit card creation request, in an inner SELECT in following code).
use the ids to identify rows updates, to prevent 2 users to be updated
delete name from creditcards table, it's already in users
having a third table to reference the relations like states user1974729 is not mandatory, however, it will be the case if you conveniently want to be able to have more than one credit card per user or more than one user that share a card (1 to n relation)
code:
//relation based on id instead of number stored in users + name removed. I assume at this point, you know the id of your user (in var "id" used below in `WHERE` clause)
con.query(createNewCreditCard, [type, number, expiration, svss], (err, results) => {
if (err) {
console.error(err);
} else {
const JoinCreditCard = 'UPDATE users SET creditcard=(SELECT id FROM creditcards WHERE type="' + type + '" AND number="' + number + '" AND expiration="' + expiration + '" AND svss="' + svss + '") WHERE id="' + id + '"';
//no change in userCreateModel
//deleted "name" in CreditCardModel
const CreditCardModel = `
CREATE TABLE IF NOT EXISTS creditcards (
id INT(11) NOT NULL AUTO_INCREMENT,
type VARCHAR(10) NOT NULL,
number INT(12) NOT NULL,
expiration DATE,
svss INT(3) NOT NULL,
created_at DATE,
PRIMARY key (id)
)
`;
it is important that the tables are in normalized forms.
There should be 3 tables.
Users -- all the user data
Credit cards -- all the credit card related information.
Users credit card map -- map users to credit card information.
I am developing an application that downloads images and their tags. When a download starts the program retrieves the tags and inserts them into the database. Here I am trying to insert a new tag and then create a relationship between the the tag and its download. The combination of name and type in tag is unique.
let download_id = 1;
let tag = {type:'language', name:'english'}
let sql = `INSERT INTO tag (name, type) SELECT '${tag.name}', id FROM tag_type WHERE type='${tag.type}' ON DUPLICATE KEY UPDATE count = count + 1, id=LAST_INSERT_ID(id)`
mysqlConnection.query(sql, (err, results) => {
if (err) throw err;
let sql = `INSERT INTO download_tag ?`;
mysqlConnection.query(sql, [{download_id: download_id, tag_id: results.insertId}], err => {
if (err) throw err;
});
});
However my first query returns this error Uncaught Error: ER_NON_UNIQ_ERROR: Column 'id' in field list is ambiguous I am unsure why my code is not working, it is very similar to the accepted answer in this question.
Your problem is that LAST_INSERT_ID doesn't know whether you are referring to id from the tag table or from the tag_type table. You just need to qualify the field name with its table:
let sql = `INSERT INTO tag (name, type)
SELECT '${tag.name}', id FROM tag_type WHERE type='${tag.type}'
ON DUPLICATE KEY UPDATE count = count + 1, id=LAST_INSERT_ID(tag.id)`
I have the following code in nodejs. I am using npm's mysql library and I know that all the columns are correct in mysql database but I keep getting the following error: "Unknown column 's3_id' in 'field list'" but when I do select s3_id from custom_videos I get rows back. How can I have an unknown column that exists?
router.post("/submitCustomVideo", async (req, res, next) => {
try {
const data = {};
const {
s3Id,
name,
renderTime,
duration,
description,
selectedCategories,
selectedKeywords,
customFields
} = req.body;
const VALUES = {
s3_id: s3Id,
name,
duration,
description,
render_time: renderTime,
custom_fields: customFields
};
const updateCustomVideoInfoResult = await database.query(
"call updateCustomVideoInfo(?)",
[VALUES]
);
} catch (error) {
console.log(error);
next(error);
}
});
heres my stored procedure
CREATE DEFINER=`mystuff`#`%` PROCEDURE `updateCustomVideoInfo`(s3_id_param varchar(255), name_param varchar(255), duration_param int, description_param varchar(255), render_time_param int, custom_fields_param json)
BEGIN
UPDATE custom_videos SET name = name_param, duration = duration_param, description = description_param, render_time = render_time_param, custom_fields = custom_fields_param WHERE s3_id = s3_id_param;
END
Try to set the columns as a string and also check your datatype for columns.
I am new to MySQL and node.js (as well as the callback). I try to insert data into table B, which depends on data in table A. Here is an example.
employee table (table A):
CREATE TABLE employees (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50),
location varchar(50),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
age table (table B, I do not include age column in table A on purpose):
CREATE TABLE age (
id int(11) NOT NULL AUTO_INCREMENT,
index_id int(11),
age int(50),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
The problem:
For each row inserted into table A, I can get the id for it. I want to use the id as the index_id in table B, and insert the corresponding age info into age table B. The problem occurs when I have multiple rows to insert.
The example:
I implement the following function to achieve above goal.
var mysql = require("mysql");
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "sitepoint"
});
function insert_employees() {
var employees = [
{name: 'Jasmine', location: 'Australia', age: 24},
{name: 'Jay', location: 'India', age: 25},
{name: 'Jim', location: 'Germany', age: 26},
{name: 'Lesley', location: 'Scotland', age: 27}
];
var name_id;
for (var i = 0; i < 4; i++) {
var employee = employees[i];
var command = sprintf('INSERT INTO employees (name, location) VALUES ("%s", "%s");', employee.name, employee.location);
con.query(command, function (err, res) {
if (err) throw err;
name_id = res.insertId;
console.log('Last insert ID in employees:', res.insertID);
// insert age here
var age = employee.age;
var command = sprintf('INSERT INTO age (index_id, age) VALUES (%d, %d);', name_id, age);
con.query(command, function (err, res) {
if (err) throw err;
});
});
}
}
The Output:
The employee table is fine, but for the age table, the age column is 27 for all fields, instead of 24, 25, 26, 27
The Question:
I think the problem is on my misuse of callback feature, but I still don't know how to solve it. Could anyone help me with it? Thanks a lot!
var employee = employees[i];
Change the above line to below, so that variable employee has the correct scope:
let employee = employees[i];
Add the following to the beginning of your script, so that let works:
'use strict';