Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Тип возвращаемого значения при обработке выражений  [new]
sanitar
Member

Откуда:
Сообщений: 66
Добрый день. Проблема в следующем.
Считываю из xml выражение типа (1+360/3). Это выражение мне нужно обработать и получить float на выходе.

Проблема в том что
  select (1+360/100)

Вернет целое 4

Пробовал так
  select 1.0*(1+360/100)

Вернет то же 4, что логично. Вопрос как без парсинга строки вернуть FLOAT? Заранее какое выражение лежит внутри xml не известно. Теоретически любое выражение.
13 апр 18, 10:34    [21335731]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
sanitar,

CAST()
13 апр 18, 10:36    [21335739]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
Приоритет типов данных
13 апр 18, 10:38    [21335745]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
sanitar
Member

Откуда:
Сообщений: 66
Чтобы сделать CAST надо ведь парсить выражение!

select CAST((1+360/100) as FLOAT)

выдаст ровно 4.0

Вот это выражение
select (1+CAST(360 as FLOAT)/100)

даст 4.6, но чтобы его выполнить нужно парсить строку на составляющие!
13 апр 18, 10:41    [21335752]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
court
Member

Откуда:
Сообщений: 1956
sanitar,

как вы из такого, например xml-я
declare @xml xml='<a>1+360/100</a>'

получаете этот select
select (1+360/100)

?

Динамик СКЛ ?
13 апр 18, 10:45    [21335765]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
sanitar
Member

Откуда:
Сообщений: 66
court,

делаю проход по таблице и обрабатываю через sp_executesql чтобы посчитать значение выражения но из-за типов на выходе имею не то что нужно.
13 апр 18, 10:52    [21335787]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
court
Member

Откуда:
Сообщений: 1956
sanitar
court,

делаю проход по таблице и обрабатываю через sp_executesql чтобы посчитать значение выражения но из-за типов на выходе имею не то что нужно.
ясно, тогда функция вам сильно не навредит :)
+ fnEval
create FUNCTION [dbo].[fnEval]
(
	@txt		varchar(4000)		
)
RETURNS varchar(8000) 
as
begin
	declare @Result varchar(8000)
	declare @object int, @object2 int
	declare @hr int

	set @txt='<body><script>document.write(' + @txt + ');</script></body>'

	exec @hr=sp_OACreate 'HTMLfile', @object out
	exec @hr=sp_OAMethod @object, 'write', null, @txt
	exec @hr=sp_OAGetProperty @object, 'body', @object2 out 
	exec @hr=sp_OAGetProperty @object2, 'innerText', @Result out 

	exec @hr=sp_OADestroy @object2
	exec @hr=sp_OADestroy @object
	
	return @Result 
end


declare @xml xml='<a>1+360/100</a>'

select 
	txt	=t.c.value('text()[1]','varchar(100)')	
	,res	=[dbo].[fnEval](t.c.value('text()[1]','varchar(100)'))
from @xml.nodes('a') as t(c)


txtres
1+360/1004.6
13 апр 18, 10:56    [21335817]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
sanitar
Member

Откуда:
Сообщений: 66
court,

Создавать OLE объекты внутри функции? Мне кажется это перебор. Может как-то можно проще все-таки.
13 апр 18, 11:13    [21335891]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
dies irae
Member

Откуда:
Сообщений: 78
court,

изобретательно, только работать это будет не особо быстро

Если скорость всё-таки важна - я бы пошёл по следующему пути:
запилил бы .net сборку с функциями работы с регулярными выражениями (она вообще не помешает и может понадобиться для многих других задач)
и добавлял бы с её помощью ко всем целым числам .0

Если версия 2017 и выше - можно через python - скрипт, там результат деления целых чисел изначально дробный
13 апр 18, 11:16    [21335906]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
Собственно говоря, всё портит именно целочисленное деление.
Может, просто тупо заменить "/" на "*1./" ??
13 апр 18, 11:24    [21335938]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
iap
Собственно говоря, всё портит именно целочисленное деление.
Может, просто тупо заменить "/" на "*1./" ??
DECLARE @SQL NVARCHAR(MAX)=N'SELECT (1+360/100)';
EXECUTE(@SQL);
SET @SQL=REPLACE(@SQL,'/','*1.0/');
EXECUTE(@SQL);
13 апр 18, 11:27    [21335955]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
iap
iap
Собственно говоря, всё портит именно целочисленное деление.
Может, просто тупо заменить "/" на "*1./" ??
DECLARE @SQL NVARCHAR(MAX)=N'SELECT (1+360/100)';
EXECUTE(@SQL);
SET @SQL=REPLACE(@SQL,'/','*1.0/');
EXECUTE(@SQL);
0, конечно, лишний:
DECLARE @SQL NVARCHAR(MAX)=N'SELECT (1+360/100)';
EXECUTE(@SQL);
SET @SQL=REPLACE(@SQL,'/','*1./');
EXECUTE(@SQL);
13 апр 18, 11:29    [21335964]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
dies irae
Member

Откуда:
Сообщений: 78
iap,
ну или так)

отличный вариант, если конечно t-sql-подобных комментариев не будет в выражении /**/
13 апр 18, 11:42    [21336019]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
sanitar
Member

Откуда:
Сообщений: 66
iap,

Спасибо, наверное так пойдет.
REPLACE(@expr, '/',*1.0/)
13 апр 18, 11:53    [21336072]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
court
Member

Откуда:
Сообщений: 1956
навсякий, ещё такой "ход конём" )
declare @txt nvarchar(100)='1+360/100'
declare @SQL nvarchar(max)='set @res=(select xz from OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',''C:\Temp\test.accdb'';''Admin'';'''',''select '+@txt+' as xz''))'
declare @res float

--print @SQL

--
exec sp_executesql @SQL, N'@res float out', @res=@res out   
select @res as res

res
4,6


Но тут и провайдер нужно, что бы был установлен, и "праздно" валяющийся на сервере файлик Акцесса потребуется, и выражение, что бы было "знакомо" Jet-SQL ... :(
13 апр 18, 12:06    [21336129]     Ответить | Цитировать Сообщить модератору
 Re: Тип возвращаемого значения при обработке выражений  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
sanitar
Вопрос как без парсинга строки вернуть FLOAT?
+ Не надо боятся парсинга
use tempdb;
go

create function dbo.fnConvertExpression
(
 @e varchar(max)
)
returns table
as
return (
 with t as
 (
  select
   b.p, stuff(a.s, b.p + 1, 0, 'e0') as s, 1 as n
  from
   (select @e + '_') a(s) cross apply
   (select patindex('%[0-9][^0-9.]%', a.s)) b(p)
  where
   b.p > 0

  union all

  select
   t.p + a.p + 5, stuff(t.s, t.p + a.p + 5, 0, 'e0'), n + 1
  from
   t cross apply
   (select patindex('%[0-9][^0-9.]%', substring(t.s, t.p + 5, cast(0x7fffffff as int)))) a(p)
  where
   a.p > 0
 )
select top (1)
 left(s, len(s) - 1) as expression
from
 t
order by
 n desc
);
go

declare @s varchar(100) = '(1+360/100)';

select @s;
exec('select ' + @s);

select @s = expression from dbo.fnConvertExpression(@s);
select @s;
exec('select ' + @s);
go

drop function dbo.fnConvertExpression;
go
13 апр 18, 13:39    [21336610]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить