I've written the below code to set filepath column in my table as 'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\SR_1.txt'
where SR_1 is file_name column
.txt is file_ext column from my table.
but after executing following procedure, I'm getting filepath column in table as
'F:\DataMigration\Wise\DELTA_20121008\Attachments\file_name.file_ext'
means It's treating column names as string, how i can make it as column so it will
use values in that column.
alter procedure [dbo].[WISEMissingAttachmentReportGenerator]
(
#tablename varchar(255), #pathonlocal nvarchar(255)
)
as
begin
--step 1
exec dbo.proc_alter_table #tablename
--step 2
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ' file_name'+'.'+'file_ext''')
EXEC('Select * from '+#tablename)
end
exec [dbo].[WISEMissingAttachmentReportGenerator] [WISE.Non_VP_Service_Request_Attachments_File_Check_Analysis],
N'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\'
Try;
EXEC('UPDATE '+ #tablename +
' SET filepath = '''+ #pathonlocal + ''' + file_name + '''+'.'+''' + file_ext')
Equal as;
UPDATE [YourTable] SET filepath = 'YourPath' + file_name + '.' + file_ext
Try changing your statement to this:
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ''' + file_name + ''.'' + file_ext')
declare #tblnm varchar(20) = 'test'
declare #upda varchar(20) = 'update '
declare #set varchar(25) = ' set'
declare #id varchar(25) = ' id'
declare #cmd varchar(1000)
set #cmd = #upda + #tblnm + #set + #id + '=7'
exec(#cmd)
SAMPLE SQL UPDATE QUERY - FOR BUILDING TABLENAME DYNAMICALLY
EXECUTED GUYS - THIS IS CALL JUGAAAAAAAAAD [NO NEED TO GET INTO ''' STUFF]
Related
I'm using an original script I found a long time ago to create a bulk import of many CSV files into an SQL database. With minor adjustments the script is working for me, but I can't get rid of the double quotes as FIELDQUOTE.
DECLARE #Path NVARCHAR(255) = 'D:\TEMP\'
DECLARE #RowTerminator NVARCHAR(5) = CHAR(13) + CHAR(10)
DECLARE #ColumnTerminator NVARCHAR(5) = CHAR(44)
DECLARE #FieldQuote NVARCHAR(5) = CHAR(34)
--DECLARE #FieldQuote NVARCHAR(5) = '"'
IF OBJECT_ID('[dbo].[Files_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Files_Temporary];
CREATE TABLE [dbo].[Files_Temporary]
(
[ID] INT
, [FileName] NVARCHAR(255)
, [TableName] NVARCHAR(255)
);
INSERT INTO [dbo].[Files_Temporary] SELECT 1, 'MyFile.txt', 'MyfileA'
INSERT INTO [dbo].[Files_Temporary] SELECT 2, 'MyFile.txt', 'MyFileB'
DECLARE #Counter INT = 1
WHILE #Counter <= (SELECT COUNT(*) FROM [dbo].[Files_Temporary])
BEGIN
PRINT 'Counter is ''' + CONVERT(NVARCHAR(5), #Counter) + '''.'
DECLARE #FileName NVARCHAR(255)
DECLARE #TableName NVARCHAR(255)
DECLARE #Header NVARCHAR(MAX)
DECLARE #SQL_Header NVARCHAR(MAX)
DECLARE #CreateHeader NVARCHAR(MAX) = ''
DECLARE #SQL_CreateHeader NVARCHAR(MAX)
SELECT #FileName = [FileName], #TableName = [TableName] FROM [dbo].[Files_Temporary] WHERE [ID] = #Counter
IF OBJECT_ID('[dbo].[' + #TableName + ']', 'U') IS NULL
BEGIN
PRINT 'Creating new table with name ''' + #TableName + '''.'
IF OBJECT_ID('[dbo].[Header_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Header_Temporary];
CREATE TABLE [dbo].[Header_Temporary]
(
[Header] NVARCHAR(MAX)
);
SET #SQL_Header = '
BULK INSERT [dbo].[Header_Temporary]
FROM ''' + #Path + #FileName + '''
WITH
(
FIRSTROW = 1,
LASTROW = 1,
MAXERRORS = 0,
FIELDTERMINATOR = ''' + #RowTerminator + ''',
ROWTERMINATOR = ''' + #RowTerminator + ''',
FIELDQUOTE = ''' + #FieldQuote + '''
)'
EXEC(#SQL_Header)
SET #Header = (SELECT TOP 1 [Header] FROM [dbo].[Header_Temporary])
PRINT 'Extracted header ''' + #Header + ''' for table ''' + #TableName + '''.'
WHILE CHARINDEX(#ColumnTerminator, #Header) > 0
BEGIN
SET #CreateHeader = #CreateHeader + '[' + LTRIM(RTRIM(SUBSTRING(#Header, 1, CHARINDEX(#ColumnTerminator, #Header) - 1))) + '] NVARCHAR(255), '
SET #Header = SUBSTRING(#Header, CHARINDEX(#ColumnTerminator, #Header) + 1, LEN(#Header))
END
SET #CreateHeader = #CreateHeader + '[' + #Header + '] NVARCHAR(255)'
SET #SQL_CreateHeader = 'CREATE TABLE [' + #TableName + '] (' + #CreateHeader + ')'
EXEC(#SQL_CreateHeader)
END
PRINT 'Inserting data from ''' + #FileName + ''' to ''' + #TableName + '''.'
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
BULK INSERT [dbo].[' + #TableName + ']
FROM ''' + #Path + #FileName + '''
WITH
(
FIRSTROW = 2,
MAXERRORS = 0,
FIELDTERMINATOR = ''' + #ColumnTerminator + ''',
ROWTERMINATOR = ''' + #RowTerminator + ''',
FIELDQUOTE = ''' + #FieldQuote + '''
)'
EXEC(#SQL)
SET #Counter = #Counter + 1
END;
IF OBJECT_ID('[dbo].[Files_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Files_Temporary];
IF OBJECT_ID('[dbo].[Header_Temporary]', 'U') IS NOT NULL
DROP TABLE [dbo].[Header_Temporary];
I've declared a variable, but neither the of both give me the correct result. The import is succesfull, but fieldquote is not ignored.
DECLARE #FieldQuote NVARCHAR(5) = CHAR(34)
--DECLARE #FieldQuote NVARCHAR(5) = '"'
I'm using SSMS V18.10
Just add one more setting like below to take care of double quotes.
It will work starting from SQL Server 2017 onwards.
SQL
...
WITH (
FORMAT='CSV'
...
I wrote this query for searching a string in whole database . Earlier it was working properly now it doesn't fetch full result at all . I don't get what is wrong with this query . Please help
QUERY
/*
- Search through tables to find specific text
- Written by Luis Chiriff (with help from SQL Server Central)
- luis.chiriff#gmail.com # 24/11/2008 # 11:54
*/
-- Variable Declaration
Declare #StringToFind VARCHAR(200), #Schema sysname, #Table sysname, #FullTable int, #NewMinID
int, #NewMaxID int,
#SQLCommand VARCHAR(8000), #BaseSQLCommand varchar(8000), #Where VARCHAR(8000), #CountCheck
varchar(8000) , #FieldTypes varchar(8000),
#cursor VARCHAR(8000), #columnName sysname, #SCn int, #SCm int
Declare #TableList table (Id int identity(1,1) not null, tablename varchar(250))
Declare #SQLCmds table (id int identity(1,1) not null, sqlcmd varchar(8000))
Declare #DataFoundInTables table (id int identity(1,1) not null, sqlcmd varchar(8000))
-- Settings
SET #StringToFind = 'abcdef'
SET NOCOUNT ON
SET #StringToFind = '%'+#StringToFind+'%'
-- Gathering Info
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
create table tempcount (rowsfound int)
insert into tempcount select 0
-- This section here is to accomodate the user defined datatypes, if they have
-- a SQL Collation then they are assumed to have text in them.
SET #FieldTypes = ''
select #FieldTypes = #FieldTypes + '''' + rtrim(ltrim(name))+''',' from systypes where collation
is not null or xtype = 36
select #FieldTypes = left(#FieldTypes,(len(#FieldTypes)-1))
insert into #TableList (tablename)
select name from sysobjects
where xtype = 'U' and name not like 'dtproperties'
order by name
-- Start Processing Table List
select #NewMinID = min(id), #NewMaxID = max(id) from #TableList
while(#NewMinID <= #NewMaxID)
Begin
SELECT #Table = tablename, #Schema='dbo', #Where = '' from #TableList where id = #NewMinID
SET #SQLCommand = 'SELECT * FROM ' + #Table + ' WHERE'
-- removed ' + #Schema + '.
SET #cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME
FROM [' + DB_NAME() + '].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ''' + #Schema + '''
AND TABLE_NAME = ''' + #Table + '''
AND DATA_TYPE IN ('+#FieldTypes+')'
--Original Check, however the above implements user defined data types --AND DATA_TYPE IN
(''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')'
EXEC (#cursor)
SET #FullTable = 0
DELETE FROM #SQLCmds
OPEN col_cursor
FETCH NEXT FROM col_cursor INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Where = #Where + ' [' + #columnName + '] LIKE ''' + #StringToFind + ''''
SET #Where = #Where + ' OR'
--PRINT #Table + '|'+ cast(len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) as varchar(10))+'|'+#Where
if (len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) > 3600)
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd) select #Where
SET #Where = ''
End
FETCH NEXT FROM col_cursor INTO #columnName
END
CLOSE col_cursor
DEALLOCATE col_cursor
if (#Where <> '')
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd)
select #Where --select #Table,count(*) from #SQLCmds
End
SET #BaseSQLCommand = #SQLCommand
select #SCn = min(id), #SCm = max(id) from #SQLCmds
while(#SCn <= #SCm)
Begin
select #Where = sqlcmd from #SQLCmds where ID = #SCn
if (#Where <> '')
Begin
SET #SQLCommand = #BaseSQLCommand + #Where
SELECT #CountCheck = 'update tempcount set rowsfound = (select count(*) '+ substring(#SQLCommand,10,len(#SQLCommand)) + ')'
EXEC (#CountCheck)
if ((select rowsfound from tempcount) > 0)
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table + ' ----------------------------------[FOUND!]'
--PRINT '--- [FOUND USING:] ' +#SQLCommand
insert into #DataFoundInTables (sqlcmd) select #SQLCommand
EXEC (#SQLCommand)
update tempcount set rowsfound = 0
End
else
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table
End
End
SET #SCn = #SCn + 1
End
set #NewMinID = #NewMinID + 1
end
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
/*
This will now return all the sql commands you need to use
*/
select #NewMinID = min(id), #NewMaxID = max(id) from #DataFoundInTables
if (#NewMaxID > 0)
Begin
PRINT ' '
PRINT ' '
PRINT '-----------------------------------------'
PRINT '----------- TABLES WITH DATA ------------'
PRINT '-----------------------------------------'
PRINT ' '
PRINT 'We found ' + cast(#NewMaxID as varchar(10)) + ' table(s) with the string '+#StringToFind
PRINT ' '
while(#NewMinID <= #NewMaxID)
Begin
select #SQLCommand = sqlcmd from #DataFoundInTables where ID = #NewMinID
PRINT #SQLCommand
SET #NewMinID = #NewMinID + 1
End
PRINT ' '
PRINT '-----------------------------------------'
End
This query was working fine one month ago but now it doesn't fetch the results . Can anyone tell me what is wrong in this query .
I would like to ask how can I insert a variables into a table using INSERT INTO x SELECT statement via dynamic SQL.
I have following table:
|-------------------|-----------------|--------------|-----------------|
| TableName | ColName | Value | SQL_Statement |
|-------------------|-----------------|--------------|-----------------|
I get a content for Value column by this query:
INSERT INTO #ReturnTable(Value) SELECT TreeHolder FROM prm.Schm_Root WHERE ParentTreeHolderId = 'DD040D31-4591-4658-A02E-A6ED00AB64F2';
But I need to fill whole table. Please consider that other values are variables, not SQL queries.
SELECT #TableSchema = TableSchema FROM #TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM #TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM #TableNames WHERE Id = #Counter;
SET #SQL_Statement = 'SELECT ' + #ColName + ' FROM ' + #TableSchema + '.' + #TableName + ' WHERE ' + #ColName + ' = ' + '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''' + ';';
Now I have this query that fills a table:
SET #SQL_String = N'INSERT INTO #ReturnTable SELECT
''' + #TableName + ''',
''' + #ColName + ''',
''' + #SQL_Statement + ''',
'' + Value + '',
(SELECT ' +
#ColName + '
FROM ' +
#TableSchema + '.' + #TableName + '
WHERE ' +
#ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '
'')';
EXECUTE sp_executesql #SQL_String
PRINT #SQL_String;
The thing I need is to rewrite this query from INSERT INTO ? VALUE to INSERT INTO ? SELECT format.
If I understand correctly, you want to insert SQL execute syntax string and it results in ReturnTable table.
I would let subquery SQL execute syntax save in a variable. because the will be more clear what you need to do.
Declare a new variable #SQL_excuteStatement variable to save your execute syntax.
the #SQL_Statement to carry the original SQL string.
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+'''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
and use select ... from table instead of subquery in select
There is a sample for you.
DECLARE #SQL_String NVARCHAR(MAX)
DECLARE #TableSchema NVARCHAR(MAX)
DECLARE #TableName NVARCHAR(MAX)
DECLARE #ColName NVARCHAR(MAX)
DECLARE #Counter int = 1
DECLARE #SQL_Statement NVARCHAR(MAX)
DECLARE #GuidArgument INT = 1
CREATE TABLE TableNames(
ID INT,
TableSchema NVARCHAR(100),
TableName NVARCHAR(100),
ColName NVARCHAR(100)
);
CREATE TABLE ReturnTable(
TableName NVARCHAR(100),
ColName NVARCHAR(100),
SQL_Statement NVARCHAR(max),
value nvarchar(max)
);
INSERT INTO TableNames VALUES (1,'dbo','T','val');
CREATE TABLE T(val INT);
INSERT INTO T VALUES (1)
SELECT #TableSchema = TableSchema FROM TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM TableNames WHERE Id = #Counter;
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+ '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
SET #SQL_String = N'INSERT INTO ReturnTable (TableName,ColName,SQL_Statement,value)
SELECT '''+ #TableName + ''','''+ #ColName + ''','''+ #SQL_Statement + '''' + ',' + QUOTENAME(#ColName) +
' FROM ' + QUOTENAME(#TableSchema) + '.' + QUOTENAME(#TableName) + '' +
' WHERE ' + #ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''';
EXECUTE sp_executesql #SQL_String
sqlfiddle
Note
I would suggest you use clear column after insert into
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX),
#servername NVARCHAR(255)
SET #servername = '[s-printstream]'
--Drop Table #Actual
CREATE TABLE #Actual
(
jobnumber INT,
firstNameCounts VARCHAR(25),
lastNameCounts VARCHAR(25),
address1Counts VARCHAR(25),
address2Counts VARCHAR(25),
cityCounts VARCHAR(25),
stateCounts VARCHAR(25),
zipCounts VARCHAR(25),
inHomeDateCounts VARCHAR(25)
)
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts , address1Counts, address2Counts, cityCounts, stateCounts, zipCounts, inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS [firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1) As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count (s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count (jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From' + ' #servername ' + '.[tdis_417133]' + '.[dbo].[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
SET #sql = #sql + ' where jobNumber = #jobNumber '
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC sp_executesql #sql
,N'#JobNumber Varchar(25)'
,#JobNumber = 417133
Could anyone please help me find out how I would pass my server name dynamically as well as the database name? When I try to do it, I get this error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#servername"
Any help is appreciated.
Thanks
or pass #servername value into sql command
EXEC sp_executesql #sql
,N'#JobNumber Varchar(25),#servername nvarchar(255)'
,#JobNumber = 417133,#servername=#servername
So, I've been hunting for a solution for this for awhile and have come up with what sort of works ... but I can't help feeling that there must be something more elegant.
What I'm looking for is to be able to extract existing data from a populated database & incorporate that data into loading scripts. The database schema & configuration data will be rolled out multiple times, and will change as development continues, so it's important to be able to rebuild the configuration data from existing data, rather than from static data kept in scripts.
Here's what I've cobbled together:
create procedure #dump (
#TableName varchar(128)
)
as
set nocount on
set rowcount 0
declare #template varchar(max)
set #template = 'SET IDENTITY_INSERT [dbo].[' + #TableName + '] ON
MERGE INTO [dbo].[' + #TableName + '] AS [Target]
USING
(
VALUES
{vals}
)
AS [Source] ({fields})
ON [Target].[{pk}] = [Source].[{pk}]
WHEN MATCHED THEN UPDATE SET
{upds}
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
{fields}
)
VALUES
(
{fields}
);
SET IDENTITY_INSERT [dbo].[' + #TableName + '] OFF
--------------------------------------------------
'
declare #pk varchar(max) = ''
declare #vals varchar(max) = '/*
set concat_null_yields_null off
select ''' + '(' + ''' + replace(replace({casts} + '') ,'', '',,'', '', null,''), ''' + ',)' + ''', ''' + ',null)' + ''') from [' + #TableName + ']
*/'
declare #casts varchar(max) = ''
declare #fields varchar(max) = ''
declare #upds varchar(max) = ''
declare #inserts varchar(max) = ''
set #pk = SUBSTRING(#TableName, 1, len(#TableName) - 1) + 'ID'
declare cur_flds
cursor for select c.name, c.type
from syscolumns c
where c.id = object_id(#TableName)
order by c.colid
declare #fn varchar(max)
declare #ft int
open cur_flds
fetch next from cur_flds into #fn, #ft
while ##FETCH_STATUS = 0
begin
if len(#fields) > 0
set #fields = #fields + ', '
set #fields = #fields + '[' + #fn + ']'
if len(#casts) > 0
set #casts = #casts + ' + ' + ''','' + '
if #ft in(56,55,50,38,48)
set #casts = #casts + 'cast([' + #fn + '] as varchar)'
else if #ft = 111
set #casts = #casts + ''''''''' + ' + 'cast([' + #fn + '] as varchar) + ' + ''''''''''
else
set #casts = #casts + ''''''''' + ' + 'replace([' + #fn + '], ''''''''' + ', ' + ''''''''''''') + '''''''''
if #fn != #pk
begin
if len(#upds) > 0
set #upds = #upds + ', '
set #upds = #upds + '[Target].[' + #fn + '] = [Source].[' + #fn + ']'
end
fetch next from cur_flds into #fn, #ft
end
close cur_flds
deallocate cur_flds
set #vals = REPLACE(#vals, '{casts}', #casts)
set #template = REPLACE(#template, '{pk}', #pk)
set #template = REPLACE(#template, '{vals}', #vals)
set #template = REPLACE(#template, '{fields}', #fields)
set #template = REPLACE(#template, '{upds}', #upds)
set #template = REPLACE(#template, '{inserts}', #inserts)
print #template
go
exec #dump 'ActionItemSystems'
drop proc #dump
That ends up giving me output of:
SET IDENTITY_INSERT [dbo].[ActionItemSystems] ON
MERGE INTO [dbo].[ActionItemSystems] AS [Target]
USING
(
VALUES
/*
set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]
*/
)
AS [Source] ([ActionItemSystemID], [ActionItemSystemName])
ON [Target].[ActionItemSystemID] = [Source].[ActionItemSystemID]
WHEN MATCHED THEN UPDATE SET
[Target].[ActionItemSystemName] = [Source].[ActionItemSystemName]
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[ActionItemSystemID], [ActionItemSystemName]
)
VALUES
(
[ActionItemSystemID], [ActionItemSystemName]
);
SET IDENTITY_INSERT [dbo].[ActionItemSystems] OFF
From this point, I can take the commented-out bit
set concat_null_yields_null off
select '(' + replace(replace(cast([ActionItemSystemID] as varchar) + ',' + '''' + replace([ActionItemSystemName], '''', '''''') + '''' + ') ,', ',,', ', null,'), ',)', ',null)') from [ActionItemSystems]
execute that, and get output like:
(33,'7111-5 -Upstream/Seed Lab') ,
(32,'7301-Seed Lab') ,
(30,'7807 UFDF') ,
(14,'BAS Panel Upgrade') ,
(1,'Clean Steam') ,
(13,'DCS') ,
(2,'HWFI') ,
(3,'MCS') ,
(12,'MES') ,
(31,'Seed Lab') ,
(18,'UCS WRO') ,
(34,'Upstream Seed Lab') ,
(29,'Viral Filtration') ,
which can then be incorporated (sans the final comma) into the script.
Now, this solution functions, but it's fragile. It depends on various assumptions (e.g., that the Table Name will have a Primary Key of Table Name - trailing 's' and plus ID) that may not hold true for every solution. It also requires cutting & pasting, and rerunning from the start when the table structures change.
This is probably quite a lot of background ... which I'm partly sharing because I couldn't find anything similar out there & thought that somebody might benefit from this. However, I still come back to my real question, which is to say: where's the tool to generate this kind of script for VS Database Projects? There really should be something - something that would take into account whatever the primary key is, that would generate the thing entire, etc.
You can try with this procedure for generating MERGE statements:
https://github.com/readyroll/generate-sql-merge
It is more advanced version of what you already have.