Reputation: 1
I have a simple stored procedure where the target table and where clause condition are specified as parameters. The "Arithmetic overflow error converting nvarchar to data type numeric." error is causing me a bit of frustration.
@TableName varchar(50), -- 'A_RECORD_ETH0' test value
@Time_ms decimal(18,4), -- '40388629085.6481' test value
@Records int out, -- should result with '1' if test values are used
This works:
SELECT COUNT(*) as Count FROM A_RECORD_ETH0 WHERE Time_ms = 40388629085.6481
This works:
SET @sql = N'SET @Records = (SELECT COUNT(*) FROM A_RECORD_ETH0 WHERE Time_ms = 40388629085.6481 )'
EXEC sp_executesql @sql, N'@Records int output', @Records output
This works:
SET @sql = N'SET @Records = (SELECT COUNT(*) FROM '+ @TableName + ' WHERE Time_ms = 40388629085.6481 )'
EXEC sp_executesql @sql, N'@Records int output', @Records output
This results in the Arithmetic overflow error:
SET @sql = N'SET @Records = (SELECT COUNT(*) FROM '+ @TableName + ' WHERE Time_ms = ' + @Time_ms + ' )'
EXEC sp_executesql @sql, N'@Records int output', @Records output
This results in the Arithmetic overflow error even when cast is used:
SET @sql = N'SET @Records = (SELECT COUNT(*) FROM '+ @TableName + ' WHERE Time_ms = Cast ( ' + @Time_ms + ' as decimal(18,4)) )'
EXEC sp_executesql @sql, N'@Records int output', @Records output
Upvotes: 0
Views: 6452
Reputation: 1
I got the following to work based on your code:
DECLARE @sqlSelect nvarchar(500);
DECLARE @ParmSelect nvarchar(500);
SET @sqlSelect = N'SET @RecordsOut = (SELECT COUNT(*) FROM ' + @TableName + ' WHERE Time_ms = @Time_msIn)'
SET @ParmSelect = N'@Time_msIn decimal(18,4), @RecordsOut int OUTPUT';
EXEC sp_executesql @sqlSelect, @ParmSelect, @Time_msIn = @Time_ms, @RecordsOut = @Records OUTPUT;
Upvotes: 0
Reputation: 10908
Passing @Time_ms directly avoids the decimal->string->decimal conversion. It's also more efficient; when @Time_ms changes, the server can still reuse the execution plan instead of generating a new one.
SET @sql = N'SET @Records = (SELECT COUNT(*) FROM '+ @TableName + ' WHERE Time_ms = @Time_ms'
EXEC sp_executesql @sql, N'@Time_ms decimal(18,4), @Records int output', @Time_ms=@Time_ms, @Records output
Upvotes: 1