请问一段关于日期转换句如何更改

sdmc01 2014-10-20 05:48:40
该语句最终目的是查询某月日(变量输入)至某月日(变量输入)内过生日的人,

DECLARE @t TABLE(ID int,Name varchar(10),Birthday varchar(10))
INSERT @t SELECT 1,'aa','1999-01-01'
UNION ALL SELECT 2,'bb','1996-02-29'
UNION ALL SELECT 3,'bb','1934-03-01'
UNION ALL SELECT 4,'bb','1966-04-01'
UNION ALL SELECT 5,'bb','1997-05-01'
UNION ALL SELECT 6,'bb','1922-11-21'
UNION ALL SELECT 7,'bb','1989-12-11'
DECLARE @dt1 varchar(10),@dt2 varchar(10)

--下面赋值这样查询无问题
set @dt1='2000-02-05'
set @dt2='2003-11-28'
--但是如果赋值一个变量就无效了
set @dt1=:dt1 --dt1是人工选择的一个日期,是2000-1-5这种格式
set@dt2=:dt2 --dt2也是人工选择一个日期
SELECT * FROM @t
WHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday)
BETWEEN @dt1 AND @dt2
and DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday)
BETWEEN @dt1 AND @dt2

请问如何更改,实际中提示:必须声明标量变量,更改@DT1为'''+@dt1+''' 最后查询结果无过滤效果了
...全文
529 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2014-10-23
  • 打赏
  • 举报
回复
实际上最应该修改的是传入参数的程序:
统一传入格式为 01-05;
:dt2 如果是月底可以用 02-31 表示,SQL 中直接进行字符串比较,就不会发生转换类型时 02-31 是无效日期的错误。
还在加载中灬 2014-10-23
  • 打赏
  • 举报
回复
'1996-02-29' '2015-01-01' '2015-02-28'
Tiger_Zhao 2014-10-23
  • 打赏
  • 举报
回复
IF @dt1 <= @dt2
BEGIN
SELECT * FROM @t
WHERE RIGHT(Birthday,5) BETWEEN @dt1 AND @dt2
END
ELSE -- 考虑跨年底的情况
BEGIN
SELECT * FROM @t
WHERE @dt1 <= RIGHT(Birthday,5)
OR RIGHT(Birthday,5) <= @dt2
END
Tiger_Zhao 2014-10-23
  • 打赏
  • 举报
回复
真啰嗦。
--将输入的 2000-1-5 格式统一成 01-05 格式
set @dt1 = Right(Convert(varchar(10), Convert(datetime,:dt1,120), 120), 5)
set @dt2 = Right(Convert(varchar(10), Convert(datetime,:dt2,120), 120), 5)

-- 不看年份直接比较月日不就成了
SELECT * FROM @t
WHERE RIGHT(Birthday,5) BETWEEN @dt1 AND @dt2
寡亾 2014-10-23
  • 打赏
  • 举报
回复
查询哪个日期段内有谁过生日也不是这种搞法啊,何必简单问题复杂化、
chen870201 2014-10-22
  • 打赏
  • 举报
回复
貌似语法不对啊
sdmc01 2014-10-21
  • 打赏
  • 举报
回复
引用 25 楼 sdmc01 的回复:
[quote=引用 24 楼 ky_min 的回复:] 仔细想也没想出怎么好的简化~~ 先这样吧~~

DECLARE @P8startDate DATETIME,@P9endDate DATETIME
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate VARCHAR(10)
SET @P8startDate='2014-12-01'
SET @P9endDate='2015-02-28'
SELECT * FROM #sxx WHERE
	DATEADD(Year,DATEDIFF(Year,Birthday,@P8startDate),Birthday) BETWEEN @P8startDate AND @P9endDate
	and DATEADD(Year,DATEDIFF(Year,Birthday,@P9endDate),Birthday) BETWEEN @P8startDate AND @P9endDate
感觉没必要动态执行~
从字符串向 datetime 转换时失败。 BIrthday表中有空值是不是产生这个错误的原因[/quote]找到原因了,确实是空值的原因,过滤空值后查询有效果,但是查询的结果都是小于,@P8startDate 月日的,为什么呢 中间为什么是or,感觉是and才对,or查旬结果是全部的好像
还在加载中灬 2014-10-21
  • 打赏
  • 举报
