如何在SQL Server中将日期时间字符串转换为日期时间

问题描述 投票:0回答:1

从我的C#应用​​程序中,我使用TVP调用存储过程。几列是datetime。对SP的调用可能类似于:

declare @p1 dbo.MyTvp
insert into @p1 values('2020-03-19 00:00:01','2020-03-30 23:59:59')
exec MySp @criteria=@p1

以上代码是用C#自动生成的。在SP中,处理日期的部分是:

declare @datefrom datetime;
---
SET @sql = CONCAT(@sql, ' AND date_from >= ''', @datefrom, '''');

SQL Server语言环境为德语。

由于从varchar到datetime的转换,以上引发错误。但是,如果我传递的日期时间值的格式如下:

declare @p1 dbo.MyTvp
insert into @p1 values('19.03.2020 00:00:01','30.03.2020 23:59:59')
exec MySp @criteria=@p1

SP正常工作。

用作源的类是:

public class MyCriteria
{
    public DateTime DateFrom { get; set; }
}

表类型为:

CREATE TYPE [dbo].[MyTvp] AS TABLE(
    [DateFrom] [datetime] NULL
)

我使用扩展方法将MyCriteria的实例转换为DataTable,然后使用Dapper执行SP:

var criteria = new List<MyCriteria>() { myCriteria }.ToDataTable();
return await conn.QueryAsync<SomeResult>(new CommandDefinition("MySp", new { criteria }, commandType: CommandType.StoredProcedure, cancellationToken: ct));

我不知道是在哪个阶段发生从datetimevarcharDateTimestring的转换。

所以我到底需要转换日期才能使SP正常工作?我应该在数据库级别还是在C#应用程序中进行转换?

c# sql sql-server dapper
1个回答
1
投票

从评论中的讨论开始,听起来像是:输入TVP中的数据(datetime),而b:在这种情况下,只有一行;太好了-这意味着我们可以大大简化;我们在这里要做的就是将TVP中的值引入本地,并与之一起使用。现在,基于示例代码中的@datefrom,听起来您已经完成了第一步,因此我们所需要做的就是修复动态SQL的构成和执行方式。在问题中,我们有:

SET @sql = CONCAT(@sql, ' AND date_from >= ''', @datefrom, '''');

大概后面跟着:

EXEC (@sql);

相反,我们可以参数化动态SQL:

SET @sql = @sql + ' AND date_from >= @datefrom ';

并传递参数进入我们的动态SQL:

exec sp_executesql @sql, N'@datefrom datetime', @datefrom

sp_executesql的第二个参数给出了所有actual参数的定义字符串,这些参数顺序在它之后。


现在,代码对于SQL注入是完全安全的,并且您无需担心任何字符串/日期转换。

请注意,在“内部”和“外部”部分中的参数名称不必相同,但是它们通常是相同的(为方便起见和可维护性)。

© www.soinside.com 2019 - 2024. All rights reserved.