Пользовательское форматирование даты и времени в SQL Server

Я пытаюсь написать хранимую процедуру, которая выбирает столбцы из таблицы и добавляет 2 дополнительных столбца в ResultSet. Эти 2 дополнительных столбца являются результатом преобразований в поле в таблице, которое является полем Datetime.

Поле формата Datetime имеет следующий формат: "YYYY-MM-DD HH: MM: SS.S"

Два дополнительных поля, которые должны быть в следующем формате:

  • DDMMM
  • HHMMT, где T - "A" для a.m и p для p.m.

Пример: если данные в поле были "2008-10-12 13: 19: 12.0", тогда извлеченные поля должны содержать:

  • 12OCT
  • 0119P

Я пробовал использовать строковые форматы CONVERT, но ни один из форматов не соответствует выходному, который я хочу получить. Я думаю по линиям извлечения полевых данных через CONVERT, а затем с помощью REPLACE, но я, безусловно, нуждаюсь в некоторой помощи здесь, поскольку я не уверен.

Может ли кто-нибудь, хорошо разбирающийся в хранимых процедурах, помочь мне здесь? Спасибо!

Ответ 1

Если dt - ваш столбец datetime, то

Для 1:

SUBSTRING(CONVERT(varchar, dt, 13), 1, 2)
    + UPPER(SUBSTRING(CONVERT(varchar, dt, 13), 4, 3))

Для 2:

SUBSTRING(CONVERT(varchar, dt, 100), 13, 2)
    + SUBSTRING(CONVERT(varchar, dt, 100), 16, 3)

Ответ 2

Используйте DATENAME и оберните логику в функции, а не в хранимой программе

declare @myTime as DateTime

set @myTime = GETDATE()

select @myTime

select DATENAME(day, @myTime) + SUBSTRING(UPPER(DATENAME(month, @myTime)), 0,4)

Возвращает "14OCT"

Попытайтесь не использовать какие-либо операции на основе символов/строк, если это возможно при работе с датами. Они являются численными (float), и производительность будет зависеть от этих преобразований типа данных.

Вырежьте эти удобные конверсии, которые я собрал за эти годы...

/* Common date functions */
--//This contains common date functions for MSSQL server

/*Getting Parts of a DateTime*/
    --//gets the date only, 20x faster than using Convert/Cast to varchar
    --//this has been especially useful for JOINS
    SELECT (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime))

    --//gets the time only (date portion is '1900-01-01' and is considered the "0 time" of dates in MSSQL, even with the datatype min value of 01/01/1753. 
    SELECT (GETDATE() - (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime)))


/*Relative Dates*/
--//These are all functions that will calculate a date relative to the current date and time
    /*Current Day*/
    --//now
    SELECT (GETDATE())

    --//midnight of today
    SELECT (DATEADD(ms,-4,(DATEADD(dd,DATEDIFF(dd,0,GETDATE()) + 1,0))))

    --//Current Hour
    SELECT DATEADD(hh,DATEPART(hh,GETDATE()),CAST(FLOOR(CAST(GETDATE() AS FLOAT)) as DateTime))

    --//Current Half-Hour - if its 9:36, this will show 9:30
    SELECT DATEADD(mi,((DATEDIFF(mi,(CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)), GETDATE())) / 30) * 30,(CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)))

    /*Yearly*/
    --//first datetime of the current year
    SELECT (DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0))

    --//last datetime of the current year
    SELECT (DATEADD(ms,-4,(DATEADD(yy,DATEDIFF(yy,0,GETDATE()) + 1,0))))

    /*Monthly*/
    --//first datetime of current month
    SELECT (DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0))

    --//last datetime of the current month
    SELECT (DATEADD(ms,-4,DATEADD(mm,1,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0))))

    --//first datetime of the previous month
    SELECT (DATEADD(mm,DATEDIFF(mm,0,GETDATE()) -1,0))

    --//last datetime of the previous month
    SELECT (DATEADD(ms, -4,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)))

    /*Weekly*/
    --//previous monday at 12AM
    SELECT (DATEADD(wk,DATEDIFF(wk,0,GETDATE()) -1 ,0))

    --//previous friday at 11:59:59 PM
    SELECT (DATEADD(ms,-4,DATEADD(dd,5,DATEADD(wk,DATEDIFF(wk,0,GETDATE()) -1 ,0))))

    /*Quarterly*/
    --//first datetime of current quarter
    SELECT (DATEADD(qq,DATEDIFF(qq,0,GETDATE()),0))

    --//last datetime of current quarter
    SELECT (DATEADD(ms,-4,DATEADD(qq,DATEDIFF(qq,0,GETDATE()) + 1,0)))