回复
引用 26 楼 sdmc01 的回复:
找到原因了,确实是空值的原因,过滤空值后查询有效果,但是查询的结果都是小于,@P8startDate 月日的,为什么呢 中间为什么是or,感觉是and才对,or查旬结果是全部的好像
你试下以下脚本
DECLARE @t TABLE(ID int,Name varchar(10),Birthday varchar(10))
INSERT @t SELECT 1,'aa','1999-01-01'
UNION ALL SELECT 2,'bb','1996-02-29'
UNION ALL SELECT 3,'bb','1934-03-01'
UNION ALL SELECT 4,'bb','1966-04-01'
UNION ALL SELECT 5,'bb','1997-05-01'
UNION ALL SELECT 6,'bb','1922-11-21'
UNION ALL SELECT 7,'bb','1989-12-11'
DECLARE @P8startDate DATETIME,@P9endDate DATETIME
--set @P8startDate=:P8startdate
--set @P9endDate=:P9enddate
SET @P8startDate='2014-12-01'
SET @P9endDate='2015-02-28'
SELECT * FROM @t WHERE
    DATEADD(Year,DATEDIFF(Year,Birthday,@P8startDate),Birthday) BETWEEN @P8startDate AND @P9endDate
    OR DATEADD(Year,DATEDIFF(Year,Birthday,@P9endDate),Birthday) BETWEEN @P8startDate AND @P9endDate
这个脚本的结果是, /* 1 aa 1999-01-01 2 bb 1996-02-29 7 bb 1989-12-11 */ 如果这是你想的结果就没有错~ 空值,是输入查询参数的空值还是,Birthday的空值呢? Birthday建议储存为 DATETIME 占用空间比VARCHAR(10)小~ 用OR原因是 那个条件判断就变成以下的判断 把Birthday的年数改为和@P8startDate一样的年数,或改为和@P9endDate一样的年数时,必须在P8startDate和@P9endDate的范围之间。 因此, 1 aa 1999-01-01 2014-01-01X 2015-01-01√ 2 bb 1996-02-29 2014-02-28X 2015-02-28√ 7 bb 1989-12-11 2014-12-11√ 2015-12-11X 这些数据是符合的,改成AND的话,就一个值也没有了~
sdmc01 2014-10-20
  • 打赏
  • 举报
回复
引用 24 楼 ky_min 的回复:
仔细想也没想出怎么好的简化~~ 先这样吧~~

DECLARE @P8startDate DATETIME,@P9endDate DATETIME
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate VARCHAR(10)
SET @P8startDate='2014-12-01'
SET @P9endDate='2015-02-28'
SELECT * FROM #sxx WHERE
	DATEADD(Year,DATEDIFF(Year,Birthday,@P8startDate),Birthday) BETWEEN @P8startDate AND @P9endDate
	OR DATEADD(Year,DATEDIFF(Year,Birthday,@P9endDate),Birthday) BETWEEN @P8startDate AND @P9endDate
感觉没必要动态执行~
从字符串向 datetime 转换时失败。 BIrthday表中有空值是不是产生这个错误的原因
还在加载中灬 2014-10-20
  • 打赏
  • 举报
回复
仔细想也没想出怎么好的简化~~ 先这样吧~~

DECLARE @P8startDate DATETIME,@P9endDate DATETIME
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate VARCHAR(10)
SET @P8startDate='2014-12-01'
SET @P9endDate='2015-02-28'
SELECT * FROM #sxx WHERE
	DATEADD(Year,DATEDIFF(Year,Birthday,@P8startDate),Birthday) BETWEEN @P8startDate AND @P9endDate
	OR DATEADD(Year,DATEDIFF(Year,Birthday,@P9endDate),Birthday) BETWEEN @P8startDate AND @P9endDate
感觉没必要动态执行~
还在加载中灬 2014-10-20
  • 打赏
  • 举报
