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

Откуда:
Сообщений: 62
Здравствуйте
такой вопрос
Необходимо каким то образом сформировать и выполнить запрос
специфика его такова
что при выполнение запроса значение поля формируется на основе выполнения функции
однако в теле функции как известно НЕВОЗМОЖНО использовать
работу с временными курсорами или таблицами
и вот встал вопрос каким образом изменить запрос что бы
осуществить множественный выбор на основе различных условий
не прибегая к использованию функции либо можно как нибудь
модифицировать запрос что бы возможно было осуществлять подобный
выбор который указан в функции

ПОнятно что можно осуществлять несколько выборок
сначала допустим сделать Join по одному условию
затем второй запрос по другому условию
(я правда не пробовал, но предполагаю что так получится)
и так постепенно реализуя все условия которые были объявленны в 1 функции
но помоему должен быть какой то более рациональный вариант
вот только какой
для пущей наглядности код :

использование "постоянной" таблицы тоже не желательно

SELECT ##_otkl.koddet, ##_otkl.sh_cex as supcons, ##_otkl.ei,
dbo.get_post_in_otkl(koddet, sh_cex, kod_otkl) as post_nom,
sum(CASE WHEN @RaschDay = or_date THEN CASE WHEN ##_otkl.kod_otkl='01' or ##_otkl.kod_otkl='08' THEN qty ELSE 0000.000 END
ELSE 000000000.000
end) as S_br_d,
sum(CASE WHEN @RaschDay <= or_date THEN CASE WHEN ##_otkl.kod_otkl= '01' or ##_otkl.kod_otkl='08' THEN qty ELSE 0000.000 END
ELSE 000000000.000
end) as s_br_M,
sum(CASE WHEN @RaschDay = or_date THEN CASE WHEN ##_otkl.kod_otkl= '03' THEN qty ELSE 0000.000 END
ELSE 000000000.000
end) as s_def_D,
sum(CASE WHEN @RaschDay <= or_date THEN CASE WHEN ##_otkl.kod_otkl= '03' THEN qty ELSE 0000.000 END
ELSE 000000000.000
end) as s_def_M
FROM ##_otkl
GROUP BY koddet, sh_cex, ei, sh_cex, kod_otkl

также объявленная функция
Create Function get_post_in_otkl (@Koddet varchar(14), @sh_cex varchar(5), @kod_otkl varchar(2) )
RETURNS varchar(5)
AS
BEGIN
Declare @post_nom varchar(5)
SET @post_nom = SPACE(5)
if SUBSTRING (@Koddet, 1, 1 ) = '9'
begin
if @kod_otkl = '01' or @kod_otkl = '08'
begin
DECLARE TmpCurs CURSOR LOCAL FORWARD_ONLY STATIC
FOR SELECT _S_KOMPL.post into rr from _S_KOMPL
WHERE _S_KOMPL.koduzla = @Koddet
AND _S_KOMPL.potreb = @sh_cex
end
else
begin
DECLARE TmpCurs CURSOR LOCAL FORWARD_ONLY STATIC
FOR SELECT _S_KOMPL.post from _S_KOMPL
where _S_KOMPL.koddet = @Koddet
AND _S_KOMPL.potreb = @sh_cex
end
end
else
SELECT _S_KOMPL.post from _S_KOMPL
where _S_KOMPL.koddet = @Koddet
AND _S_KOMPL.potreb = @sh_cex

RETURN @post_nom
END


Подскажите пожалуйста............
19 май 05, 06:16    [1553501]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
Quark
Member

