Вызов хранимой процедуры MS SQL с параметрами

443 views
Skip to first unread message

IgLowy

unread,
Dec 11, 2014, 12:03:45 PM12/11/14
to cla...@googlegroups.com
С 1-го января больницам надо будет выписывать пациентам справки о стоимости лечения.
Местный ФОМС пишет программу на С# под MS SQL Express. Её нам хотят подсунуть для работы.
Но при использовании этой программы мы получаем двойной ввод: сначала в свою программу, потом в программу ФОМС.
Хотелось бы использовать часть функционала этой программы для своих целей. Расчёт в ней находится в хранимой процедуре, которая вызывается с параметрами (сроки лечения, профиль медпомощи, диагноз, список операций...). Потом эти параметры и результат расчёта записываются хранимкой в базу данных. Т.е. записать данные в таблицу, чтобы хранимка их считала, не получается. Один их параметров является список операций.
Возможно ли из клариона вызвать такую хранимку и корректно подсунуть ей данные?

С уважением, IgLowy

Alexander Ageev

unread,
Dec 12, 2014, 9:15:08 AM12/12/14
to cla...@googlegroups.com
Привет!
 
Да, можно.
 
Реализация зависит от типа передаваемых параметров
 
В простейшем случае - {Prop:sql} рулит
 

 Александр Агеев
   alexande...@gmail.com
   ICQ 360029563
   скайп alexander.n.ageev
 

 


From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
Sent: Friday, December 12, 2014 12:04 AM
To: cla...@googlegroups.com
Subject: {ClaList:7883} Вызов хранимой процедуры MS SQL с параметрами

--
Вы получили это сообщение, поскольку подписаны на группу "ClaList".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

IgLowy

unread,
Dec 15, 2014, 1:39:16 AM12/15/14
to cla...@googlegroups.com
Ну вот у меня есть сомнения как раз насчёт параметров.
я упомянул, что там передаётся список операций. по словам разработчика это какой-то список в памяти, как я понимаю, аналогичный кларионовскому queue. и ещё есть сомнение касаемое возвращаемого значения. раньше получить его из хранимки было можно только через запись в таблицу. изменилось ли что-то в этом плане?

пятница, 12 декабря 2014 г., 18:15:08 UTC+4 пользователь Alexander Ageev написал:

Nikolay Tsigouro

unread,
Dec 15, 2014, 2:09:59 AM12/15/14
to ClaList

Декларацию (достаточно прототип) хранимки на T-SQL в студию.

WBR, Nikolay Tsigouro

15.12.2014 9:39 пользователь "IgLowy" <igl...@mail.ru> написал:

LukianovLCF

unread,
Dec 15, 2014, 4:10:03 AM12/15/14
to cla...@googlegroups.com
Привет!
Передача простых параметров,
Результат в long
!PROCEDURE prg_CancellAgreement
! @AgreementLongID int,
! @AmountReturn money,
! @NumberAgreement varchar(20),
! @dateAgreementParam varchar(10),
! @dateCancellParam varchar(10)

!SET NOCOUNT ON;
!set DateFormat ymd
!set @dateAgreement = @dateAgreementParam

! return 4

BIND('Loc:Result',Loc:Result)

CurrentParametrs{Prop:SQL} = '&Loc:Result = Call prg_CancellAgreement (' & Agr:AgreementLongID & ', ' & Agr:Amount & ', ' & |
'''' & Agr:NumberAgreement & ''', ''' & format(Agr:AgreementDay, @d10-) & ''', ''' & format(Agr:EndDay, @d10-) & ''',' & Agr:Salery_AttorneyID & ')'

Если надо в качестве результата получить набор (таблицу), то в конце (ну например prg_GetViewPlaceTable) должно быть:

dbo.prg_GetViewPlaceTable

begin

.....
select PlaceName, PlaceNumber, 1 as ZoneID, CatID, PlaceID, TypePlace, CountArenda, AgreementLongID,
SaleryID as SalareyID, NumberAgreement, YearEnd, MonthEnd, ShortName,PriceArenda, AgreementID, Agr_NumberAgreement, Agr_AgreementDay, Agr_Price, Agr_Square from @ViewPlace
end

VIEW_PLACE должна иметь соответствующую структуру

VIEW_PLACE{Prop:SQL} = 'call dbo.prg_GetViewPlaceTable(' & Loc:CatID & ',' & Loc:Year & ',' & Loc:Month & ')'
loop
Next(VIEW_PLACE)
if ErrorCode() then break.
.

Как-то так ...
А вот как передать Queue в SQL тоже очень хочется понять. Иногда страсть как надо, приходится через буферные таблицы делать...

From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
Sent: Monday, December 15, 2014 9:39 AM
To: cla...@googlegroups.com
Subject: Re: {ClaList:7885} Вызов хранимой процедуры MS SQL с параметрами

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

пятница, 12 декабря 2014 г., 18:15:08 UTC+4 пользователь Alexander Ageev написал:
Привет!
 
Да, можно.
 
Реализация зависит от типа передаваемых параметров
 
В простейшем случае - {Prop:sql} рулит
 
 Александр Агеев
   alexande...@gmail.com
   ICQ 360029563
   скайп alexander.n.ageev
 
 

________________________________________

p k

unread,
Dec 15, 2014, 5:29:49 AM12/15/14
to clalist

15 декабря 2014 г., 13:10 пользователь LukianovLCF <Luki...@lcf.ru> написал:
Настройки подписки и доставки писем: https://groups.google.com/d/optout.

IgLowy

unread,
Dec 15, 2014, 5:39:43 AM12/15/14
to Nikolay Tsigouro
Здравствуйте, Nikolay.

Вы писали 15 декабря 2014 г., 11:09:58:


Декларацию (достаточно прототип) хранимки на T-SQL в студию.
WBR, Nikolay Tsigouro
15.12.2014 9:39 пользователь "IgLowy" <igl...@mail.ru> написал:
Ну вот у меня есть сомнения как раз насчёт параметров.
я упомянул, что там передаётся список операций. по словам разработчика это какой-то список в памяти, как я понимаю, аналогичный кларионовскому queue. и ещё есть сомнение касаемое возвращаемого значения. раньше получить его из хранимки было можно только через запись в таблицу. изменилось ли что-то в этом плане?

пятница, 12 декабря 2014 г., 18:15:08 UTC+4 пользователь Alexander Ageev написал:
Привет!
 
Да, можно.
 
Реализация зависит от типа передаваемых параметров
 
В простейшем случае - {Prop:sql} рулит
 
 Александр Агеев
   alexande...@gmail.com
   ICQ 360029563
   скайп alexander.n.ageev
 
 




