2016-09-29 3 views
1

Я пишу программу на C#, а ее часть - для получения дат с сервера DB2. Даты хранятся как целочисленные значения длины 4 на сервере. Дата имеет место только месяц и день. Проблема заключается в том, что они хранятся с различной точностью. EDIT: Тип данных - это числовая длина 4 без точности (поэтому целочисленная длина 4), но при выполнении оператора Select все возвращается как строка. Именно поэтому я использовал SubStr().SQL правильно форматирует целые числа как даты

Пример

Одна дата хранится в виде представления даты 10/03

Другая дата хранится в виде , представляющий 8/05

Код SQL, который я использую для вытягивания дат

(SubStr(ML2DDM,0,3) ||'/'|| SubStr(ML2DDM,3,2))as Due__Date 

Программа возвращает даты в следующем формате

10/03

< < 80/5 < < Thats проблемы

Есть ли способ, чтобы правильно каждый форматировать значения время?

+0

* '(SubStr (ML2DDM, 0,3) ||'/'|| SubStr (ML2DDM, 3 , 2)) как Due__Date '* не похож на Sql :) – Dan

+0

@ Dan Не нравится C# :) – Nsevens

+0

Это совершенно правильный SQL, хотя использование «0» в качестве исходной позиции для SUBSTR() необычно, даже если оно действительно. И использование SUBSTR() для столбца INTEGER также неразумно, хотя, возможно, имеет смысл в некоторых случаях, когда значение является auto-CAST для CHAR. – user2338816

ответ

1
select left(right(repeat('0', 4) || trim(ML2DDM), 4), 2) || '/' || 
right(right(repeat('0', 4) || trim(ML2DDM), 4), 2) as Due__Date   
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 
1

Если они целые, кажется, что делает строковые функции является плохой идеей. Я бы просто тянуть целое назад «как есть», и бороться с ним в C#, то у вас есть:

int month = val/100; 
int day = val % 100; 

Что вы можете thendo все, что вам нужно с. I ожидайте, что ваша СБД также имеет целочисленное деление и по модулю арифметики, поэтому вы можете, вероятно, сделать это и на сервере. Например, в 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] 
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 

The TRIM() требуется, если столбец является фиксированной длиной символов вместо VARCHAR.

+0

'SUBSTR()' в столбце INTEGER [или любом числовом]] приемлемо/поддерживается из-за * неявной функции литья * между символом и числовое.Вероятная проблема, конечно, заключалась бы в том, что приведение к символу из числа приводит к выравниванию значения; что, конечно, объясняет, почему результаты от числа с менее чем четырьмя цифрами значительной точности могут быть проблематичными для нахождения какой-либо конкретной позиции 10 ** N при просмотре слева направо по цифрам числовой длины N -1. – CRPence

0

Как получить плохие данные для чтения. Я использую этот метод в основном для создания открывающих и закрывающих тегов или добавления строк при выводе html, xml, plain text. Все там.

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 
0

Учитывая, что, как и многие другие должности, нет DDL не дал, я могу предложить, что:

зависимо от DDL для ML2DDM быть CHAR (4), VARCHAR (4), SMALLINT , DECIMAL, NUMERIC, BIGINT или INTEGER [числовых типов, то также обеспечивается не более четырех цифр точности для любых фактических значений, хотя фактическая точность столбца несущественна, но только если столбец также определен с нулевым значением, масштаб; что, разумеется, подразумевается различными типами INT], должно быть достаточно следующего выражения для вставки символа / между компонентами ММ и DD каждой базы данных MMDD, которая была сохранена либо с трехзначным числом ###, либо с помощью значение четырех цифр #### [где # представляет любую десятичную цифру от нуля до девяти]; если цифры хранятся как символьные строки, то они должны быть сохранены влево, а любые нецифровые данные будут аналогичным образом отредактированы, несмотря на то, что они не являются достоверными представлениями фактических значений даты, но ни один отредактированный результат числового значения обеспечиваются действительными таким образом:

insert (case length(rtrim(ML2DDM)) 
      when 3 then '0' else '' end 
      concat ML2DDM    
      , 3, 0, '/') as due__date_ins 

Зная фактический DDL может обеспечить более емкое выражение.

Если фактический результат DATE типа данных желательно, такое выражение, как одно предложенных выше, может заменить expr в следующей вариации выражения TIMESTAMP_FORMAT, чтобы сгенерировать TIMESTAMP со значением текущего года TO_DATE(expr, 'MMDD'), и что может быть перенесенным в DATE; например DATE(TO_DATE(expr, 'MMDD')) Конечно, результаты этого дополнительного литья требуют, чтобы значения данных сохранялись как допустимые значения MMDD [или MDD].

30-сентября-2016 Добавление:
Если DDL для ML2DDM является числовым [без поплавка], то IIRC неявного приведения эффект от числовой характеру бросает в VARCHAR, так что следующее будет достаточно простое выражение для осуществления как ММДД к "MM/DD" и MDD к "MM/DD":

insert (LPAD(ML2DDM , 4, '0') , 3, 0, '/') as Due__Date 
Смежные вопросы