Начало » Использование СУБД » Microsoft SQL Server » Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) (Нужен совет сообщества.)
Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2927] |
Mon, 07 August 2023 10:28 |
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: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2929 является ответом на сообщение #2928] |
Mon, 07 August 2023 11:06 |
Sanek
Сообщений: 8 Зарегистрирован: August 2023
|
Junior Member |
|
|
Если "вообще", то да, можно определить табличную переменную/собственный табличный тип данных , засунуть туда данные и потом отдельно вызвать запрос SearchQueryExt
, но, как я говорил в вопросе: список объектов для расчёта прав появляется в результате запроса "SearchQueryExt" и хотелось бы не разбивать CTE запрос, потому, что он только в примере простой, в реальной жизни он на три страницы )
[Обновления: Mon, 07 August 2023 11:06] Известить модератора
|
|
|
|
|
|
|
|
|
|
|
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2951 является ответом на сообщение #2938] |
Tue, 08 August 2023 08:52 |
Sanek
Сообщений: 8 Зарегистрирован: August 2023
|
Junior Member |
|
|
нет, спасибо, пример не нужен. Идея хорошая. Но по сути она не отличается от использования табличной переменной.
и запрос разбивается на 2 части ..
в целом по этому пути и пошел ...
я тут спросил в надежде, что может я чего не знаю и что-то уже новое придумали ))
(давно в документацию не заглядывал)
А что касается outer apply - это функция, которая вызывается на каждую строку (и это в лучшем случае) выборки, что не добавляет производительности (.
подобные методы очень удобны, но крайне вредны ... довольно много условий необходимо соблюсти, что бы их использовать.
Спасибо всем принявшим участие!
[Обновления: Tue, 08 August 2023 08:55] Известить модератора
|
|
|
|
|
Re: Запрос + представление или функция, как лучше сделать?* (Задача со звездочкой) [сообщение #2954 является ответом на сообщение #2953] |
Tue, 08 August 2023 13:31 |
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] Известить модератора
|
|
|
|
Переход к форуму:
Текущее время: Thu Nov 21 16:05:40 GMT+3 2024
Общее время, затраченное на создание страницы: 0.00798 секунд
|