Текст хранимки:
-------------------------------------------------------------------------------------------------
USE [IZL]
GO
/****** Object:  StoredProcedure [dbo].[sp_stoim]    Script Date: 12/15/2014 13:56:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_stoim]
       @code_mo varchar(6), --код медицинской организации
       @usl_ok numeric(2,0), -- условия оказания МП
       @fam varchar(40),
       @im varchar(40),
       @ot varchar(40),
    @w numeric(1,0), -- пол: 1 - мужской, 2 - женский
    @dr date, --дата рождения
    @profil_t varchar(3), --профиль
    @pr_vidpol as numeric(1), -- тип МП в поликлинике: заболевание - 1, профилактика - 2, неотложная помощь - 3
    @pr_feld as numeric(1), -- тип медперсонала 1 - врач, 2 - младший МП
    @scode varchar(20),-- код услуги
    @mkb varchar(10),  -- мкб основное
    @mkb2 varchar(10), -- сопутствующее
    @mkb3 varchar(10), -- осложнения
    @kol_du numeric(10,2), -- кол-во дней, посещений, услуг
    @ishod varchar(1), --исход
    @date_in date, --дата начала лечения
    @date_out date, --дата окончания лечения
    @death int, --признак смерти
    @oper dbo.type_tbl_oper readonly, -- указание наименовения табличного типа
    @stoim numeric(20,2) output -- стоимость
AS
BEGIN        
       SET NOCOUNT ON;
       declare
               @kod_ksg as integer,
               @koef_ksg as numeric(14,2),
               @type_otd as char(1),
               @year as char(4),
               @month as decimal(2),
               @sex as char(1),
               @laparosk as numeric(1) --признак лапароскопической операции 0 - нет, 1 - есть
               
       set @mkb = REPLACE(@mkb,'.','')        
       set @mkb2 = REPLACE(@mkb2,'.','')        
       set @mkb3 = REPLACE(@mkb3,'.','')        
               
       set @type_otd = case when @usl_ok = 1 then '1' else '3' end
       set @year = cast(year(@date_out) as CHAR(4))
       set @month = month(@date_out)
       set @sex = RTRIM(STR(@w))
               
       --расчет стоимости медицинской момощи        
       -- Поликлиника, СМП, реабилитиция, ЭКО
       if @usl_ok in(3,4) or @profil_t in('533','040')  begin
               exec [dbo].[sp_tarif_pol]
                       @code_mo, 
                       @usl_ok,
                       @dr,
                       @profil_t,
                       @kol_du,
                       @date_in,
                       @year,
                       @month,                        
                       @pr_feld,
                       @pr_vidpol,
                       @stoim output        
       end         
               
       
       -- 1. КС, ДС по КСГ и КПГ
       if @usl_ok in(1,2) and @profil_t not in('533','040') begin
               -- определение кода КСГ
               exec dbo.kod_ksg 
                       @type_otd, 
                       @year, 
                       @month, 
                       @sex, 
                       @mkb, 
                       @mkb2, 
                       @mkb3,
                       @date_in, 
                       @dr, 
                       @oper, 
                       @kod_ksg output, 
                       @koef_ksg output,
                       @laparosk output
       
               select @kod_ksg
               
               -- расчет
               exec [dbo].[sp_tarif_ksg]
                       @code_mo,
                       @usl_ok,    
                       @dr,
                       @profil_t,        
                       @kol_du,
                       @ishod,
                       @date_in,
                       @date_out, 
                       @death,
                       @kod_ksg,
                       @laparosk,     
                       @stoim output
       end 
       
    select @stoim
    
    exec dbo.spStoimLogSave
               @fam,
               @im,
               @ot,
               @code_mo,
               @usl_ok,
               @w,
               @dr,
               @profil_t,
               @pr_vidpol,
               @pr_feld,
               @scode,
               @mkb,
               @mkb2,
               @mkb3,
               @kol_du,
               @ishod,
               @date_in,
               @date_out,
               @death,
               @oper,
               @stoim
               
    --set @stoim = 123.45*(select COUNT(*) from @oper)
    --set @stoim = @kod_ksg
END
-------------------------------------------------------------------------------------------------

Меня беспокоит параметр:
    @oper dbo.type_tbl_oper readonly, -- указание наименовения табличного типа
Разработчик уверяет, что это не таблица базы, а список в памяти.
у меня два варианта действий:
1. если все параметры я могу выдать из клариона, то тупо вызываю хранимку и она всё делает.
2. прошу разработчика сделать хранимку-прокладку, которая будет брать данные из промежуточной таблицу и вызывать хранимку расчёта.



-- 
С уважением,
 IgLowy                          mailto:igl...@mail.ru

IgLowy

unread,
Dec 15, 2014, 5:55:08 AM12/15/14
to LukianovLCF
Здравствуйте, LukianovLCF.

Вы писали 15 декабря 2014 г., 13:10:29:
Спасибо за пример вызова. Осталось только выяснить со списком.

LukianovLCF

unread,
Dec 15, 2014, 6:11:41 AM12/15/14
to cla...@googlegroups.com
Присоединяюсь к Николаю - прототип процедуры в студию :-).

-----Original Message-----
From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
--
Вы получили это сообщение, поскольку подписаны на группу ClaList.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.

IgLowy

unread,
Dec 15, 2014, 6:58:41 AM12/15/14
to LukianovLCF
Здравствуйте, LukianovLCF.

Вы писали 15 декабря 2014 г., 15:12:09:

> Присоединяюсь к Николаю - прототип процедуры в студию :-).
Ну так в ответе Николаю я текст хранимки привёл. этого недостаточно?

Игорь Стригунков

unread,
Dec 15, 2014, 7:03:12 AM12/15/14
to cla...@googlegroups.com
Привет.

http://msdn.microsoft.com/ru-ru/library/bb510489.aspx

Оно?

15.12.2014, 14:58, "IgLowy" <igl...@mail.ru>:
> --
> Вы получили это сообщение, поскольку подписаны на группу ClaList.
>
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
> Настройки подписки и доставки писем: https://groups.google.com/d/optout.

--
С уважением, Игорь
strig...@yandex.ru

LukianovLCF

unread,
Dec 15, 2014, 7:37:36 AM12/15/14
to cla...@googlegroups.com
Наверное, проскочило мимо меня.

-----Original Message-----
From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
Sent: Monday, December 15, 2014 1:58 PM
To: LukianovLCF

IgLowy

unread,
Dec 15, 2014, 8:36:24 AM12/15/14
to Игорь Стригунков
Здравствуйте, Игорь.

Вы писали 15 декабря 2014 г., 16:03:05:

> Привет.

> http://msdn.microsoft.com/ru-ru/library/bb510489.aspx

> Оно?
Позвонил разработчику. Он подтвердил, что это оно.

LukianovLCF

unread,
Dec 15, 2014, 8:38:52 AM12/15/14
to cla...@googlegroups.com
Нашёл :-)
@oper dbo.type_tbl_oper readonly, -- указание наименовения табличного типа ?

Если там не много строк, можно попробовать как http://msdn.microsoft.com/ru-ru/library/bb510489.aspx ( спасибо Игорю Стригункову)
Реально это может быть так:
Loc:SQL CString(8192)
Loc:Stoim decimal(20,2)
Bind('Stoim', Loc:Stoim)
Loc:SQL = 'DECLARE @oper AS type_tbl_oper; '

loop
Loc:SQL = Loc:SQL & ' INSERT INTO @oper (название поля1, название поля2...., название поляN) values (' & Значение1 & ', ''' & Значение2 & '',..... '); '
.
Loc:SQL = Loc:SQL & ' EXEC sp_stoim @code_mo=''' & code_mo & ''', ' & ..., @death =' & death & ', @oper = type_tbl_oper, @stoim = &Stoim ;'
SQLFile{Prop:SQL} = Loc:SQL
Loc:Stoim получает значение параметра @stoim

Сообщество поправит, если что.
-----Original Message-----
From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
Sent: Monday, December 15, 2014 1:58 PM
To: LukianovLCF

LukianovLCF

unread,
Dec 15, 2014, 8:40:30 AM12/15/14
to cla...@googlegroups.com
Спасибо.
Век живи, век учись...

И дураком помрешь :-)

С уважением,
Лукьянов Валерий


-----Original Message-----
From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of Игорь Стригунков
Sent: Monday, December 15, 2014 3:03 PM
To: cla...@googlegroups.com

IgLowy

unread,
Dec 15, 2014, 10:03:07 AM12/15/14
to LukianovLCF
Здравствуйте, LukianovLCF.

Вы писали 15 декабря 2014 г., 17:39:18:

> Нашёл :-)
> @oper dbo.type_tbl_oper readonly, -- указание наименовения табличного типа ?

> Если там не много строк, можно попробовать как
> http://msdn.microsoft.com/ru-ru/library/bb510489.aspx ( спасибо Игорю Стригункову)
> Реально это может быть так:
> Loc:SQL CString(8192)
> Loc:Stoim decimal(20,2)
> Bind('Stoim', Loc:Stoim)
> Loc:SQL = 'DECLARE @oper AS type_tbl_oper; '

> loop
> Loc:SQL = Loc:SQL & ' INSERT INTO @oper (название поля1,
> название поля2...., название поляN) values (' & Значение1 & ', ''' & Значение2 & '',..... '); '
> .
> Loc:SQL = Loc:SQL & ' EXEC sp_stoim @code_mo=''' & code_mo &
> ''', ' & ..., @death =' & death & ', @oper = type_tbl_oper, @stoim = &Stoim ;'
> SQLFile{Prop:SQL} = Loc:SQL
> Loc:Stoim получает значение параметра @stoim

> Сообщество поправит, если что.
Т.е. сформировать запросом такой список из своего списка перед
вызовом хранимки и подсунуть его хранимке? интересный вариант :)
получается, что вызов такой хранимки вполне реален, надо проверять на
реальных данных. и надо у разработчика затребовать структуру списка
операций.

LukianovLCF

unread,
Dec 15, 2014, 12:01:20 PM12/15/14
to cla...@googlegroups.com
Я проверил, работает :-).
Тут фишка в том, что на исполнение передается весь пакет сразу, в рамках одного соединения.
А структуру type_tbl_oper можно посмотреть
select d.name, tp.name, d.max_length from sys.table_types as t
inner join sys.columns as d on d.object_id = t.type_table_object_id
inner join sys.types as tp on tp.system_type_id = d.system_type_id
where t.name=' type_tbl_oper'
-----Original Message-----
From: cla...@googlegroups.com [mailto:cla...@googlegroups.com] On Behalf Of IgLowy
Sent: Monday, December 15, 2014 5:02 PM
To: LukianovLCF

Vitaly B.

unread,
Dec 16, 2014, 5:19:07 AM12/16/14
to LukianovLCF
Привет, LukianovLCF.

Вы писали 15 декабря 2014 г., 23:40:55:

> Спасибо.
> Век живи, век учись...

> И дураком помрешь :-)

Я охладел к научным книжкам
не потому, что стал ленив;
ученья корень горек слишком,
а плод, как правило, червив.

--
Всего наилучшего,
poruchik mailto:fighti...@mail.ru
callto:fighting_boa
-------------------------------------------------------------------
В молодости шалил - думал, потом поумнел и стал соображать... ©

IgLowy

unread,
Mar 26, 2015, 12:32:50 PM3/26/15
to IgLowy
Возвращаюсь к своему старому вопросу

------------------------------------------------------------------
------------------------------------------------------------------


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

013F8H(1) 18:35:07.783 Executing Statement 0532830H:CALL sp_stoim('690111',1, ,1,ВВВВВВВВ,ВВВВВВВВ,ВВВВВВВВ,1,2015-01-01,031,1,1,,K35.8,K35.8,K35.8,1,1,2015-01-01,2015-01-01,0,,,0,2,)
013F8H(1) 18:35:07.798 Error Occurred: 37000 [Microsoft][ODBC SQL Server Driver][SQL Server]Неправильный синтаксис около конструкции "690111".
013F8H(1) 18:35:07.798  Time Taken:0.02 secs
013F8H(1) 18:35:07.798 SET_PROPERTY(dbo.sluch:016A030H) Неправильный синтаксис около конструкции "690111". Time Taken:0.02 secs

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

Описание аргументов хранимки:


ALTER PROCEDURE [dbo].[sp_stoim]        
 @code_mo varchar(6), --код медицинской организации
 @usl_ok numeric(2,0), -- условия оказания МП
 @mo_pac_code varchar(40), --код пациента
 @nhistory varchar(40), --номер талона/истории

 @fam varchar(40),
 @im varchar(40),
 @ot varchar(40),
 @w numeric(1,0), -- пол: 1 - мужской, 2 - женский
 @dr date, --дата рождения
 @profil_t varchar(3), --профиль
 @pr_vidpol as numeric(1), -- тип МП в поликлинике: заболевание - 1, профилактика - 2, неотложная помощь - 3
 @pr_feld as numeric(1), -- тип медперсонала 1 - врач, 2 - младший МП
 @scode varchar(20),-- код услуги
 @mkb varchar(10),  -- мкб основное
 @mkb2 varchar(10), -- сопутствующее
 @mkb3 varchar(10), -- осложнения
 @kol_du numeric(10,2), -- кол-во дней, посещений, услуг
 @ishod varchar(1), --исход
 @date_in date, --дата начала лечения
 @date_out date, --дата окончания лечения
 @death int, --признак смерти     
 @oper dbo.type_tbl_oper readonly, -- указание наименовения табличного типа
 @usl dbo.type_tbl_usl readonly, -- указание наименовения табличного типа   
 @stoim numeric(20,2) output, -- стоимость      
 @ksg varchar(100) output, -- КСГ 
 @idcase uniqueidentifier output

Так я объявил переменные для передачи внутрь:

Loc:code_mo         cstring(7)      ! varchar(6), --код медицинской организации
Loc:usl_ok          byte            ! numeric(2,0), -- условия оказания МП
Loc:mo_pac_code     cstring(41)     ! varchar(40), --код пациента
Loc:nhistory        cstring(41)     ! varchar(40), --номер талона/истории
Loc:fam             cstring(41)     ! varchar(40),
Loc:im              cstring(41)     ! varchar(40),
Loc:ot              cstring(41)     ! varchar(40),
Loc:w               byte            ! numeric(1,0), -- пол: 1 - мужской, 2 - женский
Loc:dr              string(10)      !   date, --дата рождения
Loc:profil_t        cstring(4)      ! varchar(3), --профиль
Loc:pr_vidpol       byte            ! as numeric(1), -- тип МП в поликлинике: заболевание - 1, профилактика - 2, неотложная помощь - 3
Loc:pr_feld         byte            ! as numeric(1), -- тип медперсонала 1 - врач, 2 - младший МП
Loc:scode           cstring(21)     ! varchar(20),-- код услуги
Loc:mkb             cstring(11)     ! varchar(10),  -- мкб основное
Loc:mkb2            cstring(11)     ! varchar(10), -- сопутствующее
Loc:mkb3            cstring(11)     ! varchar(10), -- осложнения
Loc:kol_du          decimal(10,2)   ! numeric(10,2), -- кол-во дней, посещений, услуг
Loc:ishod           cstring(2)      ! varchar(1), --исход
Loc:date_in         string(10)      !   date, --дата начала лечения
Loc:date_out        string(10)      !   date, --дата окончания лечения
Loc:death           byte            !   int, --признак смерти
Loc:oper            string(100)     !   dbo.type_tbl_oper readonly, -- указание наименовения табличного типа
Loc:usl             string(100)     !   dbo.type_tbl_usl readonly, -- указание наименовения табличного типа
Loc:stoim           decimal(20,2)   ! numeric(20,2) output, -- стоимость
Loc:ksg             cstring(101)    ! varchar(100) output, -- КСГ
Loc:idcase          string(50)      !   uniqueidentifier output


Вызов хранимки:

Loc:SQLExp = 'CALL sp_stoim(''' &Loc:code_mo& ''',' &Loc:usl_ok& ',' &Loc:mo_pac_code& ',' &Loc:nhistory& ',' |
                &Loc:fam& ',' &Loc:im& ',' &Loc:ot& ',' &Loc:w& ',' &Loc:dr& ',' &Loc:profil_t& ','       |
                &Loc:pr_vidpol& ',' &Loc:pr_feld& ',' &clip(Loc:scode)& ',' &Loc:mkb& ',' &Loc:mkb2& ','        |
                &Loc:mkb3& ',' &Loc:kol_du& ',' &Loc:ishod& ',' &Loc:date_in& ',' &Loc:date_out& ','      |
                &Loc:death& ',' &clip(Loc:oper)& ',' &clip(Loc:usl)& ',' &Loc:stoim& ',' &Loc:ksg& ',' &clip(Loc:idcase)& ')'
sluch{Prop:SQL} = clip(Loc:SQLExp)

Rimantas Nedzinskas

unread,
Mar 26, 2015, 12:36:17 PM3/26/15
to cla...@googlegroups.com
Надо EXEC вместо CALL

Римас 

--
Вы получили это сообщение, поскольку подписаны на группу "ClaList".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.

Игорь Стригунков

unread,
Mar 26, 2015, 12:46:55 PM3/26/15
to cla...@googlegroups.com
Привет
 
Сдается мне, что строковые значения и даты должны быть в одиночных кавычках, в т.ч. "пустые" строки должны быть '' 
 
 
 
 
26.03.2015, 19:32, "IgLowy" <igl...@mail.ru>:
--
Вы получили это сообщение, поскольку подписаны на группу "ClaList".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Nikolay Tsigouro

unread,
Mar 26, 2015, 3:03:30 PM3/26/15
to ClaList

Что-то у тебя мало закавыченных параметров...

По хорошему, даты лучше вводить через CONVERT или CAST, чтобы работало не зависимо от дефолтного формата дат. И вообще, подстановка строки там, где хранимка ожидает дату скорее всего не прокатит.
Т. е. в клаше форматируешь дату в один из  скульных форматов, а в вызове хранимки превращаешь эту строку в дату.

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

26 Мар 2015 г. 17:32 пользователь "IgLowy" <igl...@mail.ru> написал:


>
> Возвращаюсь к своему старому вопросу
>

>


> Окончательную версию программы нам прислали только в конце февраля. На этой неделе взялся за разработку своего варианта программы.
> пробовал для начала сделать свою простенькую хранимку - работает. потом стал вызывать нужную мне хранимку - не вызывается.
> делаю вызов хранимки и получаю ошибку. 
> это фрагмент лога:
>
> 013F8H(1) 18:35:07.783 Executing Statement 0532830H:CALL sp_stoim('690111',1, ,1,ВВВВВВВВ,ВВВВВВВВ,ВВВВВВВВ,1,2015-01-01,031,1,1,,K35.8,K35.8,K35.8,1,1,2015-01-01,2015-01-01,0,,,0,2,)
> 013F8H(1) 18:35:07.798 Error Occurred: 37000 [Microsoft][ODBC SQL Server Driver][SQL Server]Неправильный синтаксис около конструкции "690111".
> 013F8H(1) 18:35:07.798  Time Taken:0.02 secs
> 013F8H(1) 18:35:07.798 SET_PROPERTY(dbo.sluch:016A030H) Неправильный синтаксис около конструкции "690111". Time Taken:0.02 secs
>
> на какую ошибку может указывать такое сообщение?
> часть параметров у меня заменены пока на более простые типы, какие-то типы я мог указать неправильно, вместо списков пока использую пустые строки. может ли это приводить к ошибке?

Легко. Я думаю, что вместо пустых списков нужно NULL передавать, а никак не строки. Список и строка - существенно разные типы, и про автоматическое клашино преобразование типов забудь!  Все преобразования типов только явно.

А вообще-то, тебе давали ссылку, как списки формировать и передавать.  RTFM что говорит?

Как ты их объявил, по большому счету, до фонаря. Это не поля таблиц. Важно, как ты из них скульный оператор сформируешь.

Рекомендую для передачи строк написать (в клаше) форматирующую функцию, которая задвоит кавычки и обработает прочие спецсимволы.

IgLowy

unread,
Mar 26, 2015, 3:11:24 PM3/26/15
to cla...@googlegroups.com
Это из-за возвращаемых значений c аттрибутом output? да, в тестовой хранимке возвращаемых значений у меня не было.


Четверг, 26 марта 2015, 16:36 UTC от Rimantas Nedzinskas <r40...@gmail.com>:
С уважением, IgLowy

IgLowy

unread,
Mar 26, 2015, 3:12:59 PM3/26/15
to cla...@googlegroups.com
Пробовал строковые значения передавать с кавычками и без, вроде проходило нормально.
когда вызов хранимки заработает, параметры буду проверять дополнительно.


Четверг, 26 марта 2015, 19:46 +03:00 от Игорь Стригунков <strig...@yandex.ru>:
С уважением, IgLowy

IgLowy

unread,
Mar 26, 2015, 3:35:44 PM3/26/15
to cla...@googlegroups.com



Четверг, 26 марта 2015, 22:03 +03:00 от Nikolay Tsigouro <n.tsi...@gmail.com>:

Что-то у тебя мало закавыченных параметров...

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

По хорошему, даты лучше вводить через CONVERT или CAST, чтобы работало не зависимо от дефолтного формата дат. И вообще, подстановка строки там, где хранимка ожидает дату скорее всего не прокатит.
Т. е. в клаше форматируешь дату в один из  скульных форматов, а в вызове хранимки превращаешь эту строку в дату.

спасибо, учту.

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


С уважением, IgLowy

IgLowy

unread,
Mar 27, 2015, 3:19:06 AM3/27/15
to Rimantas Nedzinskas
Здравствуйте, Rimantas.

Вы писали 26 марта 2015 г., 20:36:16:


Надо EXEC вместо CALL

Римас 


Замена не помогла :(  Кавычек понаставил

Loc:SQLExp = 'EXEC sp_test(''' &Loc:code_mo& ''',' &Loc:usl_ok& ',''' &Loc:mo_pac_code& ''',''' &clip(Loc:nhistory)& ''','''        |

                &Loc:fam& ''',''' &Loc:im& ''',''' &Loc:ot& ''',' &Loc:w& ',''' &Loc:dr& ''',''' &Loc:profil_t& ''','               |
                &Loc:pr_vidpol& ',' &Loc:pr_feld& ',''' &clip(Loc:scode)& ''',''' &Loc:mkb& ''',''' &Loc:mkb2& ''','''              |
                &Loc:mkb3& ''',' &Loc:kol_du& ',' &Loc:ishod& ',''' &Loc:date_in& ''',''' &Loc:date_out& ''',' &Loc:death& ','''    |
                &clip(Loc:oper)& ''',''' &clip(Loc:usl)& ''',' &Loc:stoim& ',''' &Loc:ksg& ''',''' &clip(Loc:idcase)& ''')'
sluch{Prop:SQL} = clip(Loc:SQLExp)

Лог:
0408H(1) 09:56:11.814 Executing Statement 0532830H:EXEC sp_test('690111',1,' ','1','ВВВВВВВВ','ВВВВВВВВ','ВВВВВВВВ',1,'2015-01-01','031',1,1,'','K35.8','K35.8','K35.8',1,1,'2015-01-01','2015-01-01',0,'','',0,'2','')
0408H(1) 09:56:11.814 Error Occurred: 37000 [Microsoft][ODBC SQL Server Driver][SQL Server]Неправильный синтаксис около конструкции "690111".
0408H(1) 09:56:11.814  Time Taken:0.00 secs
0408H(1) 09:56:11.814 SET_PROPERTY(dbo.sluch:016A358H) Неправильный синтаксис около конструкции "690111". Time Taken:0.00 secs


Сейчас буду пробовать методом тыка: сделал тестовую хранимку, буду добавлять туда по 1 параметру и смотреть на каком выдаст ошибку.

Юрий Философов

unread,
Mar 27, 2015, 4:17:29 AM3/27/15
to cla...@googlegroups.com
Добрый день! 

Возможно, это не по делу, но даты лучше указывать в формате @d12 - гггммдд, в противном случае результат может зависеть от настройки Set DateFormat 

А вот возврат - там да, формат именно @d10- 

C уважением, 
Юрий Философов 

27 марта 2015 г., 9:09 пользователь IgLowy <igl...@mail.ru> написал:

--
Вы получили это сообщение, поскольку подписаны на группу "ClaList".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.



--
С уважением,
Юрий Философов

Rimantas Nedzinskas

unread,
Mar 27, 2015, 5:07:06 AM3/27/15
to cla...@googlegroups.com
Ну я надеялся что ты погуглишь насчет EXEC :)
Попробуй убрать скобки. И да, дату лучше форматировать @d12.

Когда я делаю подобные вещи, то сначала пробую сформатированный Кларионом SQL запрос выполнить в SQL менеджере:

SETCLIPBOARD(Loc:SQLExp)
MESSAGE('Query in Clipboard')

Я пользуюсь dbForge Studio for SQL Server - бесплатный и сразу показывает ошибки в синтаксисе

Rimas

--

IgLowy

unread,
Mar 27, 2015, 6:06:21 AM3/27/15
to Rimantas Nedzinskas
Здравствуйте, Rimantas.

Вы писали 27 марта 2015 г., 13:07:05:


Ну я надеялся что ты погуглишь насчет EXEC :)
Попробуй убрать скобки. И да, дату лучше форматировать @d12.

Когда я делаю подобные вещи, то сначала пробую сформатированный Кларионом SQL запрос выполнить в SQL менеджере:

SETCLIPBOARD(Loc:SQLExp)
MESSAGE('Query in Clipboard')

Я пользуюсь dbForge Studio for SQL Server - бесплатный и сразу показывает ошибки в синтаксисе

Rimas


да у меня книжка по SQL2000 есть, но там примеров мало. и команда call там не упоминается при описании хранимок.
но в присланных мне советах и в примерах в кларионе использовалась чаще именно call и именно со скобками. а синтаксис sql я плохо знаю, поэтому со скобками или подобными вещами могу и накосячить. :) да мне он и нужен пока только для вызова одной процедурки.
кстати, пока с частью параметров и с call хранимка вызывается.

mikedu...@gmail.com

unread,
Mar 27, 2015, 6:09:48 AM3/27/15
to clalist форум
Мы как всегда позади планеты всей. Весь web уходит с SQL на NoSQL, а мы только начать изучать собрались 😉

Mike

От: IgLowy
Отправлено: ‎пятница‎, ‎27‎ ‎марта‎ ‎2015‎ г. ‎12‎:‎04
Кому: clalist форум

--

IgLowy

unread,
Mar 27, 2015, 8:02:57 AM3/27/15
to cla...@googlegroups.com
Здравствуйте, Mikeduglas66.

Что-то в некоторых письмах текст письма не приходит. хотя в гуглгруппах он есть.

я не ухожу и не прихожу на sql, мне просто приходится вызывать хранимку с расчётом из чужой задачи.


Вы писали 27 марта 2015 г., 14:08:36:

IgLowy

unread,
Mar 27, 2015, 8:09:30 AM3/27/15
to Rimantas Nedzinskas


пытаюсь параметру табличного типа подсунуть переменную varchar. ругается на несовпадение типов.
"Конфликт типов операндов: varchar несовместим с type_tbl_oper"

есть возможность его обмануть и подсунуть ему пока пустышку?

Rimantas Nedzinskas

unread,
Mar 27, 2015, 8:22:07 AM3/27/15
to cla...@googlegroups.com
Не понял, что и куда пытаешься подсунуть. Можно подробней, что надо сделать?

Римас 

--

IgLowy

unread,
Mar 27, 2015, 9:01:37 AM3/27/15
to Rimantas Nedzinskas
Здравствуйте, Rimantas.

Вы писали 27 марта 2015 г., 16:22:06:


Не понял, что и куда пытаешься подсунуть. Можно подробней, что надо сделать?

Римас 


в хранимке есть 2 параметра:
    @oper                        dbo.type_tbl_oper readonly,        
    @usl                        dbo.type_tbl_usl  readonly        

пытаюсь передать туда значения.
сначала объявил переменные как vachar, выдало вышеописанную ошибку.
сейчас пытаюсь описать табличный тип:
Loc:SQLExp = 'DECLARE @oper type_tbl_oper; ' &   |
             'CALL test(''' &Loc:code_mo& ''',' &Loc:usl_ok& ',''' &Loc:mo_pac_code& ''',''' &clip(Loc:nhistory)&   |
...
ругается на объявление:
Неправильный синтаксис около конструкции "CALL"

Rimantas Nedzinskas

unread,
Mar 27, 2015, 10:26:29 AM3/27/15
to cla...@googlegroups.com
CALL и NORESULTCALL - это ключевые слова для Клашиного SQL драйвера, которые драйвер должен преобразовать в правильний вызов процедуры для целевого сервера БД (в данном случае EXECUTE ...)

Если тебе не надо получить данные из этой процедуры, то нужно писать правильный с точки зрения сервера БД скрипт, со всеми декларациями и пр. 

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

Я не большой знаток Кларион - методов вызова процедур, т.к. работаю с MAV ODBC библиотекой.

Римас 
 

--

Nikolay Tsigouro

unread,
Mar 27, 2015, 10:29:33 AM3/27/15
to ClaList

Я же писал - NULL

27 Мар 2015 г. 15:09 пользователь "IgLowy" <igl...@mail.ru> написал:
--

IgLowy

unread,
Mar 27, 2015, 12:07:33 PM3/27/15
to Rimantas Nedzinskas
Здравствуйте, Rimantas.

Вы писали 27 марта 2015 г., 18:26:28:


CALL и NORESULTCALL - это ключевые слова для Клашиного SQL драйвера, которые драйвер должен преобразовать в правильний вызов процедуры для целевого сервера БД (в данном случае EXECUTE ...)

Если тебе не надо получить данные из этой процедуры, то нужно писать правильный с точки зрения сервера БД скрипт, со всеми декларациями и пр. 

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

Я не большой знаток Кларион - методов вызова процедур, т.к. работаю с MAV ODBC библиотекой.

Римас 
 


у меня возврат данных через параметры процедуры. пользоваться call или exec мне безразлично.
процедуру с простыми параметрами написать не выйдет. я на кларионе должен сформировать все данные и передать в хранимку. я предлагал разработчику брать данные для расчёта из таблиц БД, в которые я и писал бы, но он предпочитает использовать какие-то промежуточные структуры, а потом уже одной хранимкой делать расчёт и записывать и сами исходные данные и результат в БД.
у меня, похоже, проблема с описанием табличного типа.

IgLowy

unread,
Mar 27, 2015, 12:11:02 PM3/27/15
to Nikolay Tsigouro
Здравствуйте, Nikolay.

Вы писали 27 марта 2015 г., 18:29:33:


Я же писал - NULL
Извини, мой косяк. я прочитал только начало твоего ответа. задёргали другими вопросами.

Олег А. Руденко

unread,
Mar 27, 2015, 2:35:26 PM3/27/15
to IgLowy
Здравствуйте, IgLowy!

Так предложили очень хорошее решение - попробуй сначала вызвать
эту хранимку из sql-менеджера.
По крайней мере, сразу выяснишь правильные форматы параметров.
И вообще, совет - любые sql-запросы сначала проверяй в sql-менеджере
и только после их отладки вставляй их уже в Клашин код.
По другому очень сложно выловить ошибки!

Еще по твоему случаю, учитывая непонятные типы некоторых параметров хранимки,
могу посоветовать такой вариант:
1. Добиваемся безошибочного вызова этой хранимки из sql-менеджера
2. Пишем хранимку-обертку, в которой все необходимые данные берем из
временной таблички и вызываем нужную нам хранимку
3. В Клашиной проге нужные данные заносим во временную табличку и вызываем
хранимку-обертку, после чего берем результат из результирующей таблицы.
В этом случае можно вообще обойтись без каких-либо параметров - входные данные
заносим во временную табличку а результаты берем из результирующей таблицы!

пятница, 27 марта 2015 г., Вы писали:


--
Вы получили это сообщение, поскольку подписаны на группу "ClaList".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес
clalist+u...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке
https://groups.google.com/d/optout.


=============================
С уважением, Олег А. Руденко.
Oleg_R...@mail.ru

Nikolay Tsigouro

unread,
Mar 28, 2015, 11:58:03 AM3/28/15
to ClaList


27 марта 2015 г., 21:33 пользователь Олег А. Руденко <Oleg_R...@mail.ru> написал:
Здравствуйте, IgLowy!


Еще по твоему случаю, учитывая непонятные типы некоторых параметров хранимки,

Ему уже (прошлый раз) дали ссылку на MSDN по этим типам.
 
могу посоветовать такой вариант:
1. Добиваемся безошибочного вызова этой хранимки из sql-менеджера
2. Пишем хранимку-обертку, в которой все необходимые данные берем из
временной таблички и вызываем нужную нам хранимку

Строго говоря, для создания хранимки нужно иметь соответствующие права. В своей БД проблем обычно не возникает, а вот если админ чужой, боюсь ему будет трудно обосновать необходимость в таких правах в данном случае.
 
3. В Клашиной проге нужные данные заносим во временную табличку и вызываем
хранимку-обертку, после чего берем результат из результирующей таблицы.
В этом случае можно вообще обойтись без каких-либо параметров - входные данные
заносим во временную табличку а результаты берем из результирующей таблицы!

А что страшного в передаче параметров и получении через них результата? Зачем лишние телодвижения с промежуточными таблицами?

WBR, Nikolay Tsigouro

IgLowy

unread,
Mar 30, 2015, 5:06:00 AM3/30/15
to Олег А. Руденко
Здравствуйте, Олег.

Вы писали 27 марта 2015 г., 22:33:32:

> Здравствуйте, IgLowy!

> Так предложили очень хорошее решение - попробуй сначала вызвать
> эту хранимку из sql-менеджера.
> По крайней мере, сразу выяснишь правильные форматы параметров.
> И вообще, совет - любые sql-запросы сначала проверяй в sql-менеджере
> и только после их отладки вставляй их уже в Клашин код.
> По другому очень сложно выловить ошибки!
Стесняюсь спросить, а о каком sql-менеджере идёт речь? под ним имеется ввиду какая-то из функций SQL Server Management Studio или это отдельный продукт?
у меня опыт работы с sql сервером всего пара дней :)


> Еще по твоему случаю, учитывая непонятные типы некоторых параметров хранимки,
> могу посоветовать такой вариант:
> 1. Добиваемся безошибочного вызова этой хранимки из sql-менеджера
> 2. Пишем хранимку-обертку, в которой все необходимые данные берем из
> временной таблички и вызываем нужную нам хранимку
> 3. В Клашиной проге нужные данные заносим во временную табличку и вызываем
> хранимку-обертку, после чего берем результат из результирующей таблицы.
> В этом случае можно вообще обойтись без каких-либо параметров - входные данные
> заносим во временную табличку а результаты берем из результирующей таблицы!

ну с некоторыми вещами я уже разобрался. к сожалению, время приходится выкраивать среди прочих задач.
сегодня прислали очередной приказ Минздрава о проведении конкурса на лучшую регистратуру. конкурс начался с 1 марта :) там надо бумажные анкеты и электронные. электронные придётся мне делать и на инфомат запихивать. так что скучать не дают :)

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

мне сейчас хотелось бы понять некоторые вещи, связанные с использованием типов данных и объектов, описанных на сервере, которые мне надо использовать в своей программе.
с таблицами всё понятно: описываем в словаре, открываем в программе и юзаем. с хранимкой тоже вроде ясно: чёрный ящик, который вызываем по имени и которому скармливаем параметры.
но мне не очень понятно с типами, описанными на сервере. параметры табличного типа, которые мне надо сформировать перед вызовом хранимки, описаны на сервере http://prntscr.com/6n5zyv
вот rtfm по ним https://msdn.microsoft.com/ru-ru/library/bb510489.aspx
правильно ли мне перед вызовом хранимки описать самому эти типы заново, как я это делаю в кларионе с таблицами или каким-то образом я могу использовать уже сделанное на сервере описание? не должно ли использование ссылки на этот тип в тексте sql-запроса в стиле
DECLARE @oper AS type_tbl_oper
автоматически брать описание типа с сервера?
или таки мне надо, как в примере, написать что-то типа:
CREATE TYPE type_tbl_oper AS TABLE ... ?
и насколько корректно использовать оператор create в данном контексте? думаю, что нет. ведь тип уже есть на сервере, а я его пытаюсь создать заново.

IgLowy

unread,
Mar 30, 2015, 5:06:42 AM3/30/15
to Nikolay Tsigouro
Здравствуйте, Nikolay.

Вы писали 28 марта 2015 г., 19:58:02:




> Строго говоря, для создания хранимки нужно иметь соответствующие
> права. В своей БД проблем обычно не возникает, а вот если админ
> чужой, боюсь ему будет трудно обосновать необходимость в таких
> правах в данном случае.
админом базы у нас являюсь я. права раздать пользователям я могу. тем более, разработчик сделал так, что все пользователи имеют в базе права owner. но трогать базу мне не хочется из-за ежемесячного обновления базы и программы. пока неизвестно, как они будут проходить.

Nikolay Tsigouro

unread,
Mar 30, 2015, 6:03:15 AM3/30/15
to ClaList

30 марта 2015 г., 11:00 пользователь IgLowy <igl...@mail.ru> написал:

Здравствуйте, Олег.

Вы писали 27 марта 2015 г., 22:33:32:

> Здравствуйте, IgLowy!

> Так предложили очень хорошее решение - попробуй сначала вызвать
> эту хранимку из sql-менеджера.
> По крайней мере, сразу выяснишь правильные форматы параметров.
> И вообще, совет - любые sql-запросы сначала проверяй в sql-менеджере
> и только после их отладки вставляй их уже в Клашин код.
> По другому очень сложно выловить ошибки!
Стесняюсь спросить, а о каком sql-менеджере идёт речь? под ним имеется ввиду какая-то из функций SQL Server Management Studio или это отдельный продукт?
у меня опыт работы с sql сервером всего пара дней :)

Любой. Лишь бы умел подключаться и запросы выполнять ;-)  Родной (SQL SMS) тоже вполне годится.
 
использовать временные таблички можно, но я и так собираюсь вести свои таблицы в формате tps, чтобы не трогать базу присланной программы. делать дополнительные таблицы не хотелось бы.

Не предвижу проблем - сделай свою схему и работай в ней, сколько душе угодно.
 
ещё и хранимка  сама пишет данные в серверные таблицы. делать изменения на сервере - тем более не хочется. ФОМС должен каждый месяц присылать обновления таблиц и хранимок. в прошлую пятницу прислали первое обновление программы. народ уже жалуется на косяки после обновления. что они там поменяли и как...

мне сейчас хотелось бы понять некоторые вещи, связанные с использованием типов данных и объектов, описанных на сервере, которые мне надо использовать в своей программе.
с таблицами всё понятно: описываем в словаре, открываем в программе и юзаем. с хранимкой тоже вроде ясно: чёрный ящик, который вызываем по имени и которому скармливаем параметры.
но мне не очень понятно с типами, описанными на сервере. параметры табличного типа, которые мне надо сформировать перед вызовом хранимки, описаны на сервере http://prntscr.com/6n5zyv
вот rtfm по ним https://msdn.microsoft.com/ru-ru/library/bb510489.aspx
правильно ли мне перед вызовом хранимки описать самому эти типы заново, как я это делаю в кларионе с таблицами или каким-то образом я могу использовать уже сделанное на сервере описание?

Конечно. Просто объявляешь переменную этого типа и работаешь с ней, как с таблицей соответствующей структуры.
 
не должно ли использование ссылки на этот тип в тексте sql-запроса в стиле
DECLARE @oper AS type_tbl_oper
автоматически брать описание типа с сервера?
или таки мне надо, как в примере, написать что-то типа:
CREATE TYPE type_tbl_oper AS TABLE ... ?
и насколько корректно использовать оператор create в данном контексте? думаю, что нет. ведь тип уже есть на сервере, а я его пытаюсь создать заново.

У тебя там в MSDN в конце статьи пример приведен. Тебе из него нужно взять все, что после 
/* Declare a variable that references the type. */
и адаптировать под свои нужды - объявить свои табличные переменные и заполнить таблицы своими данными. Затем вызвать свою процедуру. 
Все это желательно сделать одним Prop:SQL. Т.е. сначала сгенерировать скрипт в строковую переменную, а затем его выполнить.
PS. В данном случае, я бы завел на MSSQL свои таблички для этих типов и заполнил их в клаше, 
а заполнение табличных переменных сделал как в примере выборкой из этих таблиц - INSERT ... SELECT.
Тогда гарантировано не налетишь на ограничение по длине ODBC запроса (ка-ца 4 Кб). 
Не так эффективно, но зато попроще будет.
PPS. А там глядишь и всю свою задачу на скуль перетащишь ;-)) Успеха.
WBR, Nikolay Tsigouro

Сергей Половинкин

unread,
Mar 30, 2015, 7:32:18 AM3/30/15
to cla...@googlegroups.com
Здравствуйте, IgLowy!
Вот что нарыл у себя -может поможет...

Текст:
Марков Юрий Альбертович

"Что же делать, если процедура возвращает результат в OUTPUT параметре?
Я и в этом случае использую PROP:SQL / NEXT. Только пишу более сложный SQL запрос. Вот один из примеров такого рода:"


DummyView view(Dummy)
project(Dummy:S)
end

open(Dummy); open(DummyView)

DummyView{PROP:SQL} = |
'declare @str varchar(32)<10>' & |
'exec GetCardStr 582, @str output<10>' & |
'select @str'

if errorcode() = 90
stop(Dummy{PROP:SQL} & '<10>' & fileerror())
end

next(DummyView); CardStr = Dummy:S
Здесь запрос, посылаемый на сервер, состоит из трех SQL команд. Сначала описывается рабочая переменная:
declare @str varchar(32)
Затем выполняется вызов хранимой процедуры:
exec GetCardStr 582, @str output
Первый параметр процедуры - типа INPUT, второй - OUTPUT. Процедура возвращает результат в рабочую переменную @str. И, наконец:
select @str
Это и есть тот самый SELECT, результат которого получает с помощью NEXT кларионовская программа.
Обратите внимание на вызов хранимой процедуры. Здесь используется ключевое поле EXEC вместо CALL и список параметров не заключается в скобки.
Дело в том, что этот вызов - часть SQL предложения на языке T-SQL (MS SQL Server). Для ODBC драйвера все это вместе - просто SQL запрос, содержащий SELECT.


===========================
С уважением Сергей Половинкин
sap...@yandex.ru


IgLowy

unread,
Mar 30, 2015, 7:34:07 AM3/30/15
to Nikolay Tsigouro
Здравствуйте, Nikolay.

Вы писали 30 марта 2015 г., 14:03:13:


>> Стесняюсь спросить, а о каком sql-менеджере идёт речь? под ним
>> имеется ввиду какая-то из функций SQL Server Management Studio или
>> это отдельный продукт?
>> у меня опыт работы с sql сервером всего пара дней
> Любой. Лишь бы умел подключаться и запросы выполнять Родной (SQL
> SMS) тоже вполне годится.
по кнопке "создать запрос" в панели инструментов - это он вызывается?

> Не предвижу проблем - сделай свою схему и работай в ней, сколько душе угодно.
я пока рассматриваю вопрос объединения разных кусков, которые я писал для разных задач в одно целое. в планах перехода на скуль нет. :) переводить на скуль отдельные куски, имхо, не стоит в любом случае.


>> правильно ли мне перед вызовом хранимки описать самому эти типы
>> заново, как я это делаю в кларионе с таблицами или каким-то образом
>> я могу использовать уже сделанное на сервере описание?
> Конечно. Просто объявляешь переменную этого типа и работаешь с ней,
> как с таблицей соответствующей структуры.

> У тебя там в MSDN в конце статьи пример приведен. Тебе из него нужно
> взять все, что после
> /* Declare a variable that references the type. */
> и адаптировать под свои нужды - объявить свои табличные переменные
> и заполнить таблицы своими данными. Затем вызвать свою процедуру.
> Все это желательно сделать одним Prop:SQL. Т.е. сначала
> сгенерировать скрипт в строковую переменную, а затем его выполнить.
я так и делаю. формирую в строку перечень операторов, потом её присваиваю в Prop:SQL. я приводил тут кусок кода. пока строка вписывалась в 1к.

> PS. В данном случае, я бы завел на MSSQL свои таблички для этих типов и заполнил их в клаше,
> а заполнение табличных переменных сделал как в примере выборкой из этих таблиц - INSERT ... SELECT.
> Тогда гарантировано не налетишь на ограничение по длине ODBC запроса (ка-ца 4 Кб).
> Не так эффективно, но зато попроще будет.
мне потом надо будет ещё сделать расчёт стоимости за месяц. поэтому эффективность тоже будет нужна.

Nikolay Tsigouro

unread,
Mar 30, 2015, 7:48:35 AM3/30/15
to ClaList

30 марта 2015 г., 13:31 пользователь IgLowy <igl...@mail.ru> написал:
Здравствуйте, Nikolay.

Вы писали 30 марта 2015 г., 14:03:13:

> Любой. Лишь бы умел подключаться и запросы выполнять    Родной (SQL
>  SMS) тоже вполне годится.
по кнопке "создать запрос" в панели инструментов - это он вызывается?
 
Да.
 
> Все это желательно сделать одним Prop:SQL. Т.е. сначала
> сгенерировать скрипт в строковую переменную, а затем его выполнить.
я так и делаю. формирую в строку перечень операторов, потом её присваиваю в Prop:SQL. я приводил тут кусок кода. пока строка вписывалась в 1к.

Тебе придется на каждое значение в таблице свой отдельный INSERT сгенерировать. Там букв в нагрузку много пойдет.
 
мне потом надо будет ещё сделать расчёт стоимости за месяц. поэтому эффективность тоже будет нужна.

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

Nikolay Tsigouro

unread,
Mar 30, 2015, 8:00:09 AM3/30/15
to ClaList
А почему просто не забиндить параметр(ы)? И входные, и выходные, чтобы не заниматься форматированием и парсингом?

NORESULTCALL
The SQL Accelerator drivers also allow the syntax 'NORESULTCALL storedprocedure' for stored
procedures that do not return a result set.
Example:
MyFile{PROP:SQL} = 'NORESULTCALL SelectRecordsProcedure (&MyVar[INOUT])'

См. DatabaseDrivers.pdf, Calling a Stored Procedure. 

WBR, Nikolay Tsigouro

30 марта 2015 г., 14:32 пользователь Сергей Половинкин <s.polo...@vaz.ru> написал:
--
Вы получили это сообщение, поскольку подписаны на группу ClaList.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/d/optout.

Sergey Polovinkin

unread,
Mar 30, 2015, 8:17:37 AM3/30/15
to cla...@googlegroups.com
 Да можно, вот оттуда

Example:

PROGRAM

MAP

CallProc(STRING)

END

MyFile FILE,DRIVER('MSSQL')

Record RECORD

c LONG

END

END

Ret LONG

Out STRING(10)

CODE

BIND('RetCode', Ret)

BIND('Out', Out)

CallProc('&RetCode = CALL StoredProcTest(''1'',&Out)')

MESSAGE(Return value of StoredProcTest =' & Ret)

MESSAGE(Output parameter of StoredProcTest =' & Out)

CallProc PROCEDURE(Str)

CODE

MyFile{PROP:SQL} = Str

  ===========================
  С уважением Сергей Половинкин

понедельник, 30 марта 2015 г., 16:00:09 UTC+4 пользователь Nick Tsigouro написал:

Nikolay Tsigouro

unread,
Mar 30, 2015, 11:30:59 AM3/30/15
to ClaList
 IgLowy и др.

Из-за разного представления даты и времени забиндить date не получится. Тут придется форматировать и парсить. 

WBR, Nikolay Tsigouro

30 марта 2015 г., 15:17 пользователь Sergey Polovinkin <s.polo...@vaz.ru> написал:

IgLowy

unread,
Apr 2, 2015, 7:55:01 AM4/2/15
to cla...@googlegroups.com
что в кларионе соответствует типу uniqueidentifier?
по описанию это 16 байтовое целое.
пытался подсунуть и число и строку ругается, что типы numeric и varchar не совместимы с uniqueidentifier.

Nikolay Tsigouro

unread,
Apr 2, 2015, 8:37:15 AM4/2/15
to ClaList
Это GUID. Импортни табличку в dct и увидишь.

Мы объявляли как 
OBJ_GUID                    CSTRING(37)

WBR, Nikolay Tsigouro

2 апреля 2015 г., 13:52 пользователь IgLowy <igl...@mail.ru> написал:

--

IgLowy

unread,
Apr 2, 2015, 8:50:19 AM4/2/15
to Nikolay Tsigouro
Здравствуйте, Nikolay.

как раз к твоему ответу нашёл вариант решения :)

сделал так. описал переменную типа string(36), вставил туда содержимое типа "BCBB0E18-4B10-4490-ABB2-0043D79E1942", передаваемое значение заключил в кавычки. вызов прошёл, значение записалось в базу.
в случае cstring действительно придётся удлинить строку на символ. наверно правильнее использовать cstring
а "пустое" значение для этого типа - когда в строке все нули?

Вы писали 2 апреля 2015 г., 16:37:14:

Nikolay Tsigouro

unread,
Apr 2, 2015, 9:02:02 AM4/2/15
to ClaList
Пустое - это для большинства типов - NULL. Строго говоря, не "пустое", а "не указано", "не известно", "не задано",...
Вопрос только с интерпретацией "пустая" для строк. Бывает "пустая строка" - '' и "не указано" - NULL. И это сильно разные вещи.

WBR, Nikolay Tsigouro

2 апреля 2015 г., 14:47 пользователь IgLowy <igl...@mail.ru> написал:

IgLowy

unread,
Apr 2, 2015, 9:13:27 AM4/2/15
to Nikolay Tsigouro
Здравствуйте, Nikolay.

Вы писали 2 апреля 2015 г., 17:02:01:

> Пустое - это для большинства типов - NULL. Строго говоря, не
> "пустое", а "не указано", "не известно", "не задано",...
> Вопрос только с интерпретацией "пустая" для строк. Бывает "пустая
> строка" - '' и "не указано" - NULL. И это сильно разные вещи.
этот id используется для обращения к уже сохранённой записи. не хотелось бы формировать его самому. хотел подсунуть "пустышку".

в связи с NULL тоже есть вопрос: как его задать для переменной или параметра? функция setnull и подобные ей применяются только к полю таблицы. конечно, могу для передачи данных объявить отдельную таблицу, но возможно это сделать как-то иначе?

Nikolay Tsigouro

unread,
Apr 2, 2015, 10:31:07 AM4/2/15
to ClaList
Me его формировали на сервере, хотя можно и через WINAPI:

Hide:Access:STD_OBJ.Insert PROCEDURE

ReturnValue          BYTE,AUTO

  CODE
  ASSERT(ASSERT_FLAG, 'B Insert STD_OBJ (OBJ_ID = ' & STD_OBJ:OBJ_ID & ', OBJ_GUID = ' & STD_OBJ:OBJ_GUID & ', CLASS_EQU = ' & STD_OBJ:CLASS_EQU & ')')
  IF STD_OBJ:OBJ_GUID = ''
     SQL_STR1{PROP:SQL} = 'SELECT NEWID()'
     If Access:SQL_STR1.Next() = Level:Benign
       STD_OBJ:OBJ_GUID = SQL_STR1.STR1
       STD_OBJ.OBJ_GUID{PROP:NAME} = 'OBJ_GUID'
     else
       Return Level:Notify
     end
  end
  ReturnValue = PARENT.Insert()
  IF ReturnValue = Level:Benign
     ReturnValue = AutoIncRefresh(Access:STD_OBJ, STD_OBJ:PK_STD_OBJ, STD_OBJ:OBJ_ID)
  END
  
  ASSERT(ASSERT_FLAG, 'A Insert STD_OBJ (OBJ_ID = ' & STD_OBJ:OBJ_ID & ', OBJ_GUID = ' & STD_OBJ:OBJ_GUID & ', CLASS_EQU = ' & STD_OBJ:CLASS_EQU & '), ReturnValue = ' & ReturnValue)
  RETURN ReturnValue

Можно NEWID() прописать в DEFAULT колонки, тогда вообще ничего делать не надо, но нужно как-то его узнать.
Поэтому мы его формировали сами, и потом после INSERT делали Get по этому ключевому полю и получали автоинкрементый ID.

Чтобы он (базовый объект) после создания никогда не менялся у нас еще по нему прописано следующее:

Hide:Access:STD_OBJ.TryUpdate PROCEDURE

ReturnValue          BYTE,AUTO

  CODE
  Return  Level:Benign        ! Базовый объект STD_OBJ не полдлежит модификации никогда
  ReturnValue = PARENT.TryUpdate()
  RETURN ReturnValue


Hide:Access:STD_OBJ.Update PROCEDURE

ReturnValue          BYTE,AUTO

  CODE
  Return  Level:Benign        ! Базовый объект STD_OBJ не полдлежит модификации никогда
  ReturnValue = PARENT.Update()
  RETURN ReturnValue

Ну, а сама табличка выглядит так:

В кларионе:

TN:STD_OBJ           CSTRING(261),THREAD                   ! [PATCH] Multi dct extension 26.02.2008 НЦ
STD_OBJ              FILE,DRIVER('MSSQL',Pub:DriverString),OWNER(Pub:ConnectionString),NAME(TN:STD_OBJ),PRE(STD_OBJ),BINDABLE,THREAD
PK_STD_OBJ               KEY(STD_OBJ:OBJ_ID),PRIMARY
FR_STD_OBJ__STD_CLASS    KEY(STD_OBJ:CLASS_EQU),DUP
UK_STD_OBJ__OBJ_GUID     KEY(STD_OBJ:OBJ_GUID)
Record                   RECORD,PRE()
OBJ_ID                      LONG,NAME('OBJ_ID | READONLY')
OBJ_GUID                    CSTRING(37)
CLASS_EQU                   LONG
OBJ_VERSION                 STRING(8),NAME('OBJ_VERSION | READONLY')
                         END
                     END                       

В МS SQL:

CREATE TABLE [dbo].[STD_OBJ] (
  [OBJ_ID] int IDENTITY(1, 1) NOT NULL,
  [OBJ_GUID] uniqueidentifier NOT NULL,
  [CLASS_EQU] int NOT NULL,
  [OBJ_VERSION] timestamp NOT NULL,
  CONSTRAINT [PK_STD_OBJ] PRIMARY KEY CLUSTERED ([OBJ_ID])
)
ON [PRIMARY]
GO

EXEC sp_bindefault '[dbo].[DF_GUID]', '[dbo].[STD_OBJ].[OBJ_GUID]'
GO

CREATE UNIQUE NONCLUSTERED INDEX [UK_STD_OBJ__OBJ_GUID] ON [dbo].[STD_OBJ]
  ([OBJ_GUID])
ON [PRIMARY]
GO

+ триггеры протоколирования.

Все внутрибазовые связи проложены по OBJ_ID, а OBJ_GUID предусмотрен для обмена с другими базами.

NULL в тексте SQL DML прямо так и пишется: ' ..., NULL, ...'

WBR, Nikolay Tsigouro

2 апреля 2015 г., 15:10 пользователь IgLowy <igl...@mail.ru> написал:
--
Вы получили это сообщение, поскольку подписаны на группу ClaList.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес clalist+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages