Reputation: 64056
I am trying to get some test data inserted into a MySQL database, which has a mixture of reference ID's and variable values. My statement, rejected by MySQL with it's generic (and patently next to worthless) "syntax error near xxx" error is:
INSERT INTO TimeSlotWorker (TimeSlotId, WorkerId, PostCode, CitySuburbName)
SELECT TimeSlotId, 1 , PostCode, CitySuburbName
FROM (
SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 1), '2914' AS PostCode, '' AS CitySuburbName
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 2), '2912' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 2), '2913' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 2), '2911' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Charnwood'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Dunlop'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Florey'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Flynn'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Fraser'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Higgins'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Holt'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Kippax'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Latham'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Macgregor'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Melba'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2615' , 'Spence'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2614' , 'Aranda'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 3), '2614' , 'Cook'
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 4), '2617' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 5), '2602' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 5), '2612' , ''
UNION ALL SELECT TimeSlotId FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 6), '2609' , ''
)
which gives:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 ''2914' AS PostCode, '' AS CitySuburbName UNION ALL SELECT TimeSlotId FROM Time' at line 4
Expecting this to insert 22 records where for each one the singular TimeSlotId comes from an existing record and I was trying to avoid hard coding its generated ID.
Upvotes: 0
Views: 428
Reputation: 51000
Every one of the UNION-ed together SELECT statements has the same syntax error and cannot be parsed. Consider the first one in isolation
SELECT TimeSlotId FROM TimeSlot
WHERE (DayCode = 'MON' AND SequenceNbr = 1),
'2914' AS PostCode, '' AS CitySuburbName
Those extra column names must all be before the FROM keyword:
SELECT TimeSlotId, '2914' AS PostCode, '' AS CitySuburbName
FROM TimeSlot
WHERE (DayCode = 'MON' AND SequenceNbr = 1),
Separately, the whole SELECT FROM (SELECT) construction is unnecessary Instead you can INSERT the UNIONed together SELECT statements directly:
INSERT INTO Table (ColList)
SELECT SameNumberOfColumns FROM OtherTable WHERE . . .
UNION ALL
SELECT SameNumberOfColumns FROM OtherTable WHERE . . .
(and so on)
Upvotes: 1
Reputation: 92805
To make your current code to work change it to
INSERT INTO TimeSlotWorker (TimeSlotId, WorkerId, PostCode, CitySuburbName)
SELECT TimeSlotId, 1 , PostCode, CitySuburbName
FROM
(
SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 1) TimeSlotId, '2914' PostCode, '' CitySuburbName
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2) , '2912' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2) , '2913' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2) , '2911' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Charnwood'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Dunlop'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Florey'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Flynn'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Fraser'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Higgins'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Holt'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Kippax'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Latham'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Macgregor'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Melba'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2615' , 'Spence'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2614' , 'Aranda'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3) , '2614' , 'Cook'
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 4) , '2617' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 5) , '2602' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 5) , '2612' , ''
UNION ALL SELECT (SELECT TimeSlotId FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 6) , '2609' , ''
) q
Here is SQLFiddle demo
You can rewrite it this way
INSERT INTO TimeSlotWorker (TimeSlotId, WorkerId, PostCode, CitySuburbName)
SELECT TimeSlotId, 1, '2914', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 1 UNION ALL
SELECT TimeSlotId, 1, '2912', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2 UNION ALL
SELECT TimeSlotId, 1, '2913', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2 UNION ALL
SELECT TimeSlotId, 1, '2911', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 2 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Charnwood' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Dunlop' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Florey' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Flynn' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Fraser' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Higgins' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Holt' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Kippax' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Latham' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Macgregor' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Melba' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2615', 'Spence' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2614', 'Aranda' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2614', 'Cook' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 3 UNION ALL
SELECT TimeSlotId, 1, '2617', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 4 UNION ALL
SELECT TimeSlotId, 1, '2602', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 5 UNION ALL
SELECT TimeSlotId, 1, '2612', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 5 UNION ALL
SELECT TimeSlotId, 1, '2609', '' FROM TimeSlot WHERE DayCode = 'MON' AND SequenceNbr = 6
Here is SQLFiddle demo
Upvotes: 2
Reputation: 116140
.1. You subquery had only one column, TimeslotId, while in the main query, you select three (PostCode and CitySuburbName as well). That's not really a syntax error, but it is incorrect. The syntax error is in the fact that you do add those missing fields after the select statement, while they should be part of it.
You'll need to format the subquery like this:
SELECT TimeSlotId, '2914' AS PostCode, '' AS CitySuburbName FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 1)
UNION ALL SELECT TimeSlotId, '2912', '' FROM TimeSlot WHERE (DayCode = 'MON' AND SequenceNbr = 2)
UNION ALL ...
So, make the constant value for PostCode and CitySuburbName part of the field list. You cannot just paste them after the select statement.
.2. I think this is a pretty good way. One of the best. :)
.3. I'm not sure what you mean, but it sounds like you can just leave DayCode
out of the where clause, so each query in the union returns multiple records.
Upvotes: 1