powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Форматирование decimal(31, 15) в строку на стороне сервера
9 сообщений из 9, страница 1 из 1
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717382
WinterGraveyard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ситуация: в клиентской программе на дельфи (RAD Studio 2010) нужно отображать значения типа decimal(31, 15), полностью отображая все знаки после запятой (все 15). Как выяснилось, сделать это, передавая на клиент значения как есть (именно decimal(31,15)) невозможно: при отключенной опции EnableBCD значения передаются как double, и ряд значений при заданной маске отображения 15 знаков приобретают в дробной части хвост, которого на самом деле нет - видимо, это связано с потерей точности при прееобразовании в double по IEEE-754. Если включить опцию EnableBCD, значения передаются как binary-coded decimal (собственно, BCD), но обычный BCD (TBCDField) производит округление до формата currency (до 3 знаков), что неприемлемо. А значения типа TFMTBCD (TFMTBСDField), где округление не производится, используемая версия библиотеки доступа к данным (DevArt SDAC) не поддерживает.
Ввиду всего вышеизложенного было принято решение форматировать decimal(31,15) в varchar на сервере. Требования: 15 знаков после запятой, разделитель дробной и целой частей запятая, разделитель разрядов целой части пробел. Сервер - 2005-й.
Была написана вот такая функция:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
CREATE FUNCTION [DBO].[UF_FORMAT_DECIMAL](@D DECIMAL(31,15))
RETURNS TABLE
AS RETURN
WITH CTE AS (
	SELECT @D N
)
SELECT F1.Z+LTRIM(F3.D)+F2.A RESULT
FROM CTE E
CROSS APPLY (
	SELECT
		CASE WHEN CONVERT(VARCHAR, E.N) LIKE '-%' THEN '-' ELSE '' END,
		SUBSTRING(
			REPLACE(CONVERT(VARCHAR, E.N), '.', ','),
			CASE WHEN CONVERT(VARCHAR, E.N) LIKE '-%' THEN 2 ELSE 1 END,
			LEN(CONVERT(VARCHAR, N))
		)
) F1(Z,S)
CROSS APPLY (
	SELECT
		SUBSTRING(F1.S, 1, CHARINDEX(',', F1.S)-1),
		SUBSTRING(F1.S, CHARINDEX(',', F1.S), LEN(F1.S))
) F2(B, A)
CROSS APPLY (
	SELECT
		SUBSTRING(F2.B, LEN(F2.B)-17, 3)
		+' '+SUBSTRING(F2.B, LEN(F2.B)-14, 3)
		+' '+SUBSTRING(F2.B, LEN(F2.B)-11, 3)
		+' '+SUBSTRING(F2.B, LEN(F2.B)-8, 3)
		+' '+SUBSTRING(F2.B, LEN(F2.B)-5, 3)
		+' '+SUBSTRING(F2.B, LEN(F2.B)-2, 3)
) F3(D)
GO


Вроде бы работает вполне нормально, но, может, здесь можно что-то подкрутить в плане лаконичности, быстродействия, итд?
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717635
iiyama
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,
Прошу прощения за небольшой оффтопик(тк без анализа ф-ции),
не проще ли просто 2-мя int-ами отдать (целая и дробная часть) и форматировать все же на клиенте?
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717697
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iiyamaWinterGraveyard,
Прошу прощения за небольшой оффтопик(тк без анализа ф-ции),
не проще ли просто 2-мя int-ами отдать (целая и дробная часть) и форматировать все же на клиенте?Простым intом не получится - у него не более 10 знаков
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717731
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,

я бы написал CLR функцию для таких целей.
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717733
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyardформатировать decimal(31,15) в varchar на сервере. Требования: 15 знаков после запятой, разделитель дробной и целой частей запятая, разделитель разрядов целой части пробел. Сервер - 2005-й.

если вдруг окажется сервер 2012 :)
Код: sql
1.
2.
declare @d decimal(31,15) = -1234567890123456.123456789012345
select format(@d, 'n15', 'ru')  
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717896
Massa52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,
Код: sql
1.
2.
declare @d decimal(31,15) = -1234567890123456.543210987654321
select cast(@d AS bigint), cast((@d - cast(@d AS bigint)) * 1000000000000000 AS bigint) 
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717912
WinterGraveyard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Massa52WinterGraveyard,
Код: sql
1.
2.
declare @d decimal(31,15) = -1234567890123456.543210987654321
select cast(@d AS bigint), cast((@d - cast(@d AS bigint)) * 1000000000000000 AS bigint) 


Нет, спасибо, передавать клиенту два значения вместо одного, и потом собирать из них одно в средствах отображения (DevExpress QuantunGrid/FastReports) - это намного больше возни, чем отформатировать значение на сервере (к тому же выборки в контексте данной задачи небольшие, и вряд ли такие преобразования сильно нагрузят сервер).
Владислав КолосовWinterGraveyard,
я бы написал CLR функцию для таких целей.
Отпадает - по каким-то причинам администраторы не хотят возиться с хостингом CLR-сборок на сервере.
Shakillесли вдруг окажется сервер 2012 :)
Да, спасибо, я в курсе, но есть только то, что есть. И насколько я понимаю вот это
авторFORMAT relies on the presence of the .NET Framework Common Language Runtime (CLR).
эта функция и является оберткой над дотнетовским форматированием (и использует дотнетовские форматы).
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717915
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,

Практический вопрос: судя по тому, что вы разделяете разряды пробелом, это число требуется просто для отображения? Может проще его передавать строкой в клиент и там уже как строку форматировать? Сдается мне на Дельфи это гораздо короче получится (не уверен).
...
Рейтинг: 0 / 0
Форматирование decimal(31, 15) в строку на стороне сервера
    #39717918
Massa52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,
Кстати - ваша функция не работает для значения -1234567890123456.543210987654321
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Форматирование decimal(31, 15) в строку на стороне сервера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]