我有这个存储过程:
CREATE PROCEDURE [dbo].[IsDateInBetween]
@someDateTime datetime
AS
BEGIN
DECLARE @Exists INT
IF EXISTS(SELECT Id FROM [dbo].[SomeTable]
WHERE StartDate < @someDateTime AND EndDate > @someDateTime)
BEGIN
SET @Exists = 1
END
ELSE
BEGIN
SET @Exists = 0
END
RETURN @Exists
END
当我叫它:
DECLARE @return_value int
EXEC @return_value = [dbo].[IsDateInBetween]
@someDateTime = N'2020-07-14'
SELECT 'Return Value' = @return_value
GO
我收到1,这是预期的。
但之后我尝试用C#调用它:
var result = DbConnection.ExecuteScalar<int>("dbo.IsDateInBetween", new { new DateTime(2020, 7, 14) }, commandType: CommandType.StoredProcedure);
我得到0。
我尝试将传递的对象更改为DynamicParameters,如下所示:
var parameters = new DynamicParameters();
parameters.Add("someDateTime", faultDateTime, DbType.DateTime);
但这于事无补。
我尝试了DBType.DateTime和DBType.DateTime2,以及参数名以@开头和不以@开头。 存储过程中的两列都属于DateTime类型。
我做错了什么?
您只需给参数取一个正确的名称:
var result = DbConnection.ExecuteScalar<int>(
"IsDateInBetween",
new { someDateTime = new DateTime(2020, 7, 14) },
commandType: CommandType.StoredProcedure);
另外,除非执行的模式不同于登录名的默认模式,否则无需提及,过程名就足够了。
还有一件事--问题很可能出在存储过程本身。 您不应该使用return
-您应该使用输出参数或简单SELECT。
请改为尝试此过程:
CREATE OR ALTER PROCEDURE [dbo].[IsDateInBetween]
@someDateTime datetime
AS
BEGIN
SELECT CASE WHEN EXISTS(
SELECT Id
FROM [dbo].[SomeTable]
WHERE StartDate < @someDateTime
AND EndDate > @someDateTime
)
THEN 1
ELSE 0
END
END
您可以使用query
或QueryAsync
或任何其他查询方法,如QueryFirst
或QueryFirstorDefault
。 executescalar
是ADO.NET方法,也存在于dapper中,因此可能不清楚您使用的是哪个方法。
衣冠楚楚的尝试
DbConnection.QueryFirst<int>("EXEC dbo.IsDateInBetween @someDate", new { someDate = new DateTime(2020, 7, 14) });
为什么使用query()
而不是execute()
? 您需要一个返回值。
此外,还应该在查询和匿名类型中指定参数的名称。