This does not address the problem in the C#, however, it does address the huge injection issue you have in your code. Like mentioned, don't inject your parameters and properly quote your dynamic object names. This results in something like the below:
CREATE PROC dbo.PDaynamicActualBy2Column @Colname1 sysname, @VarCol1 nvarchar(100), @Colname2 sysname, @VarCol2 nvarchar(100), @VarWeekNum int AS --Assumed @VarWeekNum is an int, as why else is it called "num"?
BEGIN
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET @SQL = N'SELECT SUM(WAT.Actual) AS ActualSum' + @CRLF +
N'FROM dbo.MAINTB MTB' + @CRLF +
N' JOIN dbo.WeekActualTemp WAT ON MTB.UQ = WAT.UQ' + @CRLF +
N'WHERE WAT.WeekNO = @VarWeekNum' + @CRLF +
N' AND MTD.' + QUOTENAME(@Colname1) + N' = @VarCol1' + @CRLF +
N' AND MTD.' + QUOTENAME(@Colname2) + N' = @VarCol2;';
--PRINT @SQL; Your Best Friend
EXEC sp_executesql @SQL, N'@VarCol1 nvarchar(100),@VarCol2 nvarchar(100),@VarWeekNum int', @VarCol1, @VarCol2, @VarWeekNum;
END;
GO
Because you're only returning a single scalar value, you could also use an OUTPUT
parameter as well, instead of a SELECT
to the display the value. This would look like the below:
CREATE PROC dbo.PDaynamicActualBy2Column @Colname1 sysname, @VarCol1 nvarchar(100), @Colname2 sysname, @VarCol2 nvarchar(100), @VarWeekNum int, @ActualSum int OUTPUT AS --Assumes Actual is an int in your table. Use an appropriate data type
BEGIN
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET @SQL = N'SELECT @ActualSum = SUM(WAT.Actual)' + @CRLF +
N'FROM dbo.MAINTB MTB' + @CRLF +
N' JOIN dbo.WeekActualTemp WAT ON MTB.UQ = WAT.UQ' + @CRLF +
N'WHERE WAT.WeekNO = @VarWeekNum' + @CRLF +
N' AND MTD.' + QUOTENAME(@Colname1) + N' = @VarCol1' + @CRLF +
N' AND MTD.' + QUOTENAME(@Colname2) + N' = @VarCol2;';
--PRINT @SQL; Your Best Friend
EXEC sp_executesql @SQL, N'@VarCol1 nvarchar(100),@VarCol2 nvarchar(100),@VarWeekNum int, @ActualSum int OUTPUT', @VarCol1, @VarCol2, @VarWeekNum, @ActualSum OUTPUT; --Again, assumes Actual is an int.
END;
GO
Notice, as mentioned in the comments, I get rid of the 3+ part naming for your columns, and alias your tables instead. I then use those aliases to reference to correct object. I've also put "Your best Friend" in the code, should you need to debug it.
Note: As mentioned in a different answer, zero is likely because the SP is returning 0
to mean success. This is a documented and intentional feature of Stored Procedures:
Unless documented otherwise, all system stored procedures return a value of 0. This indicates success and a nonzero value indicates failure.
As the SP above is likely successful, the RETURN
value is 0
; to denote success. You shouldn't be looking at the RETURN
value, but the dataset, or in the latter example the OUTPUT
parameter's value. I am sure there are questions on SO for how to use an OUTPUT
parameter in linq.