風雲論壇后台开发 → 浏览:帖子主题
分页: 1 2 3, 共 3 页
* 帖子主题:从ACCESS转为MSSQL后,遇到一个闰年2000-2-29日期问题
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 1 楼 ] 回复
从ACCESS转为MSSQL2005后,遇到一个闰年2000-2-29日期问题。

sql="select count(*) as ttshu from shengri where (user="&session("user")&" and gongnong=0 and DateDiff(day,getdate(),dateadd(year,DateDiff(year,birthday,getdate()),birthday))between 0 and 14) or (user="&session("user")&" and gongnong=1  and shengrin<>'2-29' and shengrin<>'2-30' and DateDiff(day,'"&(jinnongli)&"',dateadd(year,DateDiff(year,nongli,'"&(jinnongli)&"'),nongli))between 0 and 14)"


nongli 
2000-2-29
1990-4-11
1988-5-18

shengrin
2-29
4-11
5-18

gongnong=0 表示公历
gongnong=1 表示农历

birthday  表示公历生日
nongli    表示农历生日


通过上面语句列出14天内过阳历生日和农历生日的人数,在ACCESS运行正常,转为MSSQL数据库就出错了。语句里的字段nongli,其中一条数据是2000-2-29,

运行 提示
[SQL Server]将 expression 转换为数据类型 datetime 时出现算术溢出错误。

由此发现MSSQL2005不识别2-29 2-30,当把上述2000-2-29改为2000-2-28运行就正常了。

但是有用户提交的生日是2000-2-29,请教风云怎么做,能修改上面的语句避免错误吗
2023/11/24 9:32:27 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 2 楼 ] 回复
说明 SQL2005 不支持闰月?可以尝试存储为 nchar(10)。或者转为 2000-03-01
2023/11/24 9:34:04 IP:已设置保密
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 3 楼 ] 回复
convert(char(10),nongli,120)已经尝试过还是报错。
当前处理是,前台用户提交的生日为2-29 2-30,给改为2-28入库。

如果改成了2-28入库,当快过生日时或生日当天,数据库有其他人提交的不同生日
1. 我要列出最近14天过生日的人数,怎么处理呢,
2. 以及在过生日的时候,提前几天或当天给用户发邮件提醒,怎么处理呢。
2023/11/24 9:51:20 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 4 楼 ] 回复
那要看实际情况,例如今年没有 2月29,那这个人今年的生日算 2月28?还是 3月1日?还是今年不过生日?😀
也可以尝试使用 case when,遇到 2-29 且 year % 4 > 0 的情况就转为 2-28。
select convert(date, year(getdate()) + '-' + case when shengri when '2-29' and year(getdate()) % 4 > 0 then shengri else '2-28' end)
2023/11/24 9:55:30 IP:已设置保密
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 5 楼 ] 回复
sql="select count(*) as ttshu from shengri where (user="&session("user")&" and gongnong=0 and DateDiff(day,getdate(),dateadd(year,DateDiff(year,birthday,getdate()),birthday))between 0 and 14) or (user="&session("user")&" and gongnong=1  and shengrin<>'2-29' and shengrin<>'2-30' and DateDiff(day,'"&(jinnongli)&"',dateadd(year,DateDiff(year,nongli,'"&(jinnongli)&"'),nongli))between 0 and 14)"

没有2-29 2-30,生日也只能28的过(也即提前1天过)。当有2-29 2-30,那就正常过啊。

风云,请教具体语句应该怎么写呢?
2023/11/24 10:07:26 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 6 楼 ] 回复
我没看懂这个怎么判断农历生日的。如果只判断公历生日,我会这么写(PGSQL):
with shengri as (
    select '2-19' shengrin union
    select '3-1' union
    select '2-28' union
    select '11-28'
),
today as (
    select extract(year from now()) toyear, current_date today
),
-- 转换成日期格式
shengri1 as (
    select (toyear || '-' || case when shengrin='2-29' and toyear % 4 > 0 then '2-28' else shengrin end)::date shengrin
    from today a, shengri b
),
-- 小于今天的都+1年
shengri2 as (
    select case when shengrin<current_date then shengrin + interval '1 Year' else shengrin end::date shengrin from shengri1
)
select shengrin from shengri2 where shengrin-current_date<15
2023/11/24 10:32:11 IP:已设置保密
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 7 楼 ] 回复
判断农历生日,jinnongli 表示今天是农历多少,如2023-10-12,在对比用户提交的农历生日,对比相差天数。

我是想写在ASP文件里面,
如最近14天有多少人过生日,
我是用的ASP文件定时任务计划打开ASP文件来发送邮件的

