March 28, 2023 at 1:31 pm
I want to use a table variable in a merge statement using Dynamic SQL
I know that you cant reference table variables in Dynamic SQL as they are out of scope.
So instead ive elected to use a Table type but having problems.
My code as follows:
/****** Object: UserDefinedTableType [dbo].[ChannelReadingType] Script Date: 28/03/2023 14:18:44 ******/
CREATE TYPE [dbo].[ChannelReadingType] AS TABLE(
[ReadingDateTime] [datetime2](7) NULL,
[RawReading] [int] NULL,
[SIReading] [real] NULL
)
GO
CREATE TABLE [dbo].[t](
[ID] [int] IDENTITY(1,1) NOT NULL,
[SerialNumber] [nvarchar](60) NULL,
[ChannelID] [int] NULL,
[Si] [decimal](10, 2) NULL,
[Raw] [decimal](10, 2) NULL,
[Conversion] [int] NULL,
[TimeStamp] [datetime] NULL
) ON [PRIMARY]
GO
DECLARE@t [dbo].[ChannelReadingType];
DECLARE@ChannelReadingTableName NVARCHAR(500) = '[ChannelReading_939029_11_F0EA4CCA-3522-4175-AA53-83563F91235F]'
DECLARE@ChannelID INT = 11
DECLARE@SQL NVARCHAR(4000)
-- insert test data into [dbo].[t]
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24073, N'939029', 14, CAST(53.60 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T13:11:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24074, N'939029', 14, CAST(53.01 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T13:21:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24075, N'939029', 14, CAST(52.42 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T13:31:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24076, N'939029', 14, CAST(53.79 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T13:41:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24077, N'939029', 14, CAST(50.74 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T13:51:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24078, N'939029', 14, CAST(54.00 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:01:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24079, N'939029', 14, CAST(53.23 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:11:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24080, N'939029', 14, CAST(52.74 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:21:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24081, N'939029', 14, CAST(53.99 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:31:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24082, N'939029', 14, CAST(50.80 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:41:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24083, N'939029', 14, CAST(54.02 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T14:51:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24084, N'939029', 14, CAST(52.42 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T15:01:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24085, N'939029', 14, CAST(53.68 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T15:11:31.000' AS DateTime))
GO
INSERT [dbo].[t] ([ID], [SerialNumber], [ChannelID], [Si], [Raw], [Conversion], [TimeStamp]) VALUES (24086, N'939029', 14, CAST(53.74 AS Decimal(10, 2)), CAST(0.00 AS Decimal(10, 2)), 0, CAST(N'2022-09-13T15:21:31.000' AS DateTime))
GO
SET @sql = 'MERGE ' + @ChannelReadingTableName + ' T '+ CHAR(13) + CHAR(10) +
' USING
(
SELECT
Sias SIReading,
[Raw]as RawReading,
[TimeStamp]as ReadingDateTime
FROM
@tt
WHERE
ChannelID = ' + '''' + CAST(@ChannelID as nvarchar(10)) + '''' + CHAR(13) + CHAR(10) +
--) AS ChannelReading ' + CHAR(13) + CHAR(10) +
' ) S on T.ReadingDateTime = S.ReadingDateTime ' + CHAR(13) + CHAR(10) +
' WHEN NOT MATCHED BY TARGET '+ CHAR(13) + CHAR(10) +
' THEN '+ CHAR(13) + CHAR(10) +
' INSERT (ReadingDateTime,SIReading, RawReading)'+ CHAR(13) + CHAR(10) +
' VALUES (S.ReadingDateTime,S.SIReading, S.RawReading); '+ CHAR(13) + CHAR(10) +
' ' + CHAR(13) +
' SET @Count= @@ROWCOUNT '
DECLARE @ParmDefinition NVARCHAR(500);
SET @ParmDefinition = N'@Count int OUTPUT';
PRINT @SQL
-- EXECUTE sp_executesql @SQL, N' @tt myTable READONLY', @t;
EXECUTE sp_executesql @SQL,@ParmDefinition, N' @tt [dbo].[ChannelReadingType] READONLY', @t,@Count = @rowcount OUTPUT;
When i run this i get the following error
Msg 1087, Level 15, State 2, Line 9
Must declare the table variable "@tt"
But i have declared the table variable here
EXECUTE sp_executesql @sql,@ParmDefinition, N' @tt dbo.ChannelReadingType READONLY', @t,@Count = @rowcount OUTPUT;
what am I doing wrong?
March 28, 2023 at 1:44 pm
You can't parameterize a from clause. You could parameterize the WHERE clauses.
You could concatenate the table type into dynamic sql as described here: https://odetocode.com/articles/365.aspx
March 28, 2023 at 1:51 pm
You can't parameterize a from clause. You could parameterize the WHERE clauses.
You could concatenate the table type into dynamic sql as described her: https://odetocode.com/articles/365.aspx
Sorry I dont understand , what do you mean by concatenate the table type into dynamic sql?
March 28, 2023 at 1:57 pm
You can reference a temp table in dynamic SQL. Could you create a temp table and load it instead?
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
March 28, 2023 at 2:24 pm
Can be done your logic is just a little off.
The "ParamDefinition" must be a continuous string of all params for the dynamic SQL
DECLARE @t [dbo].[ChannelReadingType];
DECLARE @ChannelReadingTableName NVARCHAR(500) = '[ChannelReading_939029_11_F0EA4CCA-3522-4175-AA53-83563F91235F]'
DECLARE @ChannelID INT = 11
DECLARE @SQL NVARCHAR(4000)
DECLARE @CountOUT INT
SET @sql = 'MERGE ' + @ChannelReadingTableName + ' T '+ CHAR(13) + CHAR(10) +
' USING
(
SELECT
Sias SIReading,
[Raw]as RawReading,
[TimeStamp]as ReadingDateTime
FROM
@tt
WHERE
ChannelID = ' + '''' + CAST(@ChannelID as nvarchar(10)) + '''' + CHAR(13) + CHAR(10) +
--) AS ChannelReading ' + CHAR(13) + CHAR(10) +
' ) S on T.ReadingDateTime = S.ReadingDateTime ' + CHAR(13) + CHAR(10) +
' WHEN NOT MATCHED BY TARGET '+ CHAR(13) + CHAR(10) +
' THEN '+ CHAR(13) + CHAR(10) +
' INSERT (ReadingDateTime,SIReading, RawReading)'+ CHAR(13) + CHAR(10) +
' VALUES (S.ReadingDateTime,S.SIReading, S.RawReading); '+ CHAR(13) + CHAR(10) +
' ' + CHAR(13) +
' SET @Count= @@ROWCOUNT '
DECLARE @ParmDefinition NVARCHAR(500);
SET @ParmDefinition = N'@Count int OUTPUT, @tt [dbo].[ChannelReadingType] READONLY';
PRINT @SQL
-- EXECUTE sp_executesql @SQL, N' @tt myTable READONLY', @t;
EXECUTE sp_executesql @SQL,@ParmDefinition, @tt = @t,@Count = @CountOUT OUTPUT;
Can't test it fully as the "merge" table isn't provided as a create but that should do what you want it to do
March 28, 2023 at 3:15 pm
Can be done your logic is just a little off.
The "ParamDefinition" must be a continuous string of all params for the dynamic SQL
DECLARE @t [dbo].[ChannelReadingType];
DECLARE @ChannelReadingTableName NVARCHAR(500) = '[ChannelReading_939029_11_F0EA4CCA-3522-4175-AA53-83563F91235F]'
DECLARE @ChannelID INT = 11
DECLARE @SQL NVARCHAR(4000)
DECLARE @CountOUT INT
SET @sql = 'MERGE ' + @ChannelReadingTableName + ' T '+ CHAR(13) + CHAR(10) +
' USING
(
SELECT
Sias SIReading,
[Raw]as RawReading,
[TimeStamp]as ReadingDateTime
FROM
@tt
WHERE
ChannelID = ' + '''' + CAST(@ChannelID as nvarchar(10)) + '''' + CHAR(13) + CHAR(10) +
--) AS ChannelReading ' + CHAR(13) + CHAR(10) +
' ) S on T.ReadingDateTime = S.ReadingDateTime ' + CHAR(13) + CHAR(10) +
' WHEN NOT MATCHED BY TARGET '+ CHAR(13) + CHAR(10) +
' THEN '+ CHAR(13) + CHAR(10) +
' INSERT (ReadingDateTime,SIReading, RawReading)'+ CHAR(13) + CHAR(10) +
' VALUES (S.ReadingDateTime,S.SIReading, S.RawReading); '+ CHAR(13) + CHAR(10) +
' ' + CHAR(13) +
' SET @Count= @@ROWCOUNT '
DECLARE @ParmDefinition NVARCHAR(500);
SET @ParmDefinition = N'@Count int OUTPUT, @tt [dbo].[ChannelReadingType] READONLY';
PRINT @SQL
-- EXECUTE sp_executesql @SQL, N' @tt myTable READONLY', @t;
EXECUTE sp_executesql @SQL,@ParmDefinition, @tt = @t,@Count = @CountOUT OUTPUT;Can't test it fully as the "merge" table isn't provided as a create but that should do what you want it to do
Perfect I see what was missing now and added that in
Works very well. thank you very much for your help Ant
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy