Using The INSERT INTO ... SET Syntax In MySQL
A little while back, I was doing a code review for one my colleagues - Bryan Stanley - when I saw him using an INSERT syntax that I had never seen before. Rather than the traditional INSERT INTO ... VALUES syntax, he was using an INSERT INTO ... SET syntax. This appears to be a MySQL-specific extension to the SQL syntax; but, it's pretty darned cool.
Here's what it would look like to insert a new "friend" record:
-- Create a new friend record.
INSERT INTO
friend
SET
name = 'Kim',
isBFF = true,
updatedAt = UTC_TIMESTAMP()
;
-- Return the newly-generated primary-key.
SELECT
( @@Identity ) AS id
;
The most obvious benefit of this syntax, in my opinion, is that is puts the column names and insert values in very close proximity. This completely eliminates the possibility of providing column names and values in an incorrect order. It also cuts down on the cognitive overhead of understanding the query as you don't need to jump back-and-forth between two different portions of the statement.
So far, I've started using this syntax in some migration scripts. But, I've yet to fully embrace it for the core areas of the application. Since it's not a "standard" part of the SQL syntax, I always feel a little hesitant about embracing it. But, that's just an emotional response; if I'm going to use a particular database storage engine, I might as well benefit from that choice rather than feel limited by it.
Want to use code from this post? Check out the license.
Reader Comments
I'll go you one better:
INSERT INTO
friend
OUTPUT @@Identity
SET
name = 'Kim',
isBFF = true,
updatedAt = UTC_TIMESTAMP()
;
@Matt,
What does the "OUTPUT" token do? Not sure what this is doing with the @@Identity value?
>> puts the column names and insert values in very close proximity
This makes me happy.
Thank you.
@Michael,
Right?! I can't tell you how many queries I've debugging were the column names and the values were in different orders :D
Ben-
Something might be up with your comment subscription. I didn't get an update to any of this.
And @@Identity is a SQL Server thing, but you can replicate it in other DBMSs, I'm sure. It's just a handle to the last autoincrementing Identity value added to a table.
Assuming you use auto-incrementing values that don't represent table data, thus allowing for relational integrity issues. As opposed to a natural key made up of the fields that naturally define a unique set of data. But, sadly, that's a fight long lost.
@Matt,
Sorry, I think I miscommunicated. I understand the "@@Identity" portion. In fact, MySQL supports that as well (which is much nicer on the eyes than that LAST_INSERT_ID() mumbo-jumbo). What I meant was that I didn't understand what the "OUTPUT" token did.
Taking a look at the docs: https://msdn.microsoft.com/en-us/library/ms177564.aspx
.... hmm, looks to me a MSSQL thing that MySQL doesn't have parity for. But, at least they each expose the @@Identity for the last inserted record, which is typically what I need.
@Matt,
FYI, I just checked my SMTP service and it looks like you should have gotten an email about the comment I just left. So, if you're not getting things, it might be going to spam?
Nice one Ben! Will have to try that.
Just a heads up for anyone reading this on using @@IDENTITY: it's not scope safe. Better to use SCOPE_IDENTITY(), which always returns the newly created ID in the scope of the request you are executing.
Explanation:
http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/
@Evagoras,
To be honest, I've __never__ understood the scope-safety argument. I've seen that pointed out before, but I've never understood the practical implications.
@Matt,
By this model, Sql can not go wrong, it is said that in the write speed than the'Insert into (values) 'fast.
@Lee,
I agree - much hard to make a mistake :D
how would one insert multiple rows then?