powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Использование Table-valued UDF в запросе
8 сообщений из 8, страница 1 из 1
Использование Table-valued UDF в запросе
    #32030018
Sergey Makarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Есть у меня таблица пользователей Users. Во множестве мест мне нужно показать имя пользователя, его компанию, CompanyName и CompanyID. В зависимости от типа пользователя его компания может быть - поставщиком, заказчиком, агентом и т.д - т.е. имя компании нужно искать в разных таблицах. Рещил я написать Table-valued функцию, которая по UsersID будет возвращать нужные мне данные. Написал. Работает

SELECT C.* FROM dbo.fun_getCompanyInfoByUsersID(294403) C

Получаю CompanyID, CompanyName, UserName

Далее вопрос - пытаюсь вывести все записи из Users а также результат работы этой функции для каждой строки -


SELECT UsersID, G.* FROM Users, dbo.fun_getCompanyInfoByUsersID(UsersID) G

Получаю:

Server: Msg 155, Level 15, State 1, Line 6
'UsersID' is not a recognized OPTIMIZER LOCK HINTS option.


SELECT UsersID, G.* FROM Users, dbo.fun_getCompanyInfoByUsersID(101) G
Такая конструкция ощибку не выдает - но информацию выводит только о UsersID 101, т.е. проблема - как увязать работу фенкции с каждой строкой таблицы Users

Как побороть, подскажите.
спасибо.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030022
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения, что не по существу вопроса, но всех поставщиков, покупателей, страховщиков, агентов, взяткополучателей, вымогателей и прочих контактеров нужно помещать в таблицу КОНТРАГЕНТЫ, тогда такие проблемы просто не будут возникать.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030025
Sergey Makarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, я присоединился к этоиу проекту через пол года после его начала, так что кардинально менять структуру базы у меня возмодгости нет. А на счет одной таблицы - тут можно спорить - все же поставщики, клиенты, агенты, агенства есть разные сущности с разными наборами аттрибутов. И запихивать их в одну таблицу особого сиысла я не вижу.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030030
Фотография jimmers
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В запросе Вам придется использовать scalar UDF, а не table-valued UDF.
Для этого необходимо будет разбить fun_getCompanyInfoByUsersID на три
UDF функции: fun_getCompanyIDByUsersID, fun_getCompanyNameByUsersID,
fun_getUserNameByUsersID, каждая из которых есть скалярная функция.

Запрос может выглядеть так:

\nSELECT u.*,
dbo.fun_getCompanyIDByUsersID(u.UsersID),
dbo.fun_getCompanyNameByUsersID(u.UsersID)
dbo.fun_getUserNameByUsersID(u.UsersID)
FROM Users u


P.S. Не могу судить, не имея схемы, но не исключено, что Вам могло
бы сильно облегчить задачу создание представления, объединяющего
таблицы Поставщики, Заказчики, Агенты..
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030032
Sergey Makarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это как раз первое, что я сделал. Однако мне не совсем нравится, что за CompanyID и CompanyName я хожу дважды к одним и тем же таблицам - думаю это совсем не эффективно. (Функция определяет тип пользователя,потом открывает нудную таблицу и возврашает значение). А в песпективе мне похоже придется еще одно значение добывать, причем сам процесс довольно муторный. Потому я и озаботился вопросом как можно вернуть сразу несколько значений (один раз прочитать все что нужно и вернуть) - потому и пробую прикрутить табличную функцию.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030045
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Функции могут возвращать либо скалярные значения , либо наборы данных (грубо говоря, таблицы). В первом случае их можно использовать в секции перечисления полей, в конструкции WHERE и т.п., но нельзя использовать в конструкции FROM. Вторые как раз используются в конструкции FROM. Вы пытаетесь использовать функцию в разделе FROM:
> SELECT UsersID, G.* FROM Users, dbo.fun_getCompanyInfoByUsersID(UsersID) G
Исходя из этого можно заключить, что функция возвращает набор данных, а не скалярное значение. Однако, по фразе "Функция определяет тип пользователя,потом открывает нудную таблицу и возврашает значение" можно заподозрить, что функция возвращает скалярное значение, а не набор данных. И, следовательно, фигурировать в разделе FROM не должна. Если предположение верное, для меня большая загадка, как может работать приведенная вами конструкция "SELECT C.* FROM dbo.fun_getCompanyInfoByUsersID(294403) C".
Пожалуйста, уточните, какого типа данные возвращаются функцией.

И еще... (для общего развития ).
Если функция таки возвращает набор данных, то делать она это может двумя способами. Первый способ - объявление внутри функции каких-то переменных, конструкций, содержащих более одного оператора и т.п. превращают ее в родственника хранимой процедуры. Второй способ - помещение всего тела функции в оператор Return в виде параметризованного Select. Использование второго способа делает функцию родственником не хранимой процедуры, а VIEW (только параметризованного). Функции второго типа называют Inline-функциями, и MS подчеркивает их отличие от НЕ Inline-фунцкий.
Где это только возможно, я стараюсь использовать именно Inline-функции. При их оптимизатор запросов имеет возможность встроить план выполнения функции в общий план выполнения запроса с учетом фильтров, находящихся вне функции. Например, запрос
select * from MyUDF() where ID=5
будет выполняться по Inline-функции просто влёт, даже если в "голом" виде MyUDF() возвращает 10000000000000 записей. Просто потому, что условие WHERE ID=5 "поднимется" по плану выполнения функции и накладывает этот фильтр на этапе выборки данных из таблицы, причем для наложения фильтра "догадывается" применить кластерный индекс. При использовании же НЕ Inline-функции сначала вы сходите попить пивка, потом, вернувшись из пивной - попьете кофейку, потом начнете сильно нервничать, пока ваша функция будет извлекать из таблицы никому не нужные 10000000000000 записей для того лишь, чтобы потом выбрать из них одну-единственную.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030050
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Полностью согласен с Garya. Хотелось бы добавить, что ко всему прочему не Inline-функция по производительности всегда будет ниже хотя бы потому, что данные в ней сначала будут впихиваться в некую таблицу, а операция вставки всегда медленнее, чем просто выборка. Плюс таблица эта обьявляется как переменная и не думаю, что впихивать в нее большие обьемы данных хорошая идея. Далее еще ождно замечание: UDF-функции в виде параметра могут получать только константу или переменную. Вы же пытаетесь впихнуть в функцию поле UsersID с таблицы Users. Такой номер не пройдет. В данном случае получается Вам нужен вьювер, а не функция, который просто соединяется inner join с таблицей Users. Насчет хождения дважды за CompanyName тоже вопрос спорный - соптимизируйте свой вьювер - используйте вложенные подзапросы, где возвращаються по юзерам только ключ CompanyID, а на верхнем уровне уже происходит обьединение с Company.
...
Рейтинг: 0 / 0
Использование Table-valued UDF в запросе
    #32030066
Sergey Makarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо всем за коментарии. Функция у меня табличная. Не in-line - поскольку сделать все что нужно в параметеризированном запросе в RETURN увы не получается. Как я уже писал - выборка должна идти из разных таблиц в зависимости от типа User. Сделать viewшку - очень монстрообразно получается - эдакая навороченная снежинка. Вообщем с table function у меня ничего не выйдет, поскольку в качестве параметра должна быть только константа или переменная. Т.е. способа связать таблиу и функцию впредикате FROM нет. Жаль. Еще раз всем спасибо.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Использование Table-valued UDF в запросе
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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