SQL将整数正确格式化为日期
本文关键字:格式化 日期 整数 SQL | 更新日期: 2023-09-27 18:09:25
我正在用C#编写一个程序,其中一部分是从DB2服务器获取日期。日期在服务器上存储为长度为4的整数值。日期只能保存一个月和一天。我的问题是它们的存储精度不同。EDIT:数据类型为无精度的数字长度4(因此为整数长度4(,但当Select语句运行时,所有数据都以字符串形式返回。这就是我使用SubStr((的原因。
示例
一个日期存储为1003,表示日期10/03
另一个日期存储为805,表示8/05
我用来提取日期的SQL代码
(SubStr(ML2DDM,0,3) ||'/'|| SubStr(ML2DDM,3,2))as Due__Date
程序以以下格式返回日期
2003年10月
80/5<lt<lt;这就是的问题
有没有办法每次都正确地格式化值?
select left(right(repeat('0', 4) || trim(ML2DDM), 4), 2) || '/' ||
right(right(repeat('0', 4) || trim(ML2DDM), 4), 2) as Due__Date
如果它们是整数,那么执行字符串函数似乎是个坏主意。我只想把整数拉回到"原样",并在C#中处理它,然后你就有了:
int month = val / 100;
int day = val % 100;
然后你可以用做任何你需要做的事情。我期望您的RDBMS也内置了整数除法和模运算,因此您可能也可以在服务器上执行此操作。例如,在SQL Server中(因为我不了解DB2(:
declare @v int = 805; -- obviously in real code this would be a column
select @v / 100 as [month], @v % 100 as [day]
显然,您将整数存储为字符。因为您将无法在整数列上使用SUBSTR()
。
两个SQL解决方案
转换为分区/压缩十进制,然后使用DIGITS()
转换回字符并包括前导零
select
(SubStr(digits(dec(ML2DDM,4)),1,2)
||'/'|| SubStr(digits(dec(ML2DDM,4)),3,2))as Due__Date
添加一些前导零,然后取RIGHT()
大多数字符。。。
select
(left(right(trim('0' || ML2DDM),4),2)
||'/'|| right(trim('0'|| ML2DDM),2) as Due__Date
如果列是固定长度字符而不是VARCHAR,则需要TRIM()
。
在C#中,我会做这样的事情:
var fullValue = ML2DDM;
var formattedDate = fullValue.Substring(0, fullValue.Length - 2) + "/" + fullValue.Substring(fullValue.Length - 2, 2);
我不知道任何DB2,但也许同样的方法也有效?类似于:
(SubStr(ML2DDM,0,length(ML2DDM)-2) ||'/'|| SubStr(ML2DDM,length(ML2DDM)-2,2))as Due__Date
如何使坏数据可读。我使用这种技术主要是为了在输出html、xml和纯文本时制作打开和关闭标记或添加换行符。所有的方法。
select
case when length(trim(ml2ddm)) = 4
then substring(ml2ddm,1,2) || '/' || substring(ml2ddm,3)
when substring(trim(ml2ddm,4,1) = ' '
then substring(ml2ddm,1,1) || '/' || substring(ml2ddm,2)
else substring(ml2ddm,2,1) || '/' || substring(ml2ddm,3)
end as somefunkydate
from somereallyfunkydata
考虑到像许多帖子一样,没有给出DDL,我可以提供:
不管ML2DDM的DDL是CHAR(4(、VARCHAR(4,以下表达式应足以在每个MMDD数据的MM和DD分量之间插入一个CCD_;如果数字被存储为字符串,那么它们必须左对齐存储,并且任何非数字数据都将被类似地编辑,尽管它们不是实际日期值的有效表示,但也不能确保数字值的编辑结果以这种方式有效:
insert ( case length(rtrim(ML2DDM))
when 3 then '0' else '' end
concat ML2DDM
, 3, 0, '/' ) as due__date_ins
了解实际的DDL可以获得更简洁的表达式。
如果需要实际的DATE数据类型结果,则诸如上面提供的表达式之类的表达式可以替换TIMESTAMP_FORMAT表达式的以下变体中的expr
,以生成具有当前年份值TO_DATE( expr, 'MMDD' )
的TIMESTAMP,并且该TIMESTAMP可以强制转换为DATE;例如DATE( TO_DATE( expr, 'MMDD' ) )
当然,这种附加强制转换的结果将要求绝对将数据值存储为合法的MMDD[或MDD]值。
2016年9月30日附录:
如果ML2DDM的DDL是数字[非浮点],则IIRC从数字到字符的隐式强制转换效果将强制转换为VARCHAR,因此下面的表达式非常简单,既可以将MMDD转换为"MM/DD",也可以将MDD转换为"MM/DD":
insert ( LPAD( ML2DDM , 4, '0' ) , 3, 0, '/' ) as Due__Date