回复
引用 22 楼 sdmc01 的回复:
[quote=引用 18 楼 ky_min 的回复:] Declare @ssql Nvarchar(4000) 这边要NVARCHAR 我已经帮你改过来了,你改回去?
是不是换个思路,直接调取P8startdate和@P9endDate后四位 birthday后四位大于P8startdate后四位小于@P9endDate后四位这样,语句怎么写我不知道,请教一下[/quote]明白你的业务之后,我感觉可以简化~
sdmc01 2014-10-20
  • 打赏
  • 举报
回复
引用 18 楼 ky_min 的回复:
Declare @ssql Nvarchar(4000) 这边要NVARCHAR 我已经帮你改过来了,你改回去?
是不是换个思路,直接调取P8startdate和@P9endDate后四位 birthday后四位大于P8startdate后四位小于@P9endDate后四位这样,语句怎么写我不知道,请教一下
sdmc01 2014-10-20
  • 打赏
  • 举报
回复
引用 20 楼 tangguangqiang 的回复:
1.set @P8startDate=:P8startdate set @P9endDate=:P9enddate sqlserver 根本就没有这种语法,要不你把你的查询写成存储过程,前端再调用,传参数进去。 2.DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday) 这个不知道你的where过滤做什么,上面这个的结果不就是(@P8startDate 吗。
1、这是利用一个系统软件自带的参数来写的,就是这个语法,所有有关参数也就是自己输入的部分都是这样的 2、这是查询某月某日范围内过生日的人,年当然要忽略
习惯性蹭分 2014-10-20
  • 打赏
  • 举报
回复
1.set @P8startDate=:P8startdate set @P9endDate=:P9enddate sqlserver 根本就没有这种语法,要不你把你的查询写成存储过程,前端再调用,传参数进去。 2.DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday) 这个不知道你的where过滤做什么,上面这个的结果不就是(@P8startDate 吗。
sdmc01 2014-10-20
  • 打赏
  • 举报
回复
引用 18 楼 ky_min 的回复:
Declare @ssql Nvarchar(4000) 这边要NVARCHAR 我已经帮你改过来了,你改回去?
改成这样了,也不报错了,但是无过滤日期的效果了,也就是全部显示了
还在加载中灬 2014-10-20
  • 打赏
  • 举报
回复
Declare @ssql Nvarchar(4000) 这边要NVARCHAR 我已经帮你改过来了,你改回去?
sdmc01 2014-10-20
  • 打赏
  • 举报
回复
引用 16 楼 ky_min 的回复:
Declare @ssql Nvarchar(4000)
 
Declare @P8startDate datetime
Declare @P9endDate datetime
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate
Set @sSql='
select * from #sxx
where  DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime)
and DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P9endDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime) 
'
exec SYS.sp_executesql @sSQL,N'@P8startDate datetime,@P9endDate datetime',@P8startDate,@P9endDate
这样试下
过程需要类型为 'ntext/nchar/nvarchar' 的参数 '@statement'。提示这个
还在加载中灬 2014-10-20
  • 打赏
  • 举报
回复
Declare @ssql Nvarchar(4000)
 
Declare @P8startDate datetime
Declare @P9endDate datetime
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate
Set @sSql='
select * from #sxx
where  DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime)
and DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P9endDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime) 
'
exec SYS.sp_executesql @sSQL,N'@P8startDate datetime,@P9endDate datetime',@P8startDate,@P9endDate
这样试下
xiaodongni 2014-10-20
  • 打赏
  • 举报
回复

Declare @ssql varchar(8000)
 

Set @sSql='
Declare @P8startDate datetime
Declare @P9endDate datetime
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate
select * from #sxx
where  DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime)
and DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P9endDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime) 
'
exec(@sSQL)
试试这个。把声明变量放在里面
sdmc01 2014-10-20
  • 打赏
  • 举报
回复

Declare @ssql varchar(8000)

Declare @P8startDate datetime
Declare @P9endDate datetime
set @P8startDate=:P8startdate
set @P9endDate=:P9enddate
Set @sSql='
select * from #sxx
where  DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P8startDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime)
and DATEADD(Year,DATEDIFF(Year,Birthday,cast(@P9endDate as datetime)),Birthday)
BETWEEN cast(@P8startDate as datetime) AND cast(@P9endDate as datetime) 
'
exec(@sSQL)
当使用这种语句时,提示必须声明标量变量“@P8startDate ”
加载更多回复(13)

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