我有一个过程,用户可以为多列动态更改该过程,并且在运行时用SQL编写它。在SQL和Visual Studio中的Server Explorer中,一切正常,但是当我想在C#中使用它并调用它时,它总是始终返回0。 有人可以帮我吗?!
CREATE PROCEDURE [dbo].[PDaynamicActualBy2Column]
@Colname1 nvarchar(100),
@VarCol1 nvarchar(100),
@Colname2 nvarchar(100),
@VarCol2 nvarchar(100),
@VarWeekNum nvarchar(100)
as
DECLARE @temp nvarchar(1500)
set @temp='SELECT SUM([dbo].[WeekActualTemp].[ACTUAL]) from [dbo].[MAINTB] join [dbo].[WeekActualTemp] on [dbo].[MAINTB].[UQ]=[dbo].[WeekActualTemp].[UQ]
where [dbo].[WeekActualTemp].[WeekNO]='+@VarWeekNum+' And [dbo].[MAINTB].'+@Colname1+' = '''+@VarCol1+''' And [dbo].[MAINTB].'+@Colname2+' = '''+@VarCol2+''''
exec (@temp)
答案 0 :(得分:2)
这不能解决C#中的问题,但是可以解决代码中出现的巨大注入问题。如前所述,不要注入您的参数,并且正确引用您的动态对象名称。结果如下:
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
因为只返回一个标量值,所以也可以使用OUTPUT
参数,而不是SELECT
来显示该值。如下所示:
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
注意,如注释中所述,我摆脱了为您的列命名的3+部分,而是为表命名。然后,我使用这些别名来引用正确的对象。如果您需要调试它,我还会在代码中添加“您最好的朋友”。
注意:如另一个答案所述,零很可能是因为SP返回0
表示成功。这是存储过程的documented和有意功能:
除非另有说明,否则所有系统存储过程均返回0值。这表示成功,而非零值表示失败。
由于上述SP可能成功,因此RETURN
的值为0
;表示成功。您不应该查看RETURN
的值,而应该查看数据集,或者在后一个示例中查看OUTPUT
参数的值。我敢肯定,SO中是否存在有关如何在linq中使用OUTPUT
参数的问题。
答案 1 :(得分:0)
存储过程的返回值为零意味着它已成功执行。
您应该通过表的“ RETURN”语句或“ SELECT”语句返回值。
答案 2 :(得分:-1)
在LINQ中,您不能调用具有动态元输出的SP,而必须使用“选择”输出编写SP,并制作模型,然后转到SP并再次对其进行编辑。
Alter PROCEDURE [dbo].[PDaynamicActualBy2Column]
@Colname1 nvarchar(100),
@VarCol1 nvarchar(100),
@Colname2 nvarchar(100),
@VarCol2 nvarchar(100),
@VarWeekNum nvarchar(100)
as
DECLARE @temp nvarchar(1500)
set @temp='SELECT SUM([dbo].[WeekActualTemp].[ACTUAL]) from [dbo].[MAINTB] join [dbo].[WeekActualTemp] on [dbo].[MAINTB].[UQ]=[dbo].[WeekActualTemp].[UQ]
where [dbo].[WeekActualTemp].[WeekNO]='+@VarWeekNum+' And [dbo].[MAINTB].'+@Colname1+' = '''+@VarCol1+''' And [dbo].[MAINTB].'+@Colname2+' = '''+@VarCol2+''''
// exec (@temp)
SELECT top 0
SUM([dbo].[WeekActualTemp].[ACTUAL]) as sum
from [dbo].[MAINTB] join [dbo].[WeekActualTemp] on [dbo].[MAINTB].[UQ]=[dbo].[WeekActualTemp].[UQ]
然后在LINQ中导入SP,然后注释“选择”并取消注释“ exec”。