Ответ 3

Не отвечайте на свой вопрос конкретно, но это не то, что должно обрабатываться уровнем презентации вашего приложения. Выполнение этого так, как вы описываете, создает дополнительную обработку в конце базы данных, а также добавление дополнительного сетевого трафика (при условии, что база данных существует на другой машине, чем приложение), для чего-то, что может быть легко рассчитано на стороне приложения, с более богатой датой обработки библиотек, а также быть агностиком языка, особенно в случае вашего первого примера, который содержит сокращенное название месяца. Во всяком случае, другие ответы, которые вы дадите, должны указывать вам в правильном направлении, если вы все еще решите пойти по этому маршруту.

Ответ 4

Вы можете использовать следующую команду на сервере SQL:

select FORMAT(getdate(), N'yyyy-MM-ddThh:mm:ss')

Ответ 5

Поле формата Datetime имеет следующий формат: "YYYY-MM-DD HH: MM: SS.S"

Это утверждение ложно. Это то, как Enterprise Manager или SQL Server решает показать дату. Внутренне это 8-байтовое двоичное значение, поэтому некоторые из функций, опубликованных Эндрю, будут работать так хорошо.

Кибби также делает правильный вывод, и в идеальном мире я бы согласился с ним. Однако иногда вы хотите напрямую привязывать результаты запроса для отображения элементов управления или виджетов, и на самом деле нет возможности делать какие-либо форматирования. И иногда слой презентации живет на веб-сервере, который даже более загружен, чем база данных. Имея это в виду, не обязательно плохо знать, как это сделать в SQL.

Ответ 6

Да Отправление - это решение для этого, но я думаю, что такие методы - длительные поездки!

SQL SERVER:

SELECT CAST(DATEPART(DD,GETDATE()) AS VARCHAR)+'/'
+CAST(DATEPART(MM,GETDATE()) AS VARCHAR)
+'/'+CAST(DATEPART(YYYY,GETDATE()) AS VARCHAR)
+' '+CAST(DATEPART(HH,GETDATE()) AS VARCHAR)
+':'+CAST(DATEPART(MI,GETDATE()) AS VARCHAR)

Oracle:

Select to_char(sysdate,'DD/MM/YYYY HH24:MI') from dual

Вы можете написать свою собственную функцию таким образом, чтобы избавиться от этого беспорядка;

http://sql.dzone.com/news/custom-date-formatting-sql-ser

select myshortfun(getdate(),myformat)
GO

Ответ 7

Здесь вам понадобится DATEPART. Вы можете объединить результаты вызовов DATEPART вместе.

Чтобы получить аббревиатуры месяца, вы можете использовать DATENAME; если это не работает для вас, вы можете использовать оператор CASE на DATEPART.

DATEPART также работает для поля времени.

Я могу представить несколько способов получения индикатора AM/PM, включая сравнение новых дат, построенных с помощью DATEPART, или вычисление общих секунд, прошедших за день, и сравнение их с известными порогами AM/PM.

Ответ 8

в MS SQL Server вы можете:

SET DATEFORMAT ymd

год, месяц, день,

Ответ 9

Если вам понадобится нечто более конкретное, например DateKey (yyyymmdd), которое вам нужно для размерных моделей, я предлагаю что-то без каких-либо трансляций/трансляций:

DECLARE @DateKeyToday int = (SELECT 10000 * DATEPART(yy,GETDATE()) + 100 * DATEPART(mm,GETDATE()) + DATEPART(dd,GETDATE()));
PRINT @DateKeyToday

Ответ 10

Я добавляю этот ответ (для себя) как относящийся к настраиваемому форматированию.

Для подчеркивания yyyy_MM_dd

REPLACE(SUBSTRING(CONVERT(VARCHAR, @dt, 120), 1, 10),'-','_')