Refactoring INSERT into UPDATE
I wish there where a shortcut/command to change a statement like
INSERT INTO Mytable(Id,Code,Label) VALUES (@Id,@Code,@Label)
in
UPDATE MyTable
SET Id=@Id, Code=@Code, Label =@Label
Even if it looks trivial on this statement, doing it with a table with 10+ Columns might be cumbersome.
We’re happy to announce that this feature is now included in SQL Prompt 9.3. For additional information see: http://documentation.red-gate.com/display/SP9/SQL+Prompt+9.3+release+notes.
You can get the latest version of SQL Prompt from https://www.red-gate.com/products/sql-development/sql-prompt/.
Thank you for your help!
Kind regards,
The Prompt Team
-
SC commented
Just to clarify my previous statement, let's assume in Johan's example that ID is the primary key, so picking "convert INSERT to UPDATE" would produce:
UPDATE MyTable
SET Code = @Code, Label = @Label
WHERE ID = @IDObviously, with similar things happening for composite primary keys, etc.
Similarly, if doing a convert to merge, the merge statement would be written so as to merge by the primary keys.
-
SC commented
I agree about the WHERE clause, but the theory here would be that it's simply to refactor a query you're in the process of writing. I think the idea of having a "convert INSERT to MERGE" as well would be useful, and although that's not what was originally asked for, having both would be super useful (as well as the other way round).
The WHERE clause could be as people have suggested, or maybe check the table and have WHERE PKFIELD = <placeholder> in much the same way SQL prompt generates placeholder values for INSERT queries now. So for a uniqueidentifier key it might be
WHERE PKFIELD = NEWID() -- uniqueidentifier -
Nathan commented
By default you could refactor it to this:
UPDATE MyTable
SET Id=@Id, Code=@Code, Label =@Label
WHERE Id=@Id AND Code=@Code AND Label =@LabelThat would eliminate your concern about wiping out tables while at the same time allow someone to just delete the last line or delete specific parameters from the where.
-
Doug commented
Agree with James: MERGE, MERGE, MERGE!!!!
-
JRiedemann commented
For me the usefulness would be while I'm writing code - saving me the effort of typing the UPDATE from scratch or using copy/paste. Manually converting with regex (as someone suggested) is fine if you have a simple INSERT..VALUES but it can get impractical in INSERT..SELECT or when some columns are being populated with an expression.
In Johan's original post, you could simply add a "WHERE 1 = 0" to prevent accidental data loss. Someone blindly executing generated code would be safe, and I'd have the trivial edit of changing the "1=0" to something meaningful to my code.
-
Kresten Birkegaard Gregersen commented
Would be nice if this function could include a WHERE section a la:
UPDATE MyTable
SET Id=@v1, Code=@v2, Label =@v3
WHERE (
Id!=@v1 or (Id is null and @v1 is not null) or (Id is not null and @v1 is null)
or Code!=@v2 or (Code is null and @v2 is not null) or (Code is not null and @v2 is null)
or Label !=@v3 or (Label is null and @v3 is not null) or (Label is not null and @v3 is null)
)This would prevent updating data with no changes
-
James commented
Cough MERGE Cough. I'd like both the above turned into MERGE. Always Merge.
-
Ralph commented
This is what I do in such a case:
1. Let SQL Prompt write and INSERT including all columns
2. Copy and paste the columns into Notepad++ (portable and free source)
3. Search and replace ^(.+)$ with \1 = @\1, (with search mode regular expression)
... and you are done!The same can be done with long MERGE statements. Yet, here you would replace ^(.+)$ with target.\1 = source.\1, instead.
-
jbelina commented
I would also be nice if this supported the MERGE statement for SQL Server 2008.
-
Johan Buret commented
BTW it's not the name that should match, but really the order of the elements.
What I really mean is
Changing
INSERT INTO Mytable(Id,Code,Label) VALUES (@v1,@v2,@v3)into
UPDATE MyTable
SET Id=@v1, Code=@v2, Label =@v3Stephen and Josh additions are great ones, too.
-
Stephen commented
Perhaps RG could leverage the "column picker" for INSERT and UPDATE auto-generated statements. This would address the need to skinny-down the columns suggested in Josh's first post - doing it up-front rather than some complex post-processing.
-
Josh commented
I have one more suggestion for bulk refactoring INSERT/UPDATE statements.
For instance, I have a list of of INSERT or UPDATE statements. If I add a column with a value, I want to apply that change to all instances of that statement at once. If I delete a column, it deletes both the column and value from all INSERT/UPDATE statements at once.
This allows me to manage my test-data and pre-inserted-data as my table structures/needs change over time.
-
Josh commented
I would like to see LOTS of improvements on Refactoring INSERT, update, etc. Refactoring these statements can be tedious and error prone. Here is another suggestion we badly need for INSERT in particular due to the separate lists of (columns) VALUES (values).
INSERT is auto-generated with all columns from the table by default. When I delete or comment out columns, the change should automatically reflect both before and after the keyword: VALUES. Here is my example:
INSERT INTO dbo.Test
(FirstName,
LastName,
Address1)
VALUES ('', -- FirstName - varchar(100)
'', -- LastName - varchar(100)
'' -- Address1 - varchar(100)
)If I delete LastName in the column list, it should delete the placeholder/value from the VALUES list automatically. If I comment a column, it should comment the placeholder/value from the VALUES list. If later add another column to the column list, it should add a placeholder (with column info as shown) to the VALUES list.
It is silly how time-consuming and error prone it is to keep the columns/values synchronized manually.
-
Stephen commented
Have needed to do this for a LONG time - 10 columns is a pain but having 30 to 40 coulmns is a bear! The convention Johan shows is typical - @ in front of the column name. That would be a good start as we're very capable of editing the barebones afterward.
Gets 3 of my votes...
I've posted a further suggestion based off this for developing a list of DECLARE @<column_name> <<TAB>> <column_data_type> from a table in the Explorer, or hovered over in the code itself.