在过程中键入输入参数的datetime

Sal*_*ian 14 datetime stored-procedures sql-server-2008 input-parameters

我已经创建了一个具有此结构的过程,但它不适用于datetime输入参数

我执行了这个查询但是

declare @a datetime
declare @b datetime 

set @a='2012/04/06 12:23:45'
set @b='2012/08/06 21:10:12'

exec LogProcedure 'AccountLog', N'test', @a, @b
Run Code Online (Sandbox Code Playgroud)

但是SQL Server让我犯了这个错误

从字符串转换日期和/或时间时转换失败.

但是,当我使用此查询进行测试时,它可以工

  exec LogProcedure 'AccountLog',N'test'
Run Code Online (Sandbox Code Playgroud)

存储过程代码:

alter PROCEDURE LogProcedure
    @TableName VARCHAR(60),
    @SearchString NVARCHAR(50),
    @DateFirst DateTime = '',
    @DateLast DateTime = ''
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @FinalSQL      NVARCHAR(MAX)

    SET @FINALSQL = 'SELECT * FROM [' + @TableName + '] where 1=2  '

    IF @DateFirst <> '' and @DateLast <> ''
       set @FinalSQL  = @FinalSQL + '  or convert (Date,DateLog) >=     '''+@DateFirst + ' and convert (Date,DateLog) <='''+@DateLast  

    SELECT 
       @FinalSQL  = @FinalSQL + ' or  [' + SYSCOLUMNS.NAME + '] LIKE N''%' + @SearchString + '%'' ' 
    FROM SYSCOLUMNS 
    WHERE OBJECT_NAME(id) = @TableName
    AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR','INT','DECIMAL')
    ORDER BY COLID

    EXEC(@FinalSQL)
END 
Run Code Online (Sandbox Code Playgroud)

这个查询也是如此

SELECT * 
FROM AccountLog 
where 1=2  or convert (Date, DateLog) >= '2012/04/06' 
and convert (Date, DateLog) <='2012/08/06'
Run Code Online (Sandbox Code Playgroud)

mar*_*c_s 28

您应该使用ISO-8601格式进行日期的字符串表示 - 其他任何内容都取决于SQL Server语言和dateformat设置.

DATETIME仅使用日期时的ISO-8601格式为:( YYYYMMDD无破折号或antyhing!)

对于DATETIME具有时间部分的a,它是YYYY-MM-DDTHH:MM:SS(用短划线,并且T在中间用于分隔日期和时间部分).

如果要将字符串转换DATE为SQL Server 2008或更高版本,可以使用YYYY-MM-DD(使用短划线)来获得相同的结果.并且不要问我为什么这是如此不协调和混乱 - 它只是,你现在必须与之合作.

所以在你的情况下,你应该尝试:

declare @a datetime
declare @b datetime 

set @a = '2012-04-06T12:23:45'   -- 6th of April, 2012
set @b = '2012-08-06T21:10:12'   -- 6th of August, 2012

exec LogProcedure 'AccountLog', N'test', @a, @b
Run Code Online (Sandbox Code Playgroud)

此外 - 您的存储过程有问题,因为您连接在一起datetime并将字符串串入一个字符串,但您不是首先将datetime字符串转换为字符串,而且,您在两个日期之后忘记了语句中的关闭引号.

所以在这里改变这一行:

IF @DateFirst <> '' and @DateLast <> ''
   SET @FinalSQL  = @FinalSQL + '  OR CONVERT(Date, DateLog) >= ''' + 
                    CONVERT(VARCHAR(50), @DateFirst, 126) +   -- convert @DateFirst to string for concatenation!
                    ''' AND CONVERT(Date, DateLog) <=''' +  -- you need closing quotes after @DateFirst!
                    CONVERT(VARCHAR(50), @DateLast, 126) + ''''      -- convert @DateLast to string and also: closing tags after that missing!
Run Code Online (Sandbox Code Playgroud)

使用这些设置,一旦您修复了包含问题的存储过程,它就会起作用.