Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности

Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
13.05.2002, 20:19
|
|||
|---|---|---|---|
|
|||
Использование Table-valued UDF в запросе |
|||
|
#18+
Здравствуйте. Есть у меня таблица пользователей 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 Как побороть, подскажите. спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
13.05.2002, 20:58
|
|||
|---|---|---|---|
Использование Table-valued UDF в запросе |
|||
|
#18+
Прошу прощения, что не по существу вопроса, но всех поставщиков, покупателей, страховщиков, агентов, взяткополучателей, вымогателей и прочих контактеров нужно помещать в таблицу КОНТРАГЕНТЫ, тогда такие проблемы просто не будут возникать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
13.05.2002, 21:20
|
|||
|---|---|---|---|
|
|||
Использование Table-valued UDF в запросе |
|||
|
#18+
Ну, я присоединился к этоиу проекту через пол года после его начала, так что кардинально менять структуру базы у меня возмодгости нет. А на счет одной таблицы - тут можно спорить - все же поставщики, клиенты, агенты, агенства есть разные сущности с разными наборами аттрибутов. И запихивать их в одну таблицу особого сиысла я не вижу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
13.05.2002, 22:31
|
|||
|---|---|---|---|
Использование Table-valued UDF в запросе |
|||
|
#18+
В запросе Вам придется использовать 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. Не могу судить, не имея схемы, но не исключено, что Вам могло бы сильно облегчить задачу создание представления, объединяющего таблицы Поставщики, Заказчики, Агенты.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
13.05.2002, 22:47
|
|||
|---|---|---|---|
|
|||
Использование Table-valued UDF в запросе |
|||
|
#18+
Это как раз первое, что я сделал. Однако мне не совсем нравится, что за CompanyID и CompanyName я хожу дважды к одним и тем же таблицам - думаю это совсем не эффективно. (Функция определяет тип пользователя,потом открывает нудную таблицу и возврашает значение). А в песпективе мне похоже придется еще одно значение добывать, причем сам процесс довольно муторный. Потому я и озаботился вопросом как можно вернуть сразу несколько значений (один раз прочитать все что нужно и вернуть) - потому и пробую прикрутить табличную функцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
14.05.2002, 05:54
|
|||
|---|---|---|---|
Использование Table-valued UDF в запросе |
|||
|
#18+
Функции могут возвращать либо скалярные значения , либо наборы данных (грубо говоря, таблицы). В первом случае их можно использовать в секции перечисления полей, в конструкции 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 записей для того лишь, чтобы потом выбрать из них одну-единственную. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
14.05.2002, 06:47
|
|||
|---|---|---|---|
Использование Table-valued UDF в запросе |
|||
|
#18+
Полностью согласен с Garya. Хотелось бы добавить, что ко всему прочему не Inline-функция по производительности всегда будет ниже хотя бы потому, что данные в ней сначала будут впихиваться в некую таблицу, а операция вставки всегда медленнее, чем просто выборка. Плюс таблица эта обьявляется как переменная и не думаю, что впихивать в нее большие обьемы данных хорошая идея. Далее еще ождно замечание: UDF-функции в виде параметра могут получать только константу или переменную. Вы же пытаетесь впихнуть в функцию поле UsersID с таблицы Users. Такой номер не пройдет. В данном случае получается Вам нужен вьювер, а не функция, который просто соединяется inner join с таблицей Users. Насчет хождения дважды за CompanyName тоже вопрос спорный - соптимизируйте свой вьювер - используйте вложенные подзапросы, где возвращаються по юзерам только ключ CompanyID, а на верхнем уровне уже происходит обьединение с Company. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
14.05.2002, 08:18
|
|||
|---|---|---|---|
|
|||
Использование Table-valued UDF в запросе |
|||
|
#18+
Спасибо всем за коментарии. Функция у меня табличная. Не in-line - поскольку сделать все что нужно в параметеризированном запросе в RETURN увы не получается. Как я уже писал - выборка должна идти из разных таблиц в зависимости от типа User. Сделать viewшку - очень монстрообразно получается - эдакая навороченная снежинка. Вообщем с table function у меня ничего не выйдет, поскольку в качестве параметра должна быть только константа или переменная. Т.е. способа связать таблиу и функцию впредикате FROM нет. Жаль. Еще раз всем спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=46&tablet=1&tid=1822770]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
134ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 247ms |
| total: | 454ms |

| 0 / 0 |
