I have 2 tables.
Table Users has unique USERNAME values.
Table Roles has unique ROLENAME values.
I need to write a script that joins the 2 in a USER_TO_ROLE table:
INSERT INTO USER_TO_ROLE
(user_id,
role_id)
VALUES
(SELECT id FROM Users WHERE username=#username LIMIT 1,
SELECT id FROM Roles WHERE rolename=#rolename LIMIT 1);
MySQL Workbench gives Error Code 1064:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select id from Users where username=#username LIMIT 1, select record_id' at line 3
Is there a way to write that so that I don't have to make 2 separate database calls, writing the id values down, before making the insert?
RESOLVED
Using zerkms's example, I wrote this SQL:
INSERT INTO USER_TO_ROLE
(user_id,
role_id)
SELECT u.id, r.id
FROM Users u JOIN Roles r
WHERE u.username=#username and r.rolename=#rolename;
I had to take VALUES out for the INSERT statement to work.
You cannot have 2 SELECT clauses in INSERT INTO ... SELECT query.
You may rewrite your query to
INSERT INTO USER_TO_ROLE
(user_id,
role_id)
SELECT
(SELECT id FROM Users WHERE username=#username LIMIT 1),
(SELECT id FROM Roles WHERE rolename=#rolename LIMIT 1)
That way you would have a single SELECT with 2 nested queries correspondingly.
Related
I'm using the mysql node module.
My query is:
insert into myTableA (fk_1, fk_2)
values (
(select id from myTableB where name = ?),
(select id from myTableC where name = ?)
)
My method call looks like:
db.query(q, [values], (err) => { ... })
Each item in values is an array whose items are respectively the names in myTableB and myTableC. As shown above, I made sure to wrap values in another array.
The error I get is:
ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...`
Help please...
EDIT 1:
The values I am trying to insert look like the following:
var values = [
[name00, name01],
[name10, name11],
[name20, name21],
...
]
EDIT 2:
Here's to clarify my confusion... Basically, I am looking for a way that would allow me to use the INSERT INTO query to combine the following 2 queries:
INSERT INTO MyTable (col_1, col_2, col_3) VALUES ?
and:
INSERT INTO MyTableA (col_1, col_2, col_3) VALUES (
(select id from MyTableB where name=?),
(select id from MyTableC where name=?),
?
)
The query I am looking for would let me pass a values variable in the following form:
var values = [
[row_0_col_1, row_0_col_2, row_0_col_3],
[row_1_col_1, row_1_col_2, row_1_col_3],
[row_2_col_1, row_2_col_2, row_2_col_3],
...
]
myTableA appears to be a many-to-many table, and you're trying to populate the rows to be foreign keys references to myTableB and myTableC.
With the INSERT ... VALUES syntax, you can specify rows of data values, but each row must be specified. Like this:
INSERT INTO myTableA (fk_1, fk_2) VALUES
('name00', 'name01');
('name10', 'name11');
('name20', 'name21');
Each row is independent and self-contained. If you use subqueries, each subquery must return a single value (this is called a scalar subquery). You can't use subqueries that return multiple values.
You can also use INSERT ... SELECT syntax, so instead of listing rows one by one, the INSERT just uses the rows returned by a SELECT statement.
INSERT INTO myTableA (fk_1, fk_2)
SELECT b.id, c.id
FROM myTableB JOIN myTableC ON (...);
But you would have to provide some join expression to describe how to match values from the two respective tables in the join.
This would require inventing the many-to-many relationship out of thin air.
As for the syntax error returned by node, the error you included in your post above is truncated where you typed .... This isn't a complete error message. The query you posted is obviously edited (I suppose your table names are not myTableA, myTableB, etc.). You're asking for help but you have provided neither the real query you executed, nor the real error message. Given that, there's no way for anyone on Stack Overflow to guess at the cause of the error, or any fix for it.
Try using SQL Join feature, to insert the selected values from multiple tables.
An example for your reference:
INSERT INTO Table (aID, bID)
SELECT a.ID, B.ID
FROM A, B
WHERE A.Name='Me'
AND B.Class='Math';
This is my query :
SELECT vehicle,
CASE
WHEN vehicle IS NOT NULL
THEN (INSERT INTO tbl_vehicle_on_user (vehicle, userid) values
(SELECT `vehicle` FROM `tbl_missions` WHERE `id` = 4 ), (SELECT `id` FROM `tbl_users` WHERE `id` = 12))
FROM tbl_missions WHERE id = 4;
I need to insert a row to tbl_vehicle_on_user when vehicle is not null on id 4.
When i execute this query i receive this error from mysql workbench,
01:24:49 SELECT vehicle, CASE WHEN vehicle IS NOT NULL THEN (INSERT INTO tbl_vehicle_on_user (vehicle, userid) values (SELECT vehicle FROM tbl_missions WHERE id = 4 ), (SELECT id FROM tbl_users WHERE id = 12)) FROM tbl_missions WHERE id = 4 Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO tbl_vehicle_on_user (vehicle, userid) values (SELECT vehicle FROM `tbl_mi' at line 4 0.000 sec
And i get a red line under 'INTO' when i hover over it, it says 'Syntax error, unexpected INTO, expecting ('.
I don't know what it means i tried to search the web but couldn't find anything if you know how to fix this i will appreciate it if you answer my question :)
THANKS!!
If you already know the userid should be 12, then just use 12 instead of SELECT id FROM tbl_users WHERE id = 12. Here is a valid insert-select statement.
INSERT INTO tbl_vehicle_on_user (vehicle, userid)
SELECT `vehicle`, 12 userid
FROM `tbl_missions`
WHERE `id` = 4 and vehicle is not null;
So--i'm having an issue with my code. I'm testing it directly in the console and getting an "syntax error"
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'IF EXISTS(SELECT * FROM user_inventory WHERE resource_id = '6'
AND uid ='1') T' at line 1
IF EXISTS(SELECT * FROM user_inventory WHERE resource_id = '6' AND uid ='1')
THEN UPDATE user_inventory SET resource_count = resource_count+1 WHERE resource_id = 6 AND uid = 1
ELSE INSERT INTO user_inventory(uid, resource_id, resource_count) VALUES (1, 6, 1);
I've never used the IF EXISTS clause before... So I'm not sure what i've done wrong.
The SQL IF statement can only be used within a stored program. You can't use it within a generic SQL context as you have attempted.
However, you do not need to use IF here:
Define a suitable uniqueness constraint on your user_inventory table:
ALTER TABLE user_inventory ADD UNIQUE (uid, resource_id)
Use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO user_inventory
(uid, resource_id, resource_count)
VALUES
(1, 6, 1)
ON DUPLICATE KEY UPDATE
resource_count = resource_count + 1
Let's say I have two columns member_id, email in one table users. I'm trying to add a new row if no similar data is found with below statement:
INSERT INTO users(member_id, email)
VALUES (1,'k#live.com')
WHERE NOT EXISTS (SELECT * FROM users WHERE member_id=1 AND email='k#live.com');
However, it's not working. #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE EXISTS
Please shed some light. Thanks.
Assuming you have a unique constraint on member_id, email or a combination of both, I believe you will be better served with an INSERT IGNORE, if the record doesn't exist, it will be inserted.
INSERT IGNORE INTO users(member_id, email)
values (1, 'k#live.com');
If there is no unique constraint, use this technique here
INSERT INTO users(member_id, email)
SELECT 1,'k#live.com'
FROM dual
WHERE NOT EXISTS
(SELECT * FROM users WHERE member_id=1 AND email='k#live.com');
Dual is used in the dummy select rather than users in order to limit the rows inserted to 1.
There cannot be a WHERE clause in an INSERT ... VALUES ... statement.
The normal pattern for avoiding duplicates is to add UNIQUE constraint(s).
If you want to avoid adding any duplicate "member_id" values, and you also want to avoid adding any duplicate "email" values, then
CREATE UNIQUE INDEX mytab_UX1 ON mytab (member_id);
CREATE UNIQUE INDEX mytab_UX2 ON mytab (email);
Whenever an INSERT or UPDATE attempts to create a duplicate value, a duplicate key exception (error) will be thrown. MySQL provides the IGNORE keyword which will suppress the error, and allow the statement to complete successfully, but without introducing any duplicates.
Given an empty table, the first statement would insert a row, the second and third statements would not.
INSERT IGNORE INTO mytab (member_id, email) VALUES (1,'k#live.com');
INSERT IGNORE INTO mytab (member_id, email) VALUES (2,'k#live.com');
INSERT IGNORE INTO mytab (member_id, email) VALUES (1,'aaa#bbb.com');
If you want to restrict just the combination of the two columns to being unique, that is you would allow the 2nd and 3rd statements to insert a row, then you'd add a UNIQUE constraint on the combination of the two columns, rather than two separate unique indexes as above.
CREATE UNIQUE INDEX mytab_UX1 on mytab (member_id, email);
Aside from that convention, say you don't have a unique constraint, but you only want to modify the behavior of the single insert statement, then you can use a SELECT statement to return the values you want to insert, and then you can add a WHERE clause to the SELECT.
To avoid adding any duplicate member_id or duplicate email, then something like this would accomplish that:
INSERT INTO mytab (member_id, email)
SELECT s.member_id, s.email
FROM (SELECT 1 AS member_id, 'k#live.com' AS email) s
WHERE NOT EXISTS (SELECT 1 FROM mytab d WHERE d.member_id = s.member_id)
AND NOT EXISTS (SELECT 1 FROM mytab e WHERE e.email = s.email)
For best performance with a large table, you're going to want at least two indexes, one with a leading column of member_id, and one with a leading column of email. The NOT EXISTS subqueries can make use of an index to quickly locate a "matching" row, rather than scanning every row in the table.)
Again, if it's just the combination of the two columns you want to be unique, you'd use a single NOT EXISTS subquery, as in your original query.
Alternatively, you could use an anti-join pattern as an equivalent to the NOT EXISTS subquery.
INSERT INTO mytab (member_id, email)
SELECT s.member_id, s.email
FROM (SELECT 2 AS member_id, 'k#live.com' AS email) s
LEFT
JOIN mytab d
ON d.member_id = s.member_id
LEFT
JOIN mytab e
ON e.email = s.email
WHERE d.member_id IS NULL
AND e.email IS NULL
How can I use a single query for inserting table when a column value is not found.
eg/ i want to insert new user only when this username not found
what i doing now is issue 1 query to check for existing,
then another query if no existing found. total 2 query
INSERT INTO friends (memberID) SELECT 1 WHERE NOT EXISTS (SELECT memberID FROM friends WHERE memberID = 1)
You just need to add FROM DUAL
INSERT INTO friends
(memberid)
SELECT 1
FROM dual
WHERE NOT EXISTS (SELECT memberid
FROM friends
WHERE memberid = 1)
sql fiddle
How about this:
INSERT INTO YourTable (UserName)
SELECT x
FROM (SELECT 'New User Name' AS x) a
WHERE x NOT IN(SELECT UserName
FROM YourTable)
Since you only want one row with a given value you should enforce that with a UNIQUE constraint on the table, for example:
ALTER TABLE friends ADD UNIQUE (memberID);
After you do that, you can simply add the IGNORE keyword to your insert statements and it won't report an error and it won't insert a duplicate row if it already exists.
INSERT IGNORE INTO friends(memberID) VALUES(1);