Insert into tables based on updating list (table) - sql-server

Ive been struggling with this one for a while and appreciate any help.
I have a table that continuously get updated with a list of table names (same table can occure several times) that has been updated with new data recently in Database 1.
I want to create a query that checks this update list and inserts the data from updated tables in Database 1, into corresponding tables in Database 2. And loops through until the end of the list.
The list can look like this:
ID Table TimeStamp
----------------------- -------- -----------------------
0313778E-CB68-E811-910D Customer 2018-07-10 13:27:28.567
0313778E-CB68-E811-910D Customer 2018-07-10 13:28:58.010
194DD17A-CE68-E811-910D Order 2018-07-10 13:27:28.567
0EBB391D-126B-E811-910D Product 2018-07-10 13:28:58.010
4AAE33A5-CE68-E811-910D Customer 2018-07-10 13:27:28.567
DFA2A68C-056B-E811-910D Order 2018-07-10 13:28:58.010
C2CFECB6-CE68-E811-910D Employee 2018-07-10 13:27:28.583
To make it worse, the tables in Database 2 don't have same amount of columns as Database 1.
Ive been working on both MERGE and Cursor, as well as dynamic SQL. Im new to these so keep getting stuck. I think dynamic SQL + CURSOR is the best way to go. All of this will result in a stored procedure. Maybe there is a better way of doing it? Anyway, this is what I have:
Declare #Source_TableName_Column --this one contains the Database 1 tables as well as the correct columns needed to fill matching table in Database 2.
Declare #InsertInto NVARCHAR(MAX),
#TargetTable NVARCHAR(MAX)='Select name from Database2.sys.all_objects', --list of tables I have in Database 2
#Columns NVARCHAR(MAX) = 'Select name from Database2.sys.all_columns', --list of columns I have in Database 2 (same names as it is in SourceTable in Database 1)
;
DECLARE TableInsert CURSOR FOR
SELECT distinct SourceTableName from Database3.dbo.UpdateTableList
OPEN TableInsert
FETCH NEXT FROM TableInsert
INTO #TableName
--LOOP
WHILE ##FETCH_STATUS=0
BEGIN
SET #InsertInto = 'insert into Database2.dbo.'+#TargetTable+' '+(#Columns)+' values'+(....)+'' --not sure how to do this variable where i get all the results from SourceTable matching columns in TargetTable in database 2
FETCH NEXT FROM TableInsert
INTO #TableName
END
--CLOSE CURSOR
CLOSE TableInsert
DEALLOCATE TableInsert

This is complex. I would approach it in a simpler fashion than what you are doing. I’d do it your way if scenario involved destination tables with the same schema, but numerous columns, which does not seem to be the case with you.
Here’s what i’d do.
Open cur1
Fetch next from cur1 into #tablename ....
While ##fetchstatus = 0
Begin
If ##tablename= ‘tbl1’
Begin
Insert into database2.dbo.tbl2 values
Select ... from database1.dbo.table1 where ..
End
If ##tablename = ‘tblx’
And so on
Fetch next from cur1 into ...
End

