场景是,数据库处于维护阶段。此数据库不是由我们的开发人员开发的。它是由sy server 2000中的'xyz'公司开发的现有数据库。这是我正在工作的实时数据库。我想编写存储过程,它将检索记录从date1到date 2.so查询是:
Select * from MyTableName
Where colDate>= '3-May-2010' and colDate<= '5-Oct-2010' and colName='xyzName'
虽然我理解我必须得到数据,包括上限日期和下限日期。但不知怎的,我从'2010年5月3日'(这很好但是)到'10 -Oct-2010'获得了记录
正如我在表格设计中观察到的,对于ColDate,开发人员使用'varchar'来存储日期。我知道这是错误的补救措施。所以在我的存储过程中,我还使用varchar参数作为@ FromDate1和@ToDate来获取SP的输入。这给了我解释的结果。我试图将参数类型作为'Datetime',但在保存/更改“@ FromDate1具有无效数据类型”的存储过程时显示错误,对于“@ToDate”也是如此。
情况是,我根本无法改变表设计。我必须在这做什么?我知道我们可以在sql server 2008中使用用户定义的表,但是有版本sql server 2000.它不支持相同。 请指导我这个场景。
**Edited**
I am trying to write like this SP:
CREATE PROCEDURE USP_Data
(@Location varchar(100),
@FromDate DATETIME,
@ToDate DATETIME) AS
SELECT *
FROM dbo.TableName
Where CAST(Dt AS DATETIME) >=@fromDate and CAST(Dt AS DATETIME)<=@ToDate and Location=@Location
GO
but getting Error: Arithmetic overflow error converting expression to data type datetime. in sql server 2000
应该是什么?我错了一些在哪里?还
(202 row(s) affected) is changes every time in circular manner means first time sayin
(122 row(s) affected)
run again saying
(80 row(s) affected)
if again
(202 row(s) affected)
if again
(122 row(s) affected)
我无法理解发生了什么?
答案 0 :(得分:1)
你可以CAST()或在这个表上放一个视图并将所有日期转换为DateTime值吗?我不记得2000支持的索引视图,但是根据你的varchar值(dd-mmm-yyyy),尝试用这些值来选择日期范围(可能通过解析但很痛苦)将是一场噩梦。
答案 1 :(得分:0)
你需要投射&#34;日期&#34;在varchar列中的实际datetime
值,然后进行比较。另外,我建议您使用YYYYMMDD格式作为日期。
Select ...
From MyTableName
Where Cast(colDate As datetime) >= '20100503'
And Cast(colDate As datetime) <= '20101005'
And colName = 'xyzName'
如果您要传递参数,您还需要强制它们为日期时间
Create Procedure Foo
@FromDate datetime
, @ToDate datetime
...
As
Select ...
From MyTableName
Where Cast(colDate As datetime) >= @FromDate
And Cast(colDate As datetime) <= @ToDate
And colName = 'xyzName'
当然,最好的解决方案是简单地将表中的数据类型更改为datetime
并更正相关程序或创建几个计算列,将varchar值转换为datetime
或简单地添加一些静态datetime
列,并从varchar列进行一次性更新。
<强>更新强>
您得到的错误是因为某些varchar值无法转换为datetime
(这就是为什么将它们作为varchar是一个坏主意)。必须更正这些值,或者必须排除这些值。要查找不是日期的值,可以使用IsDate
函数。
Select ...
From MyTableName
Where IsDate( colDate ) = 0
您可以编写查询以排除这些值的另一种方法是:
Select ...
From (
Select Cast(colDate As datetime) As CastedDate
, ...
From MyTable
Where IsDate( colDate ) = 1
)
Where CastedDate >= @FromDate
And CastedDate <= @ToDate
答案 2 :(得分:0)
SELECT
*
FROM
MyTableName
WHERE
CAST(colDate AS DATETIME) >= '3-May-2010'
and
CAST(colDate AS DATETIME) < DATEADD(day, 1, '5-Oct-2010')
AND
colName = 'xyzName'
答案 3 :(得分:0)
听起来你需要找到坏数据。我也必须处理varchar列中存储的日期时间数据。跟踪错误数据可能很困难。首先,我打开桌子并对其进行了观察,寻找错误格式化的日期,但我找不到任何日期,所以我认为很少,并且可以快速使用更加程序化的方法。我最终使用了分而治之的方法:我将数据分成两半,并尝试将每一半投射到日期时间。如果任何一半导致错误,那么我进一步将其分成两半并检查这两半。这是一个递归过程。我可以为此编写T-SQL,但我手动完成了。大概花了半个小时。
例如,假设MyTableName有一个名为MyID的PRIMARY KEY,连续值从1开始到1000000结束。然后我会运行两个查询来检查哪一半(或一半)包含无效数据:
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 1 AND 500000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 500001 AND 1000000
GO
如果第一个查询导致错误,那么我会再运行两个查询:
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 1 AND 250000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 250001 AND 500000
GO
假设在此迭代中,只有第二个查询导致错误。然后,我会再运行两个查询:
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 250001 AND 375000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 375001 AND 500000
GO
最终 - 在log-base-2-of-n次迭代或更少 - 你会发现第一个错误的数据值。当然,您不知道表中有多少错误值,因此找到所有这些值可能需要一些时间。在我的情况下,我有大约10个错误的值,其中一些是'none'或'NA',我更新为NULL,其中一些只是格式错误的日期,我更新为正确格式化的日期。修复了不良数据后,我终于能够回到分析数据的原始任务。
答案 4 :(得分:0)
查找错误数据的另一种方法是使用SQL Server 2000的有限正则表达式功能:
SELECT
*
FROM
MyTableName
WHERE
colDate NOT LIKE '[1-9]-Jan-[12][0-9][0-9][0-9]'
AND
colDate NOT LIKE '[12][0-9]-Jan-[12][0-9][0-9][0-9]'
AND
colDate NOT LIKE '3[01]-Jan-[12][0-9][0-9][0-9]'
AND
colDate NOT LIKE '[1-9]-Feb-[12][0-9][0-9][0-9]'
AND
colDate NOT LIKE '1[0-9]-Feb-[12][0-9][0-9][0-9]'
AND
colDate NOT LIKE '2[0-8]-Feb-[12][0-9][0-9][0-9]' -- ignore Feb 29 for now
AND
您必须自己完成查询。