步骤字符串语句始终返回0

时间:2019-12-08 10:13:08

标签: c# sql sql-server tsql stored-procedures

我有一个过程,用户可以为多列动态更改该过程,并且在运行时用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)

3 个答案:

答案 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”。

相关问题