Использование хранимых функций в запросе

Коллеги, добрый день.

Есть задача: нужно построить отчёт FR, данные для которого возвращает хранимая функция. Каким образом лучше решить эту проблему?

Помониторил форум и блоги, нашёл примеры использования функции ExecuteCustomSQL, но все они в итоге возвращают какую-либо одну запись. Мне же нужна, чтобы вовращена таблица.

Либо я не все примеры нашёл, либо что-то не так понял.

Need help.

Нравится

27 комментариев

Пытаюсь использовать ADODataset.

В поле Текст SQL написал запрос: select * from _qqq(:db, :de, :wd)

При попытке определить поля, выдаёт сообщение о том, что параметры определены неправильно.

В чём может быть проблема?

Насколько понял, вам надо такой "sq", который возвращает результаты функции.

Это можно, но делается довольно эзотерически, с CustomSQL-колонками.

Ближайший пример, хоть и без вызова функции, можно посмотреть в сервисе sq_GetIsUserInGroup.

А именно такой, как требуется, можно сделать так. Делается sq с кучей колонок типа "SQL Text Column". Первая:

* from dbo.tsf_MyFunctionName(
:ContactIDs, :DepartmentID, :DateFrom, :DateTo
) /*

Последняя:

*/
if 1=0
select 1

Остальные пустые.
Во from указывается tbl_DatabaseInfo, набор параметров совпадает с параметрами функции.
sq

Александр спасибо, буду пробовать.

Сделал запрос, который в предпросмотре выглядит следующим образом:

SELECT
[WorkerName] -- AS [CustomSQLColumn],
,[Рабочих дней] from _JobTimeTracking_1(:DateBegin, :DateEnd, :WorkDaysNumbers)

group by
[WorkerName]
,[Рабочих дней]
/* AS [CustomSQLColumn1]
FROM
[dbo].[tbl_Empty] AS []
WHERE(*/--)

Но он ничего не возвращает. При этом если скопировать его в SQL Manager, он отрабатывает отлично.
Ошибок тоже никаких не выдаёт, просто не возвращает ничего. Я в запросе указал явные значения параметров.

А какой запрос идёт на сервер при открытии этого сервиса из Terrasoft? Можно посмотреть профайлером.

Какая-то беда с профайлерами. У меня СРМ 3.2.1 и судя по статье, там этот функционал не реализован. А SQL Managment Studio стоит Express, в которой тоже профайлера нет.

Буду искать сторонние разработки.

Можно и вручную попробовать разобраться. Количество и тип параметров совпадает? Если в параметры вбить значениями по умолчанию нужные данные и выбрать предпросмотр sq, функция срабатывает?

Полностью совпадает. Вот этот же запрос вSQL Manager:

declare
@WorkDaysNumbers int,
@DateBegin datetime,
@DateEnd datetime
set @WorkDaysNumbers = 22
set @DateBegin = '01.08.2012'
set @DateEnd = '31.08.2012'

SELECT
[WorkerName] -- AS [CustomSQLColumn],
,[Ðàáî÷èõ äíåé] from _JobTimeTracking_1(@DateBegin, @DateEnd, @WorkDaysNumbers)

group by
[WorkerName]
,[Ðàáî÷èõ äíåé]
/* AS [CustomSQLColumn1]
FROM
[dbo].[tbl_Empty] AS []
WHERE(*/--)

Работает прекрасно, всё возвращает. В предпросмотре не возвращает ничего. При этом, если параметр вбить некорректный, например в дату вместо 01.08.2012, вбить 41.08.2012 - то выдаёт ошибку.

Не знаю, может, это особенности 3.2.1... Всё же довольно старая версия.
А что это за колонка кириллицей, может, дело в ней? Нельзя сделать латинскими буквами?

Вадим, а вы это сами закомментировали, :

"Vitkauskas Vadim" написал:/* AS [CustomSQLColumn1]
FROM
[dbo].[tbl_Empty] AS []
WHERE(*/--)

т.к. запрос

"Vitkauskas Vadim" написал:SELECT
[WorkerName] -- AS [CustomSQLColumn],
,[Рабочих дней] from _JobTimeTracking_1(:DateBegin, :DateEnd, :WorkDaysNumbers)

group by
[WorkerName]
,[Рабочих дней]
AS [CustomSQLColumn1]
FROM
[dbo].[tbl_Empty] AS []
WHERE()

не может работать в принцыпе.
Ваша функция _JobTimeTracking_1 возвращает набор данных или одно значение?

Закомментировано специально, чтобы исключить стандартные элементы sq в Terrsoft.

