将nvarchar值'06 / 30/2012'转换为数据类型int时转换失败

时间:2013-03-28 15:58:16

标签: sql sql-server datetime sql-server-2008-r2 dynamic-sql

我在尝试设置两个变量时遇到问题,包括From Date和To Date。一旦我解决了一个问题,另一个将很容易弄明白。我收到了错误:

  

将nvarchar值'06 / 30/2012'转换为数据类型int时,转换失败。

值得注意的是,我正在使用视图将各种表格组合在一起,然后通过sp_executesql执行我想要的表格。当我打印我的查询时,我可以看到它将@fromdate识别为0,也许这就是问题..

 declare @fromdate nvarchar
 declare @todate nvarchar
 select @fromdate = '03/01/1999'
 select @todate = ''

 IF @fromdate <> ''
BEGIN
    SELECT @sql = @sql + ' and convert (nvarchar,document_Date,101) > '+@fromdate+''
END

 if @todate <> ''
BEGIN
    SELECT @sql = @sql + ' and convert(nvarchar,document_date,101) >  '+@todate+''
END

document_date是日期时间。有任何想法吗?如果是这样,你能解释为什么会这样,所以我可以学习并避免将来发生这种情况吗?我在下面包含了打印SQL。

 SELECT  [system_status]      
  ,[document_status_code]      
  ,[rpt_category]      
  ,[category]      
  ,[user_status_cd]      
  ,[user_status]      
  ,[assigned_to_id]      
  ,[assigned]      
  ,[assigned_to_date]      
  ,[owner_id]      
  ,[owner]      
  ,[rpt_acct_code]      
  ,[acct_name]      
  ,[rpt_title]      
  ,[job_name]      
  ,[logged_time]      
  ,[rpt_format_type]      
  ,[rpt_run_id]      
  ,[rpt_doc_id]      
  ,[rpt_id]      
  ,[rpt_filename]      
  ,[rpt_file_path]      
  ,[rpt_run_name]      
  ,[sla_start_date]      
  ,[sla_due_date]      
  ,[sla_completed_date]      
  ,[sla_status]      
  ,[SLA_Days]
  ,[Document_Date] 
  FROM VW_Document_Main
  WHERE 1=1 and convert (nvarchar,document_Date,101) > 0 
  order by document_status_code  ,owner_id 

4 个答案:

答案 0 :(得分:1)

部分问题在于您的@fromdate

声明没有长度

它只返回第一个字符,因为你没有长度。宣言应该说:

declare @fromdate nvarchar(10)
declare @todate nvarchar(10)

由于您没有长度,因此返回0这是第一个字符。

其次,您还要比较日期的字符串值,您应该比较日期值。

declare @fromdate datetime
declare @todate datetime

然后你的代码可能是:

SELECT @sql = @sql + ' and document_Date > '''+convert(varchar(10), @fromdate, 101)+''''

答案 1 :(得分:0)

文字

'03/01/1999'

是一个字符串文字。您正在将document_Date转换为varchar,然后进行不等式比较

and convert (nvarchar,document_Date,101) > '+@fromdate

由于日期格式不是YYYYMMDD,因此比较不太可能产生您期望的比较。

如果@fromdate例如'04 / 01/1900',则大于 '03 / 01/1999',因为'04'大于'03'。

相反,将@fromdate转换为与document_Date相同的类型,例如

AND document_Date > convert(datetime, @fromdate)

答案 2 :(得分:0)

如果列document_date已经是日期时间,为什么不声明声明@fromdate 和@todate作为日期时间,那么你的代码将更简单,你不必进行任何转换。在我看来,转换对于你想要做的事情是不必要的。

答案 3 :(得分:0)

问题#1

declare @fromdate nvarchar
select @fromdate = '03/01/1999'

为什么要将这些字符串定义为 Unicode 字符串,不要介意strings without a length?为什么你使用模糊的,不可靠的文字格式?是3月1日还是1月3日?您确定您的SQL Server实例与您同意吗?

问题#2

SELECT @sql = @sql + ' and convert (nvarchar,document_Date,101) > '+@fromdate+''

为什么要将列转换为 Unicode 字符串,不要介意string without a length?为什么要将它作为字符串进行比较?您知道'05/05/2010'大于'02/21/2015',当比较为字符串时,对吗?

解决方案

停止使用含糊不清的格式。不要以为日期是字符串,应该这样比较。

怎么样:

DECLARE @fromdate DATETIME = '19990301'; -- guessing you meant March 1st. 
      -- See why ambiguous formats are bad and you should never use them?

...
SELECT @sql += ' AND document_Date > @fromdate;';

EXEC sp_executesql @sql, N'@fromdate DATETIME', @fromdate;

现在您根本不需要进行任何转换。