0

我在尝试设置两个变量(从日期和截止日期)时遇到问题。一旦我解决了一个问题,另一个就很容易解决了。我收到错误:

将 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

4 回答 4

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)+''''
于 2013-03-28T16:05:46.587 回答
0

问题 #1

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

为什么将这些定义为Unicode字符串,更不用说没有长度的字符串了?你为什么对文字使用模棱两可、不可靠的格式?是3月1日还是1月3日?您确定您的 SQL Server 实例与您一致吗?

问题 #2

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

为什么要将列转换为Unicode字符串,更不用说没有长度的字符串?为什么将其作为字符串进行比较?你知道它'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;

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

于 2013-03-28T16:07:49.350 回答
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)
于 2013-03-28T16:02:30.937 回答
0

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

于 2013-03-28T16:05:37.393 回答