放到ASP文件里,语句怎么写呢
2023/11/24 10:43:01 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 8 楼 ] 回复
去掉注释和换行,改成 SQL 可以试试这个:
with shengri as (select '2-19' shengrin union select '3-1' union select '2-28' union select '11-28'), today as (select year(getdate()) toyear, convert(date, getdate()) today), shengri1 as (select a.today, concat(toyear, '-', case when shengrin='2-29' and toyear % 4 > 0 then '2-28' else shengrin end) shengrin from today a, shengri b), shengri2 as (select convert(date, case when shengrin<today then dateadd(year, 1, shengrin) else shengrin end) shengrin, today from shengri1) select shengrin, datediff(day, today, shengrin) remain from shengri2 where datediff(day, today, shengrin)<15
2023/11/24 10:50:59 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 9 楼 ] 回复
格式化看得清晰一些:
with shengri as (
    select '2-19' shengrin union
    select '3-1' union
    select '2-28' union
    select '11-28'
)
,today as (select year(getdate()) toyear, convert(date, getdate()) today)
,shengri1 as (select a.today, concat(toyear, '-', case when shengrin='2-29' and toyear % 4 > 0 then '2-28' else shengrin end) shengrin from today a, shengri b)
,shengri2 as (select convert(date, case when shengrin<today then dateadd(year, 1, shengrin) else shengrin end) shengrin, today from shengri1)
select shengrin, datediff(day, today, shengrin) remain from shengri2 -- where datediff(day, today, shengrin)<15

结果为:
+------------+--------+
|  shengrin  | remain |
+------------+--------+
| 2024-02-19 |  86  |
| 2024-03-01 |  96  |
| 2024-02-28 |  93  |
| 2023-11-28 |  4    |
+------------+--------+
2023/11/24 10:52:04 IP:已设置保密
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 10 楼 ] 回复
我不是在数据库里面直接查询。
放进ASP文件里面查询,如下面:

sql="select count(*) as ttshu from shengri where (user="&session("user")&" and gongnong=0 and DateDiff(day,getdate(),dateadd(year,DateDiff(year,birthday,getdate()),birthday))between 0 and 14) or (user="&session("user")&" and gongnong=1  and shengrin<>'2-29' and shengrin<>'2-30' and DateDiff(day,'"&(jinnongli)&"',dateadd(year,DateDiff(year,nongli,'"&(jinnongli)&"'),nongli))between 0 and 14)"

你写的代码可以整合到上面的语句里面吗?
2023/11/24 11:51:41 IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:天使
积分:1373
发帖:60
来自:保密
注册:2022/3/30 15:28:53
造访:2024/5/3 6:15:31
[ 第 11 楼 ] 回复
asp 也可以直接执行这个 SQL 语句的。写多行是为了看得更清晰。你可以试试
sql = "with shengri as (select '2-19' shengrin union select '3-1' union select '2-28' union select '11-28'), today as (select year(getdate()) toyear, convert(date, getdate()) today), shengri1 as (select a.today, concat(toyear, '-', case when shengrin='2-29' and toyear % 4 > 0 then '2-28' else shengrin end) shengrin from today a, shengri b), shengri2 as (select convert(date, case when shengrin<today then dateadd(year, 1, shengrin) else shengrin end) shengrin, today from shengri1) select shengrin, datediff(day, today, shengrin) remain from shengri2 where datediff(day, today, shengrin)<15"
set Rs = Conn.Execute sql

从你的 SQL 语句来看,你的逻辑和结构有些复杂,我可能会这么处理:
1、计算今天农历和公历的日期差值,然后农历统一增加该差值。
2、统一格式,将农历的 YYYY-MM-DD 统一为 MM-DD 结构。
3、将生日全部设置为今年。对小于今天的日期再增加1年
4、筛选 between today and dateadd(day, today, 14) 的数据即可
具体如何写,我这没有条件测试,你可以尝试按照该逻辑编写 SQL 语句。然后你的SQL 语句应该是查看某个用户是否在 14 天内过生日,不是列出所有 14 天内即将过生日的人。
2023/11/24 12:02:35 IP:已设置保密
tian (ID: 45)
等级:精灵
积分:122
发帖:6
来自:保密
注册:2023/11/24 9:14:32
造访:2024/2/17 9:58:19
[ 第 12 楼 ] 回复
虽然在一个表里面,农历和公历的生日分开的。
统计14天内过生日的人数,以及发送邮件给即将过生日的(当天,3天前,7天前),是采用:
单独对比公历生日和今天公历日期。
单独对比农历生日和今天农历日期。


请问 with shengri as (select '2-19' shengrin union select '3-1' union select '2-28' union select '11-28'),  这里面的日期是测试用的吗
2023/11/24 14:52:48 IP:已设置保密
分页: 1 2 3, 共 3 页
快速回复主题
账号/密码
用户: 没有注册? 密码:
评论内容