我的数据库表名=" SearchTask"看起来像这样 列的数据类型
Task = varchar
AssignedDate = varchar
**Task | AssignedDate**
A | 01/02/2016
A | 02/03/2016
A | 05/04/2016
A | '
A | '
PS:第3行和第4行是char(39),当用户不想要任何指定日期时添加它们,并且无法更改此规则。客户必须这样。
现在我写一个查询
select task, AssignedDate
from SearchTask
where AssignedDate not like char(39)
and convert(varchar(10), convert(date,assigneddate, 105),112) >= 20160301
and convert(varchar(10), convert(date,assigneddate, 105),112) <= 20160331
它给了我错误信息
从字符串转换日期和/或时间时,转换失败
有人可以帮忙吗?
但我真正的问题是 如何在
时编写应该打印输出的查询根据要求我正在添加更多样本数据和预期输出:
**Task | AssignedDate**
A | 01/02/2016
A | 02/03/2016
A | 05/04/2016
A | '
A | '
如果我的情况说:
场景#1
where AssignedDate not like char(39)
and convert(varchar(10), convert(date,assigneddate, 105),112) >= 20160301
and convert(varchar(10), convert(date,assigneddate, 105),112) <= 20160331
It should print me:
A | 02/03/2016
场景#2
where AssignedDate not like char(39)
and convert(varchar(10), convert(date,assigneddate, 105),112) >= 20160201
and convert(varchar(10), convert(date,assigneddate, 105),112) <= null
它应该打印我:
A | 01/02/2016
A | 02/03/2016
A | 05/04/2016
场景#3
where AssignedDate not like char(39)
and convert(varchar(10), convert(date,assigneddate, 105),112) >= null
and convert(varchar(10), convert(date,assigneddate, 105),112) <= 20160301
它应该打印我:
A | 01/02/2016
A | 02/03/2016
答案 0 :(得分:1)
最重要的经验教训:从不让您的客户设计您的数据库
您应该使用可为空的date
或datetime
列来保留日期而不是您现在使用的varchar
,并且只要此列包含,表示层就会显示char(39)
null
。
如果您无法更改数据库,则应更改您的sql:
SELECT task, assigneddate
FROM SearchTask
WHERE CASE WHEN assigneddate <> '''' THEN convert(date,assigneddate, 105) ELSE '1900-01-01' END >= '2016-03-01'
AND CASE WHEN assigneddate <> '''' THEN convert(date,assigneddate, 105) ELSE '9999-12-31' END <= '2016-03-31'
使用case
语句可阻止数据库尝试将char(39)
转换为datetime
值。在原始查询中不是这种情况,因为Sql server不保证短路条件。
请注意,如果您可以更改数据库结构,那么这是最好的行动方案 在这里阅读更多相关信息:Aaron Bertrand的Bad habits to kick : choosing the wrong data type。
答案 1 :(得分:0)
很抱歉回复很晚: 我能够通过使用您提供的上述帮助来解决上述问题。我做的第一件事是使用日期选择器获取日期的用户输入并使用以下变量@AssignedDateFrom和@AssignedDateTo然后最后我使用了以下查询:
where
(@AssignedDateFrom is null or
(len(assigneddate)<>1 and
convert(date,substring(assigneddate,1,10),103)>=@AssignedDateFrom
)
)
and
(@AssignedDateTo is null or
(len(assigneddate)<>1 and
convert(date,substring(assigneddate,1,10),103)<=@AssignedDateTo
)
)