我正在用C#编写程序,其中一部分是从DB2服务器获取日期。日期在服务器上存储为长度为4的整数值。日期只持有月份和日期我遇到的问题是它们的存储精度不同。 编辑:数据类型是数字长度4,没有精度(所以整数长度为4)但是当Select语句运行时,所有内容都以字符串形式返回。这就是我使用SubStr()的原因。
示例
一个日期存储为 1003 ,表示日期 10/03
另一个日期存储为 805 ,代表 8/05
我用来提取日期的SQL代码
(SubStr(ML2DDM,0,3) ||'/'|| SubStr(ML2DDM,3,2))as Due__Date
程序以下列格式返回日期
10/03
80/5<<<<那就是问题
有没有办法每次都正确格式化值?
答案 0 :(得分:1)
如果它们是整数,似乎做字符串函数是一个坏主意。我只是按“原样”拉回整数,并在C#中处理它,然后你有:
V1 V2
1: 2000-02-08 2000-02-11
2: 2000-03-09 2000-03-15
您可以使用来实现所需的任何内容。我期待您的RDBMS 也内置了整数除法和模运算,因此您也可以在服务器上执行此操作。例如,在SQL Server中(因为我不知道DB2):
int month = val / 100;
int day = val % 100;
答案 1 :(得分:1)
显然你有整数存储为字符。因为您无法在整数列上使用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()
。
答案 2 :(得分:1)
select left(right(repeat('0', 4) || trim(ML2DDM), 4), 2) || '/' ||
right(right(repeat('0', 4) || trim(ML2DDM), 4), 2) as Due__Date
答案 3 :(得分:0)
在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
答案 4 :(得分:0)
如何获取糟糕的数据。我使用这种技术主要是为了在输出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
答案 5 :(得分:0)
考虑到这一点,就像很多帖子一样,没有给出DDL,我可以提供:
无论ML2DDM的DDL是CHAR(4),VARCHAR(4),SMALLINT,DECIMAL,NUMERIC,BIGINT还是INTEGER [数值类型],也确保任何实际值的精度不超过四位数虽然实际的列精度并不重要,但只有当列也定义为零刻度时;这当然是由各种INT类型暗示的,下面的表达式应该足以在每个 MMDD 基准的MM和DD组件之间插入一个/
字符。三位数值###或四位数值#### [其中#表示任意十进制数字0到9];如果数字存储为字符串,则它们必须左对齐存储,并且任何非数字数据都将被类似地编辑,尽管它们不是实际日期值的有效表示,但编辑的结果也不会确保价值以这种方式有效:
insert ( case length(rtrim(ML2DDM))
when 3 then '0' else '' end
concat ML2DDM
, 3, 0, '/' ) as due__date_ins
了解实际的DDL可以让表达更加简洁。
如果需要实际的DATE数据类型结果,则上面提供的表达式可以替换TIMESTAMP_FORMAT表达式的以下变体中的expr
,以生成具有当前年值{{TIMESTAMP'的TIMESTAMP 1}},这可以投射到DATE;例如TO_DATE( expr, 'MMDD' )
当然,这种额外投射的结果要求绝对将数据值存储为合法的MMDD [或MDD]值。
2016年9月30日附录:
如果ML2DDM的DDL是数字[非浮点],那么IIRC从数字到字符的隐式转换效果正在转换为VARCHAR,因此以下将是一个非常简单的表达式,以实现MMDD到" MM / DD&# 34;和MDD到" MM / DD":
DATE( TO_DATE( expr, 'MMDD' ) )