I made a solution that works for me. Some names I have changed here to better fit my description above. I think they are correct, will look through it later and correct it if wrong =)
I am, however, a bit unsure about the delete statement further down in the code.
I have a TempTable based on the update list. I want to delete the rows in the update list after Ive inserted into tables. I have one with two 'where field IN (corresponding field in TempTable' clauses and another one with a 'delete from ... where exists (tempTable). Temptable has two columns but update list has three in total. Whichever is fastest/best?
DECLARE #InsertInto NVARCHAR(MAX);
DECLARE #SourceID NVARCHAR(MAX);
DECLARE #TableAttribute NVARCHAR(MAX);
DECLARE #SourceViewName NVARCHAR(MAX);
DECLARE #TargetTable NVARCHAR(MAX);
DECLARE #SourceTableName NVARCHAR(MAX);
/*-------Create temp table to be used in cursor-------*/
Declare #SQL_TempTable_Insert NVARCHAR(MAX);
IF OBJECT_ID('tempdb..#Cursor_TempTable') IS NOT NULL DROP TABLE #Cursor_TempTable
CREATE TABLE #Cursor_TempTable (
SourceEntity NVARCHAR(MAX) )
/*-------variable to be used in insert step below-------*/
SET #SQL_TempTable_Insert = 'SELECT SourceLogicalName FROM DataBaseC.dbo.REF_ENTITIES_SYNC group by SourceLogicalName'
/*-------Insert into temp table-------*/
INSERT INTO #Cursor_TempTable EXECUTE (#SQL_TempTable_Insert)
/*-------Create temp table from NeworUpdate table-------*/
Declare #SQL_TempTable_NewOrUpdated NVARCHAR(MAX);
IF OBJECT_ID('tempdb.. #TempTable_NewOrUpdated') IS NOT NULL DROP TABLE #TempTable_NewOrUpdated
CREATE TABLE #TempTable_NewOrUpdated (
[ID] NVARCHAR(MAX),
[TimeStamp] DATETIME )
/*-------variable to be used in insert step below in NewOrUpdate temp table-------*/
SET #SQL_TempTable_NewOrUpdated = 'SELECT ID, TimeStamp FROM DataBaseC.dbo.[REF_POSTS_NewOrUpdated] group by ID, TimeStamp'
/*-------Insert into NewOrUpdate temp table-------*/
INSERT INTO #TempTable_NewOrUpdated EXECUTE (#SQL_TempTable_NewOrUpdated)
/*-------Cursor segment-------*/
DECLARE EntitiesInsert CURSOR FOR
SELECT SourceEntity FROM #Cursor_TempTable
OPEN EntitiesInsert
FETCH NEXT FROM EntitiesInsert
INTO #TargetTable
--LOOP
WHILE ##FETCH_STATUS=0
BEGIN
BEGIN TRY
BEGIN TRAN
SET #SourceViewName = (select SourceName from DataBaseC.dbo.REF_ENTITIES_SYNC where Targetname = #TargetTable);
SET #SourceTableName = (select SourceTableName from DataBaseC.dbo.REF_ENTITIES_SYNC where Targetname = #TargetTable);
SET #TableAttribute = stuff(( select ', ' +char(10)+ ac.[name] from DataBaseB.sys.all_columns ac
inner join DataBaseB.sys.all_objects ao on ao.object_id=ac.object_id
where ao.name = #TargetTable and ac.name not in ('ValidFrom','ValidTo')
FOR XML PATH('')
), 1, 1, '')
--Finds DatabaseA table's Primary Key
SET #SourceID = (select c.name
from sys.index_columns ic
inner join sys.columns c on ic.object_id = c.object_id and ic.column_id = c.column_id
inner join sys.indexes i on ic.object_id = i.object_id and ic.index_id = i.index_id
inner join sys.tables t on i.object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where i.is_primary_key= 1 and t.name = #SourceTableName);
SET #InsertInto = 'INSERT INTO DataBaseB.dbo.'+#TargetTable+' ('+#TableAttribute+')
SELECT '+#TableAttribute+' FROM DataBaseA.dbo.'+#SourceViewName+'
where '+#SourceID+' in (select nu.ID from DataBaseC.Inno.REF_ENTITIES_SYNC sync inner join #TempTable_NewOrUpdated nu on nu.SourceEntity = sync.TargetName where sync.TargetName = '''+#TargetTable+''' group by nu.ID )'
EXEC sp_sqlexec #insertInto
--Delete the records from [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated] that we have inserted.
--DELETE FROM [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated]
-- WHERE ID = (select [ID] from #TempTable_NewOrUpdated)
-- AND TimeStamp = (select [Timestamp] from #TempTable_NewOrUpdated)
----alt2
--DELETE FROM [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated]
-- where exists (select * from #TempTable_NewOrUpdated)
--End TRAN
COMMIT
--End TRY
END TRY
--Catch possible errors
BEGIN CATCH
--IF there is an open transaction then roll back and print error messages.
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION
DECLARE #ErrorNumber INT = ERROR_NUMBER();
DECLARE #ErrorLine INT = ERROR_LINE();
DECLARE #ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
DECLARE #ErrorSeverity INT = ERROR_SEVERITY();
DECLARE #ErrorState INT = ERROR_STATE();
PRINT 'Actual error number: ' + CAST(#ErrorNumber AS VARCHAR(10));
PRINT 'Actual line number: ' + CAST(#ErrorLine AS VARCHAR(10));
PRINT 'Actual error message: ' + CAST(#ErrorMessage AS VARCHAR(MAX));
PRINT 'Actual error Severity: ' + CAST(#ErrorSeverity AS VARCHAR(MAX));
PRINT 'Actual error State: ' + CAST(#ErrorState AS VARCHAR(MAX));
END CATCH
FETCH NEXT FROM EntitiesInsert
INTO #TargetTable
END
CLOSE EntitiesInsert
DEALLOCATE EntitiesInsert
GO

Related

create a table with table and database statistics

There are around 200+ tables in our SQL DB and every table has 1 common field [updated_timestamp]
Is there a way to query the DB itself and list all tables, with the MAX value of [updated_timestamp] and the row count of each table?
i'm sorry if i've not explained that the best
are there secret/system tables that hold such info?
my desired output would be
table
updated_timestamp
row_count
Table A
2022-08-22
89,854
Table B
2022-08-18
103,55,166
if there is a table like this i could intergate that would be great, but i'm assuming not that simple.
i picked up some code from another stored procedure and was hoping this would be of use for the row count at least
SELECT
QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) AS [DB_Schema],
QUOTENAME(sOBJ.name) AS [TableName],
SUM(sPTN.Rows) AS [Row_Count]
INTO ##tmpRowCount2
FROM
sys.objects AS sOBJ
INNER JOIN sys.partitions AS sPTN
ON sOBJ.object_id = sPTN.object_id
WHERE
sOBJ.type = 'U'
AND sOBJ.is_ms_shipped = 0x0
AND index_id < 2
GROUP BY
sOBJ.schema_id
, sOBJ.name
ORDER BY [Row_Count]
GO
ALTER TABLE ##tmpRowCount2 ADD updated_timestamp datetime NULL;
-- keep only API rows
DELETE FROM ##tmpRowCount2
WHERE [DB_Schema] != '[api]'
DECLARE #Row_Count int
DECLARE #sql nvarchar(max)
DECLARE #TableName as VARCHAR(256)
DECLARE #DB_Schema as VARCHAR(256)
DECLARE #updated_timestamp as DATETIME
DECLARE tablenamefromcursor CURSOR FOR
SELECT TableName,
Row_Count,
DB_Schema
FROM ##tmpRowCount2
OPEN tablenamefromcursor
FETCH NEXT FROM tablenamefromcursor INTO #TableName, #Row_Count, #DB_Schema
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'UPDATE ##tmpRowCount2 SET updated_timestamp = ' +
'(SELECT MAX([updated_timestamp]) FROM ' + #DB_Schema + '.' + #TableName +
') WHERE TableName = ''' + #TableName + ''''
EXEC(#sql)
FETCH NEXT FROM tablenamefromcursor INTO #TableName, #Row_Count, #DB_Schema
END
CLOSE tablenamefromcursor
DEALLOCATE tablenamefromcursor
Code editied above and i can confirm it works, by debugging with select #sql iwas able to parse the statement and edit the syntax unitl it worked by getting the parethesis and quotes in the right order

How can I list all databases and all tables of my databases with a final "Attach" and list total row of each table in SQL Server?

I did this. But unfortunately that return all in many table. I want to return all in one unique table. Maybe using "UNION" but I don't know the way to do.
This is my code:
EXEC sp_msforeachdb 'select ''?''AS "DataBase", s.name, t.name AS "Tables",max(si.rows) as "Rows Line"
from [?].sys.tables t inner join [?].sys.schemas s
on t.schema_id = s.schema_id
inner join [?].sys.partitions si on t.object_id = si.object_id
where t.name like "%ATTACH" group by s.name,t.name'`
You cannot do it in a single query.
You could query the sys.databases table to get a temporary table of all your databases, and then run a dynamic query on each database to store the results of the query in your question all in another temporary table.
Then at the end, you just select all rows from the last temporary table.
I have found finally a solution.i just used a Stored Procedures for having the result i was looking for.So decided to post the answer here maybe that will help someone else.
DECLARE #banco_nome nvarchar(MAX), #tabela_nome nvarchar(MAX)
DECLARE #banco_cursor CURSOR
DECLARE #sqlstatement nvarchar(MAX)
DECLARE #count_sql nvarchar(MAX)
DECLARE #total int
DECLARE #RegistrosFotograficos TABLE
(
DatabaseName nvarchar(max),
TableName nvarchar(max),
Total int
)
SET #banco_cursor = CURSOR FORWARD_ONLY FOR
SELECT name FROM sys.databases
OPEN #banco_cursor
FETCH NEXT FROM #banco_cursor INTO #banco_nome
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sqlstatement = 'DECLARE tabela_cursor CURSOR FORWARD_ONLY FOR SELECT TABLE_NAME FROM ' + #banco_nome + '.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_NAME LIKE ''%ATTACH'' ORDER BY TABLE_NAME'
EXEC sp_executesql #sqlstatement
OPEN tabela_cursor
FETCH NEXT FROM tabela_cursor INTO #tabela_nome
WHILE ##FETCH_STATUS = 0
BEGIN
SET #count_sql = 'USE ' + #banco_nome + '; SELECT #total=COUNT(1) FROM ' + #tabela_nome;
EXECUTE sp_executesql #count_sql, N'#total int OUTPUT', #total=#total OUTPUT
INSERT INTO #RegistrosFotograficos (DatabaseName, TableName, Total) VALUES (#banco_nome, #tabela_nome, #total);
FETCH NEXT FROM tabela_cursor INTO #tabela_nome
END
CLOSE tabela_cursor;
DEALLOCATE tabela_cursor;
FETCH NEXT FROM #banco_cursor INTO #banco_nome
END
CLOSE #banco_cursor;
DEALLOCATE #banco_cursor;
SELECT * FROM #RegistrosFotograficos
This will list all the tables in a given database and the number of rows in each. Notice the results are in a table named #results:
set nocount on
declare #curtable sysname
declare #prevtable sysname
declare #curcount int
declare #tsql varchar(500)
if object_ID('tempdb..#curtables','U') is not null
drop table #curtables
select name into #curtables
from sys.objects
where type='U'
order by 1
if object_id('tempdb..#results','U') is not null
drop table #results
create table #results(name sysname,numrows int)
select top 1 #curtable=name from #curtables order by name
while (1=1)
begin
set #tsql = 'select '''+quotename(#curtable) +''',count(*) numrows from '+quotename(#curtable)
print #tsql
insert into #results
exec (#tsql)
set #prevtable= #curtable
select top 1 #curtable = name
from #curtables
where name > #prevtable
order by name
if #curtable=#prevtable
break
end

compare schema of tables and script of stored-procedures between 2 databases

source : MS-SQL 2005
destination : MS-SQL 2012
somehow I need to change developing database from one to another but unfortunately the "to database" does have had some tables and SPs already and the worse, those objects such as tables might have some columns with different name or types or even descriptions inconsistent between.
what am I supposed to do to achieve sth like, maybe easier or smarter,
append new columns to tables which already existed (and also put col's default value and description from source)
change types of columns consistent to source
prevent overwriting contents of SPs already appeared in destination (but will review manually later)
So far I can figure out some statistics by the follwing scripts
select name from sys.Tables order by name (export to left.txt and right.txt and compare them between)
select * from sys.all_objects where type='p' and is_ms_shipped=0 order by name (also compare them between)
get all column names in one line per table (and compare them between),
e.g.
--sth like SELECT * FROM INFORMATION_SCHEMA.COLUMNS, but select into only ONE line per table
declare #temp_table_list table(
id int identity not null,
name varchar(100) not null
)
insert #temp_table_list(name) select name from sys.tables
declare #id int
declare #name varchar(100)
declare #result as nvarchar(max)
set #result = N''
while 1 = 1
begin
select #id = min(id)
FROM #temp_table_list
where id > isnull(#id,0)
if #id is null break
select #name = name
FROM #temp_table_list
where id = #id
declare #tbName as nvarchar(max)
declare #sql as nvarchar(max)
declare #col as nvarchar(max)
Set #tbName = #name
DECLARE T_cursor CURSOR FOR
select c.name from sys.columns c
inner join sys.tables t on c.object_id = t.object_id
inner join sys.types tp on tp.user_type_id = c.system_type_id
where t.name =#tbName
OPEN T_cursor
FETCH NEXT FROM T_cursor into #col
set #sql = N'select '
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql = #sql+#col+','
FETCH NEXT FROM T_cursor into #col
END
set #sql =substring( #sql,0,len(#sql)) +' from '+ #tbName
CLOSE T_cursor
DEALLOCATE T_cursor
set #result = #result + #sql + '/r/n'
end
select #result
This isn't free software, but it does have a trial period:
http://www.red-gate.com/products/sql-development/sql-compare/
As it sounds like your requirement is a one off sync, then that should do what you want.

while loop inside a trigger to loop through all the columns of table in sql

I have a trigger like below on user table to insert into the audit table with which column was updated and previous value:
ALTER TRIGGER [dbo].[trgAfterUpdate] ON [dbo].[tbl_User]
AFTER UPDATE
AS
declare #fieldname varchar(128) ;
declare #OldValue varchar(255);
declare #CreateUser varchar(100) ;
declare #User_Key int;
select #CreateUser =i.user_name from deleted i;
SELECT #User_Key = i.user_key from inserted i;
if update(user_name)
begin
select #OldValue=j.user_name from deleted j;
set #fieldname = 'user_name';
insert into tbl_Audit(user_key, field_name, previuos_Value, user_name)
values(#User_Key ,#fieldname,#OldValue, #CreateUser);
end
But my questions is I have like 100 fields on my table. I can't write 100 if conditions. And i need a suggestion how to use while loop in it, and how is it going to effect the performance.
Thanks
Try this one -
ALTER TRIGGER [dbo].[trgAfterUpdate]
ON [dbo].[tbl_User]
AFTER UPDATE
AS BEGIN
SET NOCOUNT ON
SET XACT_ABORT ON
DECLARE #DocumentUID UNIQUEIDENTIFIER
DECLARE cur CURSOR FORWARD_ONLY READ_ONLY LOCAL FOR
SELECT DocumentUID, ...
FROM INSERTED
OPEN cur
FETCH NEXT FROM cur INTO #DocumentUID, ...
WHILE ##FETCH_STATUS = 0 BEGIN
DECLARE
#BeforeChange XML
, #AfterChange XML
SELECT #BeforeChange = (
SELECT *
FROM DELETED
WHERE [DocumentUID] = #DocumentUID
FOR XML RAW, ROOT
)
, #AfterChange = (
SELECT *
FROM INSERTED
WHERE [DocumentUID] = #DocumentUID
FOR XML RAW, ROOT
)
INSERT INTO dbo.LogUser (DocumentUID, BeforeChange, AfterChange)
SELECT #DocumentUID, #BeforeChange, #AfterChange
-- your business logic
FETCH NEXT FROM cur INTO #DocumentUID, ...
END
CLOSE cur
DEALLOCATE cur
END
Try using query similar to this one – it will generate If statements for all columns of a given table.
Note: This is not fully tested and probably needs more adjustments but you see the idea behind it.
select 'if update(' + C.name + ')
begin
select #OldValue=j.' + C.name + ' from deleted j;
set #fieldname = ''' + C.name + ''';
insert into tbl_Audit(user_key, field_name, previuos_Value, user_name)
values(#User_Key ,#fieldname,#OldValue, #CreateUser);
end'
from sys.all_columns C
inner join sys.tables T on C.object_id = T.object_id
where T.name = 'table_name' and T.schema_id = SCHEMA_ID('schema_name')
If wouldn’t go with while loop because it can probably cause perf issues…

suggest a query to in sql to find the unused tables

SNAHi
anyone please suggest a query in sql to find the unused tables.
I have a legacy application migrated to .net from coldfusion.But lots of tables are unused now
What is the best way to find all the unused objects from database. (sql 2005)
thanks
SNA
In SQL Server, the acutal table data IS the clustered index. Using this query on the Dynamic Management Views (DMV) in SQL Server 2005 and up, you can find unused indices - if you find any clustered index (index_id=1) being unused over an extended period of time, the table is not being used anymore:
DECLARE #dbid INT
SELECT #dbid = DB_ID(DB_NAME())
SELECT
OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
INDEXNAME = I.NAME,
I.INDEX_ID
FROM
SYS.INDEXES I
JOIN
SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
WHERE
OBJECTPROPERTY(O.OBJECT_ID, 'IsUserTable') = 1
AND I.INDEX_ID NOT IN
(SELECT S.INDEX_ID
FROM SYS.DM_DB_INDEX_USAGE_STATS S
WHERE S.OBJECT_ID = I.OBJECT_ID
AND I.INDEX_ID = S.INDEX_ID
AND DATABASE_ID = #dbid)
ORDER BY
OBJECTNAME,
I.INDEX_ID,
INDEXNAME ASC
Another option would be to temporarily rename a table if you suspect it's not being used, and then see if your app(s) still work as expected. If they do for e.g. 30 days or so, then you're pretty sure you don't need that table anymore.
Marc
-- Query to find the tables not used by any stored procedure, function nor view
-- Using SQL 2005 system tables, all programatical objects for dependencies, and one&only query:
select tables.name, progr.name
from sys.objects tables (nolock)
left join sys.syscomments comm (nolock) on comm.text like '%' + tables.name +'%'
left join sys.objects progr (nolock) on progr.object_id = comm.id and progr.type in ('P', 'FN', 'TR', 'V' )
where tables.type = 'U'
and comm.id is null
Here is a query i have written to find the tables not used by any store procedures..
......................................................................................
Declare #tablename nvarchar(40)
Declare tablecursor cursor for
Select name from sysobjects where xtype = 'U'
DECLARE #sqlCommand nvarchar(1000)
declare #rowCount int
DECLARE #searchstring varchar(50)
DECLARE #ParmDefinition nvarchar(500);
create table #temp
(
UnusedTables nvarchar(40)
)
open tablecursor
fetch next from tablecursor into #tablename
while ##fetch_status = 0
begin
set #searchstring='p'
SET #sqlCommand = N'SELECT #rows = count(o.name) from sysobjects o ,
syscomments c where o.type='+char(39)+#searchstring + char(39)+' and
o.id=c.id and c.text like '+ char(39)+'%' + #tablename +'%'+char(39);
SET #ParmDefinition = N'#rows int OUTPUT';
EXECUTE sp_executesql #sqlCommand, #ParmDefinition,#rows=#rowCount OUTPUT;
if #rowCount = 0
begin
insert into #temp values (#tablename)
end
fetch next from tablecursor into #tablename
end
close tablecursor
deallocate tablecursor
select UnusedTables from #temp
drop table #temp
thanks
SA
Try something like below
DECLARE #TableNameTemp TABLE
(
id INT IDENTITY (1, 1),
tablename VARCHAR(1000)
)
INSERT INTO #TableNameTemp
SELECT table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
ORDER BY table_name
DECLARE #CursorTestID INT = 1;
DECLARE #TotalCount INT = (SELECT Count(1)
FROM #TableNameTemp)
DECLARE #FinalResult TABLE
(
unsedtables VARCHAR(max)
)
DECLARE #TemExecInsert TABLE
(
testvalue VARCHAR(max),
type VARCHAR(max)
)
DECLARE #TableaName VARCHAR(max) = ''
WHILE #CursorTestID <= #TotalCount
BEGIN
DELETE FROM #TemExecInsert
SET #TableaName = (SELECT tablename
FROM #TableNameTemp
WHERE id = #CursorTestID)
INSERT INTO #TemExecInsert
EXEC Sp_depends
#objname = #TableaName
SET #CursorTestID = #CursorTestID + 1
IF ( (SELECT Count(1)
FROM #TemExecInsert) = 0 )
BEGIN
INSERT INTO #FinalResult
VALUES (#TableaName)
END
END
SELECT *
FROM #FinalResult
PS: Sorry, I am not certain how to bring the answer in shape. Hope this helps

Resources