Откуда: Екат
Сообщений: 1099
Чтото мысль не улавливаю(

А dynamic SQL пробовали?
19 май 05, 07:42    [1553565]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
=Sergey==
Member

Откуда:
Сообщений: 62
Quark
Чтото мысль не улавливаю(

А dynamic SQL пробовали?


ну смысл в том что

SELECT Table1.*,
dbo.get_post_in_otkl(koddet, sh_cex, kod_otkl) as post_nom
.......


а в самой функции
выполняются уже какие то преобразования по определенным условиям
такой вариант срабатывыл в Foxpro
когда объявленную функцию использвали для формирования значения поля
она и час работает но ограничения t-sql что в функции не возможно работать с временными таблицами курсорами и т.д
вот и вопрос как реализовать подобное допустим без использования функции или с использованием но тогда что бы в функции осуществлялась работа с временными наборами данных
19 май 05, 08:19    [1553611]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
Quark
Member

Откуда: Екат
Сообщений: 1099
ИМХО
автор
ПОнятно что можно осуществлять несколько выборок
сначала допустим сделать Join по одному условию
затем второй запрос по другому условию

В SQL и есть более рациональный вариант.
Усложнение функции очень сильно скажется на производительности.
19 май 05, 08:28    [1553623]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
=Sergey==
Member

Откуда:
Сообщений: 62
ну вот пока я слабо знаком с возможностями и особенностями T-SQL

вот какой может быть вариант
в реализации поставленной задачи средствами SQL что бы сделать вариант по куче условий которые можно было бы не обработать в функции
19 май 05, 08:40    [1553656]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Постановка задачи абсолютно непонятна. Абракадабра какая-то. Поэтому отвечу на единственный вопрос, который понятен из всего топика:

=Sergey==
что бы в функции осуществлялась работа с временными наборами данных

В функциях вместо временных таблиц
create table #t(...)
можно использовать табличные переменные
declare @t table (...)

Прочая работа с ними почти идентична временным таблицам.
19 май 05, 10:49    [1554171]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
=Sergey==
Member

Откуда:
Сообщений: 62
я конечно извинясь,
может я не четко формулирую но попробую в последний раз:

1. есть некий запрос
SELECT ##_otkl.koddet, ##_otkl.sh_cex as supcons, ##_otkl.ei,
dbo.get_post_in_otkl(kod_otkl) as post_nom,
FROM ##_otkl
GROUP BY koddet, sh_cex, ei, sh_cex, kod_otkl

как видно поле post_nom формируется за счет возвращенного значения
функции get_post_in_otk

Далее смотрим реализацию функции (чисто для пояснения самой логики, которую я пытаюсь объяснить, привожу код )

Create Function get_post_in_otkl (@kod_otkl varchar(2) )
RETURNS varchar(5)
AS
BEGIN
Declare @post_nom varchar(5)
SET @post_nom = SPACE(5)
if SUBSTRING (@kod_otkl , 1, 1 ) = '9'
begin
if @kod_otkl = '01' or @kod_otkl = '08'
begin
RETURN '0'
end
else
begin
RETURN '1'
end
end
else
RETURN '3'
END

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

или вообще отказаться от использования функций изменив запрос но как ? я не знаю


я думаю так понятнее
19 май 05, 11:37    [1554453]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Работайте с таблицами-переменными вместо временных таблиц.
19 май 05, 12:12    [1554690]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
TaiNe
Member

Откуда:
Сообщений: 123
SELECT o.koddet, o.sh_cex as supcons, o.ei, 
	dbo.get_post_in_otkl(koddet, sh_cex, kod_otkl) as post_nom,
	S_br_d = sum(CASE WHEN @RaschDay = or_date and o.kod_otkl in('01','08')
			THEN qty 
			ELSE 0 END) ,
	s_br_M = sum(CASE WHEN @RaschDay <= or_date and o.kod_otkl in('01','08')
			THEN  qty 
			ELSE 0 END) ,
	s_def_D = sum(CASE WHEN @RaschDay = or_date and o.kod_otkl= '03'
			THEN qty 
			ELSE o END) ,
	s_def_M = sum(CASE WHEN @RaschDay <= or_date and o.kod_otkl= '03'
			THEN qty 
			ELSE 0)
FROM ##_otkl o
GROUP BY koddet, sh_cex, ei, sh_cex, kod_otkl

--также объявленная функция 
Create Function get_post_in_otkl (@Koddet varchar(14), @sh_cex varchar(5), @kod_otkl varchar(2) )
RETURNS varchar(5) 
AS 
BEGIN 
Declare @post_nom varchar(5)

declare table @tt(post varchar(10))

insert into @tt
select post 
from _S_KOMPL 
where koddet = @Koddet
	AND potreb = @sh_cex 
union all
select post 
from _S_KOMPL 
where koduzla = @Koddet
	AND potreb = @sh_cex

SELECT @post_nom = max(a.post)
from @tt

RETURN @post_nom
END 
19 май 05, 12:14    [1554698]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
=Sergey==
Member

Откуда:
Сообщений: 62
спасибо большое
а еще вопрос
S_br_d = sum(CASE WHEN @RaschDay = or_date and o.kod_otkl in('01','08')
			THEN qty 
			ELSE 0 END) ,

вообще как определяется формат поля S_br_d (длина, точность)
это к тому что допустим 1 запись будет 1000
а вторая 1000.55 и если формат поля (точность) задается по 1 записи то 0.55 теряется
вот как задать формат поля при ее создание (не используя Create Table)
как вообще сервер обрабатывает данную ситуацию ???
(просто из опыта ФоксПро приходилось использовать преобразование что получить необходимый формат и не потеряло точность)
19 май 05, 13:03    [1554999]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
В любых сомнительных случаях используйте CAST или CONVERT, что заставит сервер привести именно к тому типу (с той длиной/точностью), что вы скажете. И не будет никаких неоднозначностей.
19 май 05, 13:16    [1555099]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
=Sergey==
Member

Откуда:
Сообщений: 62
и еще вопрос если все таки в функции необходимо выбрать из временного набора данных как например

Create Function get_post_in_otkl (@Koddet varchar(14), @sh_cex varchar(5), @kod_otkl varchar(2) )
RETURNS varchar(5) 
AS 
BEGIN 
Declare @post_nom varchar(5)

declare table @tt(post varchar(10))

insert into @tt
select post 
from #_S_KOMPL 
where koddet = @Koddet
	AND potreb = @sh_cex 
union all
select post 
from #_S_KOMPL 
where koduzla = @Koddet
	AND potreb = @sh_cex

SELECT @post_nom = max(a.post)
from @tt

RETURN @post_nom
END 
то опять ругается на невозможность данной реализации

как быть подскажите ??
просто в приведенном выше госп-ном TaiNe
выборка осуществляется из (насколько я понял ) статичной таблицы а создавать и замусоривать БД не хотелось бы

если выбирать из @S_KOMPL то она должна быть объявлена в теле функции
(и понятно что будет то же самое данные все равно находятся во временном наборе)
19 май 05, 13:32    [1555219]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
TaiNe
Member

Откуда:
Сообщений: 123
Во-первых в Вашем примере как раз шла выборка из постоянной таблицы. Я просто Ваш пример переделалаю
Во-вторых, поймите, функция по сути является вьюшкой. И поэтому у нее все те же ограничения что и у вьюшки. Вы никак не сможете использовать временную таблицу.
Ну, и в-третьих. Госпожа. :)
19 май 05, 15:37    [1555972]     Ответить | Цитировать Сообщить модератору
 Re: Реализация запроса с функцией  [new]
Glory
Member

Откуда:
Сообщений: 104760
как быть подскажите ??
Почему сразу на момент заполнения временной таблицы не использовать функцию, которая формирует ваш код ?

select ... dbo.get_post_in_otkl(koddet, sh_cex, kod_otkl) as xxx
into ##_otkl
from ...
19 май 05, 16:01    [1556103]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить