Приветы, PostgreSQL 7.17.0.2164, есть следующая ошибка. 

Error occurred when saving: 23503: insert or update on table "SysLocalizableValue" violates foreign key constraint "FKYru8eiQRBeFoEfawvRwKSlCy2o"

 

Случается при попытке сохранить чистый БП с одним элементом Читать/Добавить данные (кроме начального и конечного). При элементе типа скрипт - всё ок. Сохранение естественно не происходит.

Что интересно этот вторичный ключ относиться к Culture. 

 

Как быть? 

Нравится

2 комментария
Лучший ответ

Добрый день. Встречал такую ошибку, когда использовал уже "занятую" базу (номер базы) редиса. Попробуйте в ConnectionStrings.config изменить номер базы редиса на свободный.

Добрый день. Встречал такую ошибку, когда использовал уже "занятую" базу (номер базы) редиса. Попробуйте в ConnectionStrings.config изменить номер базы редиса на свободный.

Действительно, причина чаще всего в этом. Происходит такое, когда два приложения смотрят на один Redis и на одном из них в БД другой Id у какой-то культуры (какой угодно, например, шведской) или её вообще нет. Культуры кешируются в одном месте после вычитки из БД и затем система работает с ними.

Ранее было два случая с похожей проблемой, но на установке пакетов. В одном случае помогла очистка Redis, во втором попробовали заменить dll на изменённую без кеширования культур. При необходимости можно заказать в  поддержке её создание для нужной версии.

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

У нас для некоторого нашего сотрудника создан справочник, по которому находится визирующий сотрудник. В логике БП с визированием, запись визирующего нашего сотрудника из справочника корректно вычитывается и помещается в элемент "Визирование" в поле Визирующий. После чего всякий экземпляр БП без каких-нибудь ошибок зависает на элементе "Визирование". Если жестко сделать указание на сотрудника, то бп отрабатывает.

Вопрос не о том, как исправить эту ошибку. Интересно бы повторить логику элемента Визирование на основе базовых элементов чтения/записи.

Элемент визирования работает так:

  • В системе создается новая виза. Вся информация по визе, например, визирующий, результат визирования, комментарии и т. д., отображается на вкладке [ Визы ] записи раздела, по которой запущен кейс. 
  • Email-уведомление о необходимости визирования отправляется в момент создания визы сотруднику или группе сотрудников, которые назначены визирующими.
  • После утверждения или отклонения визы выбранному сотруднику, который заинтересован в результате визирования, отправляется email-уведомление и выполняется переход на следующую стадию кейса.

Где посмотреть в коде механизм логики работы элемента визирования? Может быть логика у вас есть в виде какой-нибудь диаграммы? Может быть базовый элемент визирования кто-нибудь успешно дублировал сам?

Нравится

1 комментарий

Там очень странная логика - надо указать роль или конкретного пользователя.   В элементе визирования тип Approver'а важен (хотя, данные в любом случае берутся из System Administration Object) и самого пользователя надо читать из Users (view)

Мы в итоге сделали так:

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

Привет, с наступающим или уже наступившим.

Есть следующая ошибка:

System.IO.FileLoadException: Не удалось загрузить файл или сборку "Google.Apis, Version=1.49.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab" либо одну из их зависимостей. Найденное определение манифеста сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)
Имя файла: 'Google.Apis, Version=1.49.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab' ---> System.IO.FileLoadException: Найденное определение манифеста сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)

Ситуация:
Есть задача поиграться с GoogleSheets API со стороны Creatio, для этого нужно установить соответствующие библиотеки. 
Сначала я создал консольный проект в VS и через nuget поставил либы Google.Apis.Sheets.v4 - https://www.nuget.org/packages/Google.Apis.Sheets.v4/
Подтянулись либы GoogleSheets и зависимые тоже, в том числе Google.Apis v 1.49.0.0. Протестировав на консольном проекте, где все работало, я решил поставить эти же либы в Creatio, прикрепив их как сборки к пакету.
После компиляции приложения вылезло предупреждение что уже существует либа Google.Apis, только другая - "Google.Apis, Version=1.1.4547.22925, Culture=neutral, PublicKeyToken=edaadfbc3b0bb879" как я понимаю на ней работает синхронизация календаря и ещё что то там и возможны конфликты, но предупреждение это не ошибка, по этому я пошел дальше и использовал классы новой либы версии 1.49, и тут же получил  ошибку которую написал выше.

На счет зависимостей странность:
Я скачал сборку старую Google.Apis что бы пощупать и сразу увидел зависимость от либы "Newtonsoft.Json 4.0.4.0" хотя в системе Creatio эта же либа работает в версии 12.0.0.0. Как в системе могут присутствовать сборки которые используют в одно и то же время разные версии сборки?

Возможные решения: 
1. Переписать календарь и другой функционал под новую версию либы, удалив старую, но потом обнова и gg.
2. Попробовать сделать отдельный сервис где то "во вне" и поставить туда нужные мне либы и заделать этот сервис как посредник между гуглом и Creatio.
3. Подскажите свое, что я упускаю?

Нравится

2 комментария

Добрый день.

Благодарю вас за то, что подметили данную проблему.

 

Так сразу мы не сможем решить данный вопрос, но по идее, вы можете завязаться на либу, без указания версии, дабы не требовать конкретную версию.

Мы со своей стороны займемся обновлением этой либы, но это будет не скоро.

Также могу порекомендовать вам реализовать ваш вариант №2.

Здравствуйте! Данную проблема присутствует уже очень долго. В моем случае это была проблема интеграции Creatio с  Google Analytics. И как следствие пришлось делать внешний сервис + подключил туда Rabbit для обмена данными. 

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

Добрый день!

От имени пользователя добавляю запись в таблицу OpportunityFile с помощью POST запроса - все успешно. При попытке загрузить файл в поле Data с помощью запроса PUT, запрос возвращает ошибку 404. Если у пользователя повысить права до администратора, запрос успешно выполняется. Не могу понять что надо настроить чтобы запрос выполнялся от имени простого пользователя.

Подскажите, пожалуйста.

Нравится

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

Руслан, вообще, довольно странно. Если бы там было ограничено по правам то отдавало бы 403 для пользователя. Можете показать примеры запросов? Точно в обоих случаях одинаковые?

 

Также проверьте, нет ли ограничений прав на объекте OpportunityFile: на операции, записи, поле Data.

Вот такой код запроса на изменение поля Data:

curl --location --request PUT 'https://my.company.com/0/odata/OpportunityFile(f7cb87e9-dea4-4609-95f6-5ce7ca499544)/Data' \
--header 'BPMCSRF: qR7NHdxnvLVamFiF4QnCsu' \
--header 'Content-Type: application/pdf' \
--header 'Cookie: BPMLOADER=hhv02mucokh1hdvnnrrna43e; UserName=99|97|98|105|110|101|116|68|105|115|116|114|105|98|117|116|111|114; BPMSESSIONID=zxfuxvecmcjbg0vteh1ibpvh; .ASPXAUTH=45F3530449360B52EC8592892D0588D74F78D2F37E2A91893700AB56ED32E3589FE972BF81199EE6EF9DBA8D6F3A0341586187B1D5C03358262C3E0DF181FE5DE68AB65946E18A742A83EAB74BD1A5DDE5BE6A99CEA0F5EC1574FE9A746D193CB161A330A4732121728AA5F43D2F4D252D844867C0CEDD6E9BC507012C6FF202A540A311D80980E6C4290C8426EF0E0E37B73543828236BFC59E8EABB3158132B0BA2566D72649E0942BC708DDA1264793A6302875345757E32AA1F8E8688C1C8DD9A192CA06BF8B3BC077C420F46C6211B3D37BEB674450533514FF33AA21D72B616E22CEDBBC999D5AB7B66F0BF45E10290E814024AB1550A8455978A60BC124CDE2458A99E26613202F55BA2BF2381FC057CAAF0669170605291C61DD6764A25A3694999D88BE8E3ACA371C225B88D02D46F40791CB11B6928C7587231A3E04CED54910D82498580AA62AC2DBF66088F43B35E09B07ABE3F8182A9250501969C958DBC9464682AE07DEF13C7D1D4C910AEAFBD8A6C2CEE558DA3087EB956F8EE24346; BPMCSRF=qR7NHdxnvLVamFiF4QnCsu' \
--data-binary '@/D:/Docs/Pictures/kyoScan-‎4‎.‎23‎.‎2020-‎14‎.‎07‎.‎08.pdf'

Он не меняется, менял только права пользователя (повышал до админа). С админскими правами работает, без - нет. 

Вообще с самого начала все было выполнено от имени администратора (себя), чтобы исключить влияние прав и проверить работоспособность запросов. Когда все заработало от администратора, я стал проверять от имени пользователя (не себя). Запрос на добавление сработал, на изменение - нет.  Повысил права рядового пользователя до админа и запрос сработал. Вернул обратно - не работает.

Ограничения по колонкам не настроены.

У пользователя есть право на системную операцию CanUseODataService? Хотя, выше пишете, что POST у него прошёл...

Зверев Александр,

Да, есть. 

Можно было бы понять если бы были ошибки типа 401, 403 или 406, но никак не 404. Руслан, а если завести демо-сайт в облаке и отправлять такие запросы на него, тоже воспроизводится? 

Спасибо, Александр, за подсказку. Развернул тестовую базу в облаке с версией 7.17, у нас 7.16.4. Боялся что из-за разницы в версиях ошибка не воспроизведется. Но, нет, ошибка такая же. 

Руслан, у меня на демо-сайте 7.17 не воспроизвелось: и под админом, и под пользователем файл успешно обновился. Пробовал не в curl, а в Fiddler, и на тестовом сайте не была включена проверка BPMCSRF. Пользователя в группы не включал, права на чтение и изменение записи о продаже дал вручную. Файл создал в интерфейсе, то есть на момент запроса поле Data уже было со старым содержимым.

Значит, ошибка не в «коробке», а что-то неправильно отправляете к серверу. 

Зверев Александр,

Что не правильно может отправляться на сервер, если от администратора запрос успешно отрабатывает, а от пользователя нет? Повторю - запрос не меняется, значит запрос правильный.

У меня и под администратором, и под пользователем файл обновляется. Без точного описания, как воспроизвести, не могу сказать, что неправильно.

 

А если, как и в моём примере, файл на момент запуска PUT уже есть, у Вас тоже такая ошибка?

Зверев Александр,

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

Вот результат запроса от имени администратора (200 Ок):

Вот результат от имени пользователя 404 (Not Found):

Выполнено на тестовой платформе - https://041470-sales-enterprise.terrasoft.ru/

Руслан, попробуйте не в Postman, а в Fiddler, как на моих скриншотах. Сейчас приведенного тестового сайта уже нет, проверить на нём не могу.

Либо же обратитесь в поддержку с более подробным описанием воспроизведения и параметрами подключения.

Ссылка на тестовую платформу устарела, сгенерировал новое тестовое приложение

Все таки дело было в правах, но оказалось что права проверялись не на таблицу OpportunityFile, а на Opportunity. Интересно получается, создать запись в таблице OpportunityFile разрешено, а изменить нет. Неожиданно.

Руслан, то есть на нескольких разных тестовых базах было одинаково настроено с правами? А как именно? После выдачи пользователю прав на изменение продажи заработало?

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

Добрый день!

Пытаюсь по инструкции создать запись в таблице OpportunityFile. 

При отправке запрос сервер возвращает 500 ошибку Internal Server Error. 

Подскажите, пожалуйста, что не так делаю?

Код запроса:

curl --location --request POST 'https://my.domain.com/0/odata/opportunityfile' \
--header 'BPMCSRF: mbaZawvWrbrf0jub0ayr7O' \
--header 'Content-Type: application/json' \
--header 'Cookie: UserName=username; BPMLOADER=5vurytjra4qxcy2ym1xjsfji; .ASPXAUTH=8FFC3373A07416E90889F9B924E2FFB16B7A75335673C6A585B4FBD7941A36C709548056A1C53030AA0A65C6BC5B9C1F4D5B58195B65BA3BDBFF5F34542A423746FE1329F390C67190FD230C47E8834F89E7D448FC2C14D32C46FF77C6BB64D7A47057BA009B80E4F31093730B41DFDADEF0F70DC3A1A7130D6450ACC136080AB6DACE828A8B68420B4701C983818AFD1CF38573D7DC5E127180D93C8B8D86314CBCFCB86CCEE9E7B5EB1D30248EA25B3AC465E7ADFFA0E891FAB31B2A72627E88A5520BFC625E8701DCF9F7756E1287EA7535F445C13633DE89166AB35BE431C315AD66A10F583CD0D4E31FCC6092701635AAC199D74E9B807A632D9A3BBA2AF3BF0893BB09C9CBDBD3BA110E434B9BFEC744B464D1BF833579317AE62D59D99E58C7C3E40FC03C37BB1BFC401CD958E69A12C3B132DDF1AF7DE58176B26DC6F1DCE91B10CDBDBF98464C7D4047C512010D423A074E4A9EBEC2656F2C45CC76B77EF82C241564FE95494EA754421B45B9BDF2FFAE60853A6F6B44CDA4229AB1FF557FD4; BPMCSRF=mbaZawvWrbrf0jub0ayr7O; BPMSESSIONID=0tt2ubyrc4mo2c4ci5dpwg0w' \
--data-raw '{
    "Name": "FieldValue"
}'

 

Нравится

5 комментариев
Лучший ответ

Руслан, ошибка 500 означает, что более подробная информация будет в логах приложения на веб-сервере.

Но, скорее всего, просто не заполнено обязательное поле OpportunityId в объекте, по которому должна осуществляться связь с объектом раздела, куда добавляется файл.

Руслан, ошибка 500 означает, что более подробная информация будет в логах приложения на веб-сервере.

Но, скорее всего, просто не заполнено обязательное поле OpportunityId в объекте, по которому должна осуществляться связь с объектом раздела, куда добавляется файл.

Зверев Александр,

Подскажите, пожалуйста, где находится файл логов сервиса ODATA. Самостоятельные поиски не увенчались успехом.

Такого нет, логи общие для всего сайта. Могут писаться в файлы (Error.log и подобные) или в базу, если так настроено логирование.

В файле Error.log имеется единственная запись:

2020-12-23 08:24:08,710 [1] ERROR IIS APPPOOL\BPMonline Terrasoft.Core.Entities.Events.EntityEventListenersLoader CreateListenerInstance - Error while creating entity event instance of type FileSecurityExcludedUriEventListener
Terrasoft.Core.InstanceActivationException: Error creating an instance of the "Terrasoft.Web.FileSecurity.IFileSecurityExcludedUrisProvider" class ---> Ninject.ActivationException: Error activating IFileSecurityExcludedUrisProvider using binding from IFileSecurityExcludedUrisProvider to method
Provider returned null.
Activation path:
  1) Request for IFileSecurityExcludedUrisProvider
 
Suggestions:
  1) Ensure that the provider handles creation requests properly.
 
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   --- End of inner exception stack trace ---
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   at DynamicInjector7f791e96d519466d85d3463387ed1a0f(Object[] )
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, String name, IParameter[] parameters)
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   at Terrasoft.Core.Entities.Events.EntityEventListenersLoader.CreateListenerInstance(Type classType)

Имеет ли она отношение к проблеме?

К проблеме, скорее всего, относится то, что в запросе нет значения поля OpportunityId, которое в объекте обязательное.

Или с ним будет то же самое?

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

Добрый день!

Подскажите, пожалуйста, как сделать так, чтобы при удалении контрагента, автоматически удалялись все связанные с ним записи из детали на контрагенте?

 

Спасибо!

Нравится

4 комментария
Лучший ответ

Каскадная связь при настройке детали по полю контрагент должна помочь

Каскадная связь при настройке детали по полю контрагент должна помочь

Алексей Следь, спасибо большое!))) В 7.17 не могу её найти((( 

"Удалять записи" не помогает.

 

 

Екатерина, непонятно, почему у Вас подписи переключателей такие, а не «Блокировать удаление, если есть связанные записи в текущем объекте с этим значением» и «Удалять записи из текущего объекта с этим значением», как написано при открытии в дизайнере стандартной детали, вроде «Контрагент в группе». Там у поля связи с разделом выбрано второе значение.

На всякий случай, старая конфигурация доступна на /0/dev_old и можно включить каскадную связь там.

Зверев Александр,

Cпасибо большое! Помогло переключение на старую конфигурацию!)

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

Добавляю данные в бизнес-процессе через задание сценарий. Делаем многострочный Insert

var insCertificateData = new Insert(UserConnection).Into("NavCertificateData");
foreach (var entity in navCertificateData)
{
	insCertificateData.Values()
		.Set("NavCertificate", Column.Parameter(certificateId))
		.Set("NavProduct", Column.Parameter(entity.NavProduct ))
		.Set("NavDiametr", Column.Parameter(entity.NavDiametr))
		.Set("NavMarka", Column.Parameter(entity.NavMarka,))
		.Set("NavNippelAssembly", Column.Parameter(entity.NavNippelAssembly))
		.Set("NavQuantity", Column.Parameter(entity.NavQuantity))
		.Set("NavWeight", Column.Parameter(entity.NavWeight))
		.Set("NavMinUES", Column.Parameter(entity.NavMinUES))
		.Set("NavMaxUES", Column.Parameter(entity.NavMaxUES))
		.Set("NavMinLength", Column.Parameter(entity.NavMinLength))
		.Set("NavMaxLength", Column.Parameter(entity.NavMaxLength))
		.Set("NavDK", Column.Parameter(entity.NavDK))
		.Set("NavBend", Column.Parameter(entity.NavBend))
		.Set("NavKTP", Column.Parameter(entity.NavKTP))
		.Set("NavCompanyGrafit", Column.Parameter(entity.NavCompanyGrafit));
}
insCertificateData.Execute();

В основном все типа string. В значении NavNippelAssembly иногда приходит EmptyString. И в этом случае получаем ошибку 

"Для параметра \"P5\" со значением null необходимо указать тип данных"

Собственно есть Column.Parameter(Object,DataValueType). Полагаю, что надо его использовать, но как указать этот самый DataValuType? Тип строка  

Нравится

8 комментариев
Лучший ответ

Алексей Следь,

Посмотрите обсуждение в этой теме.

Для установки null можно использовать Column.Const(null)

Николай Кузьмин,

Так у меня ж не всегда null и 5 полей, где может быть string.Empty

Алексей Следь,

Посмотрите обсуждение в этой теме.

Алла, спасибо, я там как раз приводил похожий пример, только в нынешнем случае сравнение будет не с Guid.Empty, а с String.Empty.

 .Set("IndustryId", ((IndustryIdParameter!=Guid.Empty)?Column.Parameter(IndustryIdParameter):Column.Const(null)))

Ну, или проверять условие и если не выполняется, не производить добавление к формируемому запросу этого Set, тогда в SQL-запросе вообще не будет упоминания этого пустого поля.

Мда, как всегда решение на поверхности лежало. 

Александр, по мне правильней тогда делать сравнение не со string.Empty, а проверять stringIsNullOrEmpty(). А т.к. табличка у меня нуллы не поддерживает, то все пришло к такой конструкции

.Set("NavProduct", (string.IsNullOrEmpty(entity.NavProduct)? Column.Parameter(string.Empty) : Column.Parameter(entity.NavProduct)))

 

Алексей, если всё так, как описали, то зачем вообще два раза писать Column.Parameter и проверять на Empty? Можно только на null при помощи «??», как предложили тут:

.Set("NavProduct", Column.Parameter(entity.NavProduct ?? string.Empty))

 

Александр, учитывая источник данных, лучше проверять на Null и Empty. В любой момент Null может стать пустой строкой.

Так пустая строка в итоге и пишется, её же не надо на такую же заменять, можно сразу в параметр.

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

Добрый день!

Подскажите, пожалуйста, где используется пользователь с именем SysPortalConnection и можно ли его отключить?

Нравится

1 комментарий

Руслан, этот пользователь используется для выполнения загрузки конфигурационных страниц, когда пользователь не авторизирован. Например при оценке обращения, после того как оценка уже проставлена, для того чтобы показать пользователю страницу обратной связи, на которой он сможет ввести комментарий к оценке.

Логин и пароль этого пользователя при этом используются в ядре при обращении к AppConnection, там они считываются из внутреннего Web.config из значений параметров UserManagementSauName и UserManagementSauPassword.

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

 

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

Установлено дополнение Excel reports builder for Creatio
https://marketplace.terrasoft.ru/app/excel-reports-builder-creatio

При установке ошибок не было, дополнение установлено успешно.

 

При попытке добавить запись в раздел сразу открывается карточка редактирования, при этом в консоли наблюдаются ошибки:

Ну и далее ничего сделать нельзя.

Версия системы: 7.16.4.1731

 

Прошу подсказать как исправить.

Спасибо.

 

Нравится

2 комментария

Сергей, добрый день!

 

возможно решение не было полностью установлено. Выполните в нерабочее время компиляцию приложения и попробуйте добавить отчет повторно.

 

Также уточните продукт Creatio для воспроизведения ошибки.

Переустановку приложения выполнял несколько раз, результат один и тот же... ошибка.
Продукт: bpmonline sales enterprise & marketing & service enterprise

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

Добрый день

 

Есть интересная задача. Надо в БП по событию подключится к стороннему серверу MS-SQL и выполнить хранимую процедуру с двумя параметрами, которая вернет нам таблицу данных. Далее эту таблицу данных сохранить в кастомном разделе в системе и настроить связи с другими объектами.

Затык именно в подключении к стороннему серверу БД и вызове процедуры.

В MSSMS это выглядит как:

EXECUTE [dbo].[GetDataForCRM] @nomer,@date 

 

Нравится

8 комментариев
Лучший ответ

Добрый день!

Пробовали ли настраивать линкованные серверы? Если получится подключить сторонний сервер, то можно будет отправлять на него sql-запросы.

Добрый день!

Пробовали ли настраивать линкованные серверы? Если получится подключить сторонний сервер, то можно будет отправлять на него sql-запросы.

Указать имя сервера

Логин и пароль

Разрешить RPC для вызова ХП

Спасибо, помогло, частично. в MSSMS могу вызвать как

EXEC [LinkedServer].[LinkedDB].[dbo].[GetDataForCRM] @nomer,@date 

Как передать что надо вызывать на связанном сервере? Если я указываю полный путь процедуры, а не только имя, то получаю

EXEC [dbo].[[LinkedServer].[LinkedDB].[dbo].[GetDataForCRM]] @nomer,@date 

 

Алексей, функцию на связанном сервере запускают специальным образом, через OPENQUERY или sp_executesql, см. примеры тут.

SELECT SomeField
    FROM OPENQUERY([YOURSERVER], 'SELECT * FROM [SOMEDB].dbo.fn_SomeRemoteFunction(NULL)') tst

 

Зверев Александр,

т.е. через

StoredProcedure getDataForCRM = new StoredProcedure(UserConnection, "GetDataForCRM")
				.WithParameter("nomer", numberDoc)
				.WithParameter("date", dateDoc) as StoredProcedure;

не выйдет получить данные?

Так запускается хранимка на локальном сервере БД, а вопрос был о запуске на другом, связанном.

 

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

 

Также не очень понятно, Вам нужно хранимую процедуру или таки функцию? Таблицу с результатами может возвращать последняя.

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