SQLRU.net
Разработка приложений баз данных

Начало » Использование СУБД » Microsoft SQL Server » Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) (Нужен совет сообщества.)
Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2927] Mon, 07 August 2023 10:28 Переход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
Наткнулся на следующую проблему ...
Дано:
Есть представление, которое очень сложным образом раcсчитывает галочку "можно, нельзя" для каждого объекта.
Есть CTE запрос, который поделен на блоки вроде 1й блок - найти все нужные объекты, 2й - расчитать можно или нет их показывать (обращаясь к представлению) и 3й - вывод.

Что не работает:
представление считает разрешения для всей базы, но на текущий момент появилось такое кол-во записей о правах, что представление тупо зависает, пытаясь это дело обработать.

Моё решение
Появилась мысль из представления сделать функцию и передать в нее параметры , ограничивающие кол-во обрабатываемых записей, тогда функция будет работать. Но проблема в том, что список объектов, для которых надо рассчитать доступ появляется только в 1м блоке запроса.
По этой причине мне как-то надо засунуть результат запроса в параметр функции и все это в CTE )))

Вопроса два:
1. Возможно ли это реализовать (и как)
2. Может есть другой путь?

Пример кода:

Представление (естественно пример для понимания)

Create view Accesses as 
Select ObjectId from AccessTable where Allow=1

Запрос:

With SearchQuery AS (
Select ObjectId from Table1 where ...
) , SearchQueryExt (
Select * from SearchQuery 
union Select ObjectId from Table2 where .... 
union Select ObjectId from Table3 where ....
), FilterQuery (
Select * 
   fom SearchQueryExt s 
  join Accesses a on a.ObjectId = s.ObjectId
)
Select * 
  from TableN s
  join FilterQuery f on s.ObjectId = f.ObjectId

Я же хочу сделать функцию что бы было так:

Create function Accesses (ObjctIds ????)
Select ObjectId 
  from AccessTable 
 where ObjetId in ObjctIds 
   and Allow=1

А FilterQuery  поменять на что-то вроде :

.
.
.
), FilterQuery (
Select * 
   fom SearchQueryExt s 
  join dbo.fAccesses(select ObjectId from SearchQuery) on a.ObjectId = s.ObjectId
)
.
.
.

Есть мысли, как это реализовать ?
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2928 является ответом на сообщение #2927] Mon, 07 August 2023 11:00 Переход к предыдущему сообщениюПереход к следующему сообщению
BlackEric в настоящее время не в онлайне  BlackEric
Сообщений: 294
Зарегистрирован: June 2022
Senior Member
Передать список ID в функцию? Через табличную переменную можно.
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2929 является ответом на сообщение #2928] Mon, 07 August 2023 11:06 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
Если "вообще", то да, можно определить табличную переменную/собственный табличный тип данных , засунуть туда данные и потом отдельно вызвать запрос SearchQueryExt
, но, как я говорил в вопросе: список объектов для расчёта прав появляется в результате запроса "SearchQueryExt" и хотелось бы не разбивать CTE запрос, потому, что он только в примере простой, в реальной жизни он на три страницы )

[Обновления: Mon, 07 August 2023 11:06]

Известить модератора

Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2930 является ответом на сообщение #2929] Mon, 07 August 2023 11:54 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 799
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
не надо усложнять сложное.
декомпозиция в данном случае самое то.
зы: согласен с BlackEric.
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2931 является ответом на сообщение #2930] Mon, 07 August 2023 12:31 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
Возможно вы и правы ... а жаль, было бы очень эстетичное решение (
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2932 является ответом на сообщение #2931] Mon, 07 August 2023 12:41 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 799
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
вам шашечки, или таки ехать? ©
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2933 является ответом на сообщение #2932] Mon, 07 August 2023 13:32 Переход к предыдущему сообщениюПереход к следующему сообщению
shigor в настоящее время не в онлайне  shigor
Сообщений: 26
Зарегистрирован: March 2023
Географическое положение: НиНо
Junior Member
outer apply
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2934 является ответом на сообщение #2933] Mon, 07 August 2023 13:54 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
shigor писал(а) Mon, 07 August 2023 13:32
outer apply
Если Вы хотели сказать что-то по делу, то я Вас не понял (
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2935 является ответом на сообщение #2934] Mon, 07 August 2023 14:57 Переход к предыдущему сообщениюПереход к следующему сообщению
shigor в настоящее время не в онлайне  shigor
Сообщений: 26
Зарегистрирован: March 2023
Географическое положение: НиНо
Junior Member
если Вы хотели объединить результат запроса с вызовом функции возвращающей табличный результат, то для этого есть тип соединения outer apply
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2936 является ответом на сообщение #2935] Mon, 07 August 2023 15:14 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
shigor писал(а) Mon, 07 August 2023 14:57
если Вы хотели объединить результат запроса с вызовом функции возвращающей табличный результат, то для этого есть тип соединения outer apply
Вот теперь понял! ))

Я хотел результат одного из запросов в CTE запросе засунуть в параметры функции или что-то подобное ...

но всё равно, спасибо за попытку.

[Обновления: Mon, 07 August 2023 15:14]

Известить модератора

Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2938 является ответом на сообщение #2936] Mon, 07 August 2023 15:33 Переход к предыдущему сообщениюПереход к следующему сообщению
shigor в настоящее время не в онлайне  shigor
Сообщений: 26
Зарегистрирован: March 2023
Географическое положение: НиНо
Junior Member
напишите функцию, которая делает расчет по одному объекту, и свяжите ее с выборкой через outer apply.

если вот прям вообще никак, то как вариант сделать через xml.
первый cte генерит список идентификаторов в xml, последующий cte вызывает функцию с xml параметром.
сама функция парсит xml в табличную переменную и работает с ней.
пример накидать?

[Обновления: Mon, 07 August 2023 15:35]

Известить модератора

Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2951 является ответом на сообщение #2938] Tue, 08 August 2023 08:52 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
нет, спасибо, пример не нужен. Идея хорошая. Но по сути она не отличается от использования табличной переменной.
и запрос разбивается на 2 части ..
в целом по этому пути и пошел ...

я тут спросил в надежде, что может я чего не знаю и что-то уже новое придумали ))
(давно в документацию не заглядывал)

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

Спасибо всем принявшим участие!

[Обновления: Tue, 08 August 2023 08:55]

Известить модератора

Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2952 является ответом на сообщение #2951] Tue, 08 August 2023 12:26 Переход к предыдущему сообщениюПереход к следующему сообщению
shigor в настоящее время не в онлайне  shigor
Сообщений: 26
Зарегистрирован: March 2023
Географическое положение: НиНо
Junior Member
по сути - нет, по использованию - да.
табличную переменную нельзя объявить в самом запросе или в представлении, это будет уже скрипт.
в случае с xml как раз можно, что позволяет все оформить в виде представления.
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2953 является ответом на сообщение #2952] Tue, 08 August 2023 12:33 Переход к предыдущему сообщениюПереход к следующему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
shigor писал(а) Tue, 08 August 2023 12:26
по сути - нет, по использованию - да.
табличную переменную нельзя объявить в самом запросе или в представлении, это будет уже скрипт.
в случае с xml как раз можно, что позволяет все оформить в виде представления.
Если не затруднит, могли бы Вы привести пример?
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2954 является ответом на сообщение #2953] Tue, 08 August 2023 13:31 Переход к предыдущему сообщениюПереход к следующему сообщению
shigor в настоящее время не в онлайне  shigor
Сообщений: 26
Зарегистрирован: March 2023
Географическое положение: НиНо
Junior Member
выполнить можно полностью, можно отдельными кусками

use tempdb
go

-- создание функции обработки списка
create function fn_get_olist(@olist xml)
returns table as return (
  select 
    olist.object.value('./@o_id', 'integer') as o_id,
    'Идентификатор объекта ' + try_cast(olist.object.value('./@o_id', 'integer') as varchar(10)) as o_newname
  from @olist.nodes('/olist/object') olist(object)
)
go

-- запрос, и это не скрипт.. его можно оформить в виде представления
;with 
   -- полный список объектов
   o_list as ( select * from (values (0, 'object 0'), (1, 'object 1'), (2, 'object 2'), (3, 'object 3'), (4, 'object 4')) v(o_id, o_name)  )
   -- ограниченный список объектов
 , o_list_selected as ( select * from o_list where (o_id % 2) = 0 )
   -- ограниченный список объектов в формате xml
 , o_list_selected_xml as ( select (select (select o_id [@o_id] from o_list_selected for xml path('object'), type) olist for xml path(''), type) olist )
 -- вызов функции с ограниченным списком объектов и получением раcчетных результатов из функции
 select o_id, o_newname from o_list_selected_xml outer apply fn_get_olist(olist) 

go

-- подчистим
drop function fn_get_olist

[Обновления: Tue, 08 August 2023 13:32]

Известить модератора

Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2955 является ответом на сообщение #2954] Tue, 08 August 2023 14:04 Переход к предыдущему сообщению
Sanek в настоящее время не в онлайне  Sanek
Сообщений: 8
Зарегистрирован: August 2023
Junior Member
Огонь! То, что я искал! Спасибо!
Предыдущая тема: Сложный поиск соответствия.
Следующая тема: Группа доступности Always ON MS SQL
Переход к форуму:
  


Текущее время: Sat Apr 27 11:10:44 GMT+3 2024

Общее время, затраченное на создание страницы: 0.00798 секунд