带有日期时间参数的 EXEC sp_executesql?

EXEC sp_executesql with a datetime parameter?

我在 SQL Server 2016 中使用 EXEC sp_executesql 进行动态查询,并且在用户想要在一年内通过时绊倒了。我有一个名为 tkemdate 的日期时间字段,它作为日期时间字段存储在 SQL.

虽然SQL存储为日期时间,但用户只传入一个年份参数(2020、2019、2018等)。如何让查询只接受年份?

这是我的存储过程,带有日期时间参数。

(
@tkemdate datetime
)

AS
BEGIN

Declare  @SQL NVARCHAR(MAX)

Set @SQL = 'SELECT        timekeep.tkinit, timekeep.tkfirst, timekeep.tklast, 
                          year(timekeep.tkemdate) as tkemdate

FROM   abc123.timekeep'        
                     
WHERE  1 = 1

IF @tkemdate IS NOT NULL
Select @SQL = @SQL + 'AND ([tkemdate] = @tkemdate)'
EXEC sp_executesql @SQL, N'@tkemdate datetime',  @tkemdate

END

你可以这样使用:

IF @year IS NOT NULL
    Select @SQL = @SQL + ' AND (YEAR([tkemdate]) = @year)'

EXEC sp_executesql @SQL, N'@year int',  @year=@year;

不清楚@year从何而来,但你说用户是在当年路过

如果您只想使用 @tkemdate 的年份,那么:

IF @tkemdate IS NOT NULL
    Select @SQL = @SQL + ' AND (YEAR([tkemdate]) = YEAR(@tkemdate))';

EXEC sp_executesql @SQL, N'@@tkemdate datetime',  @@tkemdate=@@tkemdate;

它也可能是这样的——你的程序有一个代表年份的整数参数。

我们还可以为其添加一些验证,例如,如果@year 小于 1000 或大于 2500。

CREATE PROCEDURE abc123.get_timekeep_records (
 @year int
)
AS
BEGIN
 SET NOCOUNT ON; -- I usually add this because of a PHP driver
 DECLARE @SQL NVARCHAR(MAX)

 SET @SQL = 'SELECT timekeep.tkinit, timekeep.tkfirst, timekeep.tklast,
                    YEAR(timekeep.tkemdate) as [tkemdate]
             FROM abc123.timekeep
             WHERE 1 = 1 '

 -- Validation
 IF @year < 1000 OR @year > 2500
   RAISERROR('Invalid year: %i', 16, 1, @year)

 IF @year IS NOT NULL
   SELECT @SQL = @SQL + 'AND (YEAR(timekeep.tkemdate) = @year)'

 EXEC sp_executesql @SQL, N'@year int', @year;

END