Михаил, я это закомментировал в сервисе запроса, по примеру Александра. Опять же, по его совету, можно посмотреть сервис sq_GetIsUserInGroup, там очень наглядно использована данная технология.

Функция возвращает таблицу, которую я хочу вставить в отчёт FR.

Может есть какие-то иные способы получить таблицу из ХФ и вставить её в FR?

Вадим, а с названием латиницей второй колонки результат тот же самый?

Вадим, во первых вам этот подход не поможет т.к. вам надо вытягивать более чем одну колоку и вы не сможете их подтянуть в Датасет.

Только что попробовал сделать через ADO Dataset.
0. Настроил подклучение в ADO Dataset
1. Определил датасете 2 поля Val1 и Val2.
2. Val1 установил как ключевое поле (для того, чтоб датасет открывался).
3. в тексте SQL написал следующее:

select 
  [val1] as [Val1],
  [val2] as [Val2]
from fn_MyTest(:Param1)

Param1 - строковый параметр.

тогда в коде просто задал параметр и открыл датасет:

function Main() {
	ds = Services.GetNewItemByUSI('adods_Test');
	ds.Parameters.ItemsByName('Param1').Value = '1'
        ds.Open();
}  

И все заработало.

Возможно он у вас матерится на то, что названия колонок в вашей ХФ кириличные. Попробуйте изменить на латинские.
И внимательно проверте типы параметров.

Да. Даже без неё тоже самое. Это сюда кириллица не корректно перенеслась. Эх, тяжело без профайлера.

Спасибо, Михаил, ADODataset действительно работает, но только если я значения параметров задаю в самом запросе.

ййй

Если же вставляю параметры, то при попытке определить колонки автоматом, выдаёт следующее:

ййй

"Vitkauskas Vadim" написал:Эх, тяжело без профайлера.

Нагуглил такой и такой. Не пробовали?

Здравствуйте, Вадим.

Картинки также потерялись. Интересно посмотреть что за ошибка в случае установки значения параметра через

ds.Parameters.ItemsByName('Param1').Value = '1';

Дмитрий, картинки не потерялись. Они на внешнем хостинге. Кликните по тому месту, где они должны быть правой кнопкой и откройте их в новой вкладке.

Таже ошибка, что на второй картинке возникает при попытке открыть сервис FR, к которому данный датасет привязан. Я так понимаю, что ошибка в самих драйверах TADО.

Вадим, удалось ли Вам отловить запросы, которые идут к БД?

Дмитрий, нет не удалось. У меня нет профайлера. Александр предоставил пару ссылок, но первый из них не ставится на Win7, а второй, я не понял, что это за библиотеки и как их использовать.

Будет ли работать профайлер для MS SQL 2000 с MS SQL 2008 server? Вроде у нас у кого-то есть такой, могу поискать. Но не уверен, что они будут работать вместе.

"Vitkauskas Vadim" написал:
а второй, я не понял, что это за библиотеки и как их использовать.

Там в папке SqlExpressProfiler/bin/Debug есть что-то похожее на exe-шник.

"Vitkauskas Vadim" написал:Если же вставляю параметры, то при попытке определить колонки автоматом, выдаёт следующее:

Вадим, у вас скорее всего что-то не так с типами параметров.
Можете предоставить типы параметров функции и типы, которые вы проставили в ADO датасете?
Вы так проставляли значения параметрам? :
"Домброва Михаил" написал: ds.Parameters.ItemsByName('Param1').Value = '1'

Плюс задайте Ключевое Поле в ADO датасете, он иначе не будет открыватся, на сколько я знаю..

Михаил, вот определение функции:

alter function _JobTimeTracking_2 (@DateBegin as datetime, @DateEnd as datetime, @WorkDaysNumbers as int) returns table as return (

Ключевое поле задано.

В датасете типы параметров следующие:

DateBegin, DateEnd - дата/Время
WorkDaysNumbers - целое число

Вадим, в таком случае уже даже не знаю:sad:
Если есть возможность подключится, я бы мог посмотреть, в чем проблемма. Мой скайп m.dombrova

На форумах (http://stackoverflow.com/questions/712011/delphi-parameter-object-is-im…) пишут, что такое случается если один параметр дважды передавать в запрос, но я так понял, что это не тот случай. Вобщем, пишите если что :)

Вадим, здравствуйте.

Т.к. если задать значения параметров в самом запросе то ADO заполняется без проблем, тогда скорее всего причина в формате даты.

Попробуйте заполнить датасет функцией с одним параметром типа целое число.

Показать все комментарии