23.09.2005, 15:57 | #1 |
Участник
|
И вновь о вызове хранимой из Аксапты
Вообщем вот код
static void run() { Connection connection; Statement stmt; str sqlS; ; connection = new Connection(); stmt = connection.createStatement(); sqlS = 'EXECUTE [AXTest].[dbo].[GET_DISC_CARD_REP] Count_Buys0, Count_Buys1, Count_Buys2, Count_Buys3, Count_Buys4, Actual_Period, Date_Start, Date_End'; } Сервак на MSSQL "EXECUTE [AXTest].[dbo].[GET_DISC_CARD_REP] Count_Buys0, Count_Buys1, Count_Buys2, Count_Buys3, Count_Buys4, Actual_Period, Date_Start, Date_End" входные параметры получаются с диалоговой формы, в Query Analyzer отрабатывается на ура, а в аксапте не хотит, при нажатии на ок ничего не происходит, даже ошибки нет, подскажите в чем может быть проблема |
|
23.09.2005, 16:01 | #2 |
Administrator
|
какой метод исполняет эту строку?
__________________
Возможно сделать все. Вопрос времени |
|
23.09.2005, 16:09 | #3 |
Участник
|
вверху же написано что это метод run
|
|
23.09.2005, 16:32 | #4 |
----------------
|
Где stmt.executeUpdate(sqlS);?
|
|
23.09.2005, 16:44 | #5 |
Участник
|
Упс, нечаянно стер но в коде он есть.
правда не stmt.executeUpdate(sqlS); а stmt.executeQuery(sqlS); Попробовал вместо stmt.executeQuery(sqlS) написать stmt.executeUpdate(sqlS), он мне ошибку выдал "[Microsoft][ODBC SQL Server Driver][SQL Server]Error converting data type nvarchar to int." хотя у меня данные только типа date и int |
|
23.09.2005, 17:06 | #6 |
Administrator
|
вот поэтому я и спросил какой метод - подразумевалось - stmt.executeQuery(sqlS) или stmt.executeUpdate(sqlS)
executeQuery следует исполнять только тогда когда запрос возвращает набор записей. Хранимая процедура не возвращает набор записей (на то она и процедура). Для этого существуют табличные функции А раз так - значит нужно исполнять executeUpdate. А вот уже ODBC-шная ошибка говорит о том, что Axapta пытается исполнить запрос
__________________
Возможно сделать все. Вопрос времени |
|
23.09.2005, 17:26 | #7 |
Участник
|
В упор понять не могу почему эта ошибка возникает...
Входные параметры в процедуре это FromDate и int почему ошибку выдает понять не могу... вот заголовок процедуры ALTER proc dbo.GET_DISC_CARD_REP( @count_buys0 int, @count_buys1 int, @count_buys2 int, @count_buys3 int, @count_buys4 int, @actual_period int, @date_start datetime, @date_end datetime) as |
|
23.09.2005, 17:35 | #8 |
Участник
|
Так вам надо в процедуру передавать значения, а не непонятно что.
"EXECUTE [AXTest].[dbo].[GET_DISC_CARD_REP] 1, 2, 3, 4, 5, 6, '09-23-2005', '09-23-2005'"
__________________
Axapta v.3.0 sp5 kr2 |
|
23.09.2005, 17:39 | #9 |
Участник
|
Так в переменных: Count_Buys0, Count_Buys1, Count_Buys2, Count_Buys3, Count_Buys4, Actual_Period, Date_Start, Date_End и хранятся значения
|
|
23.09.2005, 17:49 | #10 |
Участник
|
А откуда эти переменные, из Axapta'ы?
В MS SQL Server переменные используются так declare @count_buys0 int set @count_buys0 = 0 declare @count_buys1 int set @count_buys1 = 1 declare @count_buys2 int set @count_buys2 = 2 declare @count_buys3 int set @count_buys3 =3 declare @count_buys4 int set @count_buys4 = 4 declare @actual_period int set @count_buys5 = 5 declare @date_start datetime set @date_start = '09-23-2005' declare @date_end datetime set @date_end = '09-23-2005' exec [AXTest].[dbo].[GET_DISC_CARD_REP] @count_buys0, @count_buys1, @count_buys2, @count_buys3, @count_buys4, @count_buys5, @date_start, @date_end
__________________
Axapta v.3.0 sp5 kr2 |
|
23.09.2005, 17:56 | #11 |
Участник
|
Как они в MSSQL используются я знаю
Да, эти переменные с диалоговой формы |
|
23.09.2005, 18:01 | #12 |
Участник
|
обратите внимание
sqlS - это у вас прото строка ... парсить ее и вставлять переменные некому ... , воспользуйтесь strFmt(' ...%1...%2', count_buys0, .... ) С уважением, itfs. |
|
25.09.2005, 11:38 | #13 |
Участник
|
Как я об этом сразу не подумал
Попробовал, все равно проблемы остались, на дату ругается. я уже попробовал в аксапте конвертить дату в строку и в процедуре обратно из строки в дату вот как в аксаптке конвертирую d1 = date2str(ds,123,2,2,2,2,4); d2 = date2str(de,123,2,2,2,2,4); sqlS = strFmt("EXECUTE [AXTest].[dbo].[GET_DISC_CARD_REP] %1, %2, %3, %4, %5, %6, %7, %8", c0, c1, c2, c3, c4, ap, d1, d2) Аксапта выдает такую ошибку "[Microsoft][ODBC SQL Server Driver][SQL Server]Line 1: Incorrect syntax near '.2005'." у переменных ds и de представление в таком виде '10.06.2005' В чем может быть проблема? |
|
25.09.2005, 12:16 | #14 |
Участник
|
Оказывается акспата передает в процедуру дату без кавычек то есть в виде ... 1,2,3, 10.06.2005, ... - как это исправить?
|
|
25.09.2005, 12:39 | #15 |
Administrator
|
ну для начала в строке EXECUTE надо взять соотв параметр (%8) в апострофы .SQL вполне удовлетворяется ими
Аксапта хранит дату как некое число и форматирует его в нужный формат по требованию - как в функции date2str - согласно заданным параметрам. Потом было бы интересно узнать в каком виде воспринимает дату SQL - вроде как по умолчанию в английском формате (ммддгг) - однако настройки у SQL могут быть и русские ... Но я думаю - вариант предложенный AndyD вполне прокатит
__________________
Возможно сделать все. Вопрос времени |
|
25.09.2005, 16:24 | #16 |
Участник
|
Спасибо всем кто помогал!
Вообщем я все доделал, все вроде как работает, но неправильно Вот в чем косяк, процедура в тесте отрабатывает отлично, но вот из аксапты она ведет себя ну очень странно, она выполняется только до того места где в процедуре идет вызов одной функции (самописной), после нее никакие операции не выполняются, с чем это может быть связано, поделитесь мыслями плиз! |
|
25.09.2005, 16:32 | #17 |
Участник
|
Если бы вы привели текст своей процедуры и пример ее вызова, то ответить на ваш вопрос было бы намного проще
__________________
Axapta v.3.0 sp5 kr2 |
|
25.09.2005, 16:49 | #18 |
Участник
|
Без проблем, если вам будет не лень копаться буду признателен
Вот метод run из аксапты void run() { Connection connection; Statement stmt; ResultSet resultSet; str ds; str de; str sqlS; str d1; str d2; ; connection = new Connection(); stmt = connection.createStatement(); d1 = date2str(PeriodBegin,123,2,2,2,2,4); d2 = date2str(PeriodEnd,123,2,2,2,2,4); ds = substr(d1,7,4)+'-'+substr(d1,4,2)+'-'+substr(d1,1,2); de = substr(d2,7,4)+'-'+substr(d2,4,2)+'-'+substr(d2,1,2); sqlS = ("EXECUTE [AXTest].[dbo].[GET_DISC_CARD_REP] %1, %2, %3, %4, %5, %6, '%7', '%8'"); stmt.executeUpdate(strfmt(sqlS, Count_Buys0, Count_Buys1, Count_Buys2, Count_Buys3, Count_Buys4, Actual_Period, ds, de)); super(); } вот сама процедура работа прерывается на вот этой строке: set @work = axtest.dbo.Is_worked(@cod, @count_buys0, @count_buys1, @count_buys2, @count_buys3, @count_buys4, @date_act1, @date_act2); ALTER proc dbo.GET_DISC_CARD_REP( @count_buys0 int, @count_buys1 int, @count_buys2 int, @count_buys3 int, @count_buys4 int, @actual_period int, @date_start1 varchar(20), @date_end1 varchar(20)) as delete from axtest.bmssa.disc_card_rep; DROP TABLE ##DISC_CARD_REP_TMP; CREATE TABLE ##DISC_CARD_REP_TMP ( [DISC_CODE] [varchar] (22) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL , [PRODUCTION] [varchar] (255) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL , [PAY_SUM] [numeric](28, 12) NOT NULL , [DATA] [datetime] NOT NULL , [GROUPS] [varchar] (255) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL , [REP_DATE] [datetime] NULL , [IS_WORK] [int] NULL , [RECID] [int] IDENTITY (1, 1) NOT NULL , CHECK ([RECID] <> 0) ) ON [PRIMARY] declare @date_start datetime; declare @date_end datetime; declare @date_act1 datetime; declare @date_act2 datetime; declare @date_rep1 datetime; declare @date_rep2 datetime; declare @cod varchar(22); declare @work int; set @date_start=cast(@date_start1 as datetime); set @date_end=cast(@date_end1 as datetime); set @date_rep1=@date_start; set @date_rep2=dateadd(dd,-datepart(dd,@date_rep1),dateadd(mm,1,@date_rep1)); while @date_rep2<@date_end begin declare cur1 cursor for select distinct(dc.DISC_CODE) from axtest.dbo.discont_card dc where dc.data between @date_rep1 and @date_rep2; set @date_act1 = dateadd(dd,1-datepart(dd,@date_rep1),dateadd(mm,1-@actual_period,@date_rep1)); set @date_act2 = @date_rep2 open cur1; fetch cur1 into @cod; while @@FETCH_Status=0 begin set @work = axtest.dbo.Is_worked(@cod, @count_buys0, @count_buys1, @count_buys2, @count_buys3, @count_buys4, @date_act1, @date_act2); insert into ##DISC_CARD_REP_TMP(disc_code, production, pay_sum, data, groups) (select dc.disc_code, dc.production, dc.pay_sum, dc.data, groups from axtest.dbo.discont_card dc where dc.disc_code=@cod and dc.data between @date_rep1 and @date_rep2); update ##DISC_CARD_REP_TMP set is_work=@work, rep_date=@date_rep1 where disc_code=@cod; fetch cur1 into @cod; end; close cur1; deallocate cur1; set @date_rep1=dateadd(dd,1,@date_rep2); set @date_rep2=dateadd(dd,-1,dateadd(mm,1,@date_rep1)); end declare cur1 cursor for select distinct(dc.DISC_CODE) from axtest.dbo.discont_card dc where dc.data between @date_rep1 and @date_end; set @date_act1 = dateadd(dd,1-datepart(dd,@date_rep1),dateadd(mm,1-@actual_period,@date_rep1)); set @date_act2 = @date_rep2 open cur1; fetch cur1 into @cod; while @@FETCH_Status=0 begin set @work = axtest.dbo.Is_worked(@cod, @count_buys0, @count_buys1, @count_buys2, @count_buys3, @count_buys4, @date_act1, @date_act2); insert into ##DISC_CARD_REP_TMP(disc_code, production, pay_sum, data, groups) (select dc.disc_code, dc.production, dc.pay_sum, dc.data, groups from axtest.dbo.discont_card dc where dc.disc_code=@cod and dc.data between @date_rep1 and @date_end); update ##DISC_CARD_REP_TMP set is_work=@work, rep_date=@date_rep1 where disc_code=@cod; fetch cur1 into @cod; end; insert into axtest.bmssa.disc_card_rep(disc_code, production, pay_sum, data, groups, rep_date, is_work, recid) (select * from ##DISC_CARD_REP_TMP); close cur1; deallocate cur1; GO ну вот и сама функция ALTER FUNCTION Is_worked( @code char(22), @count_buys0 int, @count_buys1 int, @count_buys2 int, @count_buys3 int, @count_buys4 int, @date_start datetime, @date_end datetime) returns int AS begin declare @is_work int declare @date1 datetime declare @date2 datetime set @is_work = 0; set @date1 = @date_start; set @date2 = @date_start; if @count_buys0 < (select count(*) from drest.dbo.discont_card d_card where d_card.data <= @date_end and d_card.disc_code=@code) set @is_work = 1; if @is_work = 0 begin if @count_buys1 < (select count(*) from drest.dbo.discont_card d_card where d_card.data between @date_start and @date_end and d_card.disc_code=@code) set @is_work = 1; end; if @is_work = 0 begin if @count_buys2 < (select count(*) from drest.dbo.discont_card d_card where d_card.data <= @date_start and d_card.disc_code=@code) set @is_work = 1; end; while (@date2 < @date_end) and (@is_work = 0) begin if @count_buys3 < (select count(*) from drest.dbo.discont_card d_card where d_card.data between @date2 and dateadd(mm,1,@date2) and d_card.disc_code=@code) set @is_work = 1; set @date2 = dateadd(mm,1,@date2); end; while (@date1 > (select min(dc1.data) from drest.dbo.discont_card dc1 where dc1.disc_code=@code) ) and (@is_work = 0) begin if @count_buys4 < (select count(*) from drest.dbo.discont_card d_card where d_card.data between dateadd(mm,-1,@date1) and @date1 and d_card.disc_code=@code) set @is_work = 1; set @date1 = dateadd(mm,-1,@date1); end; return @is_work; end |
|
25.09.2005, 18:17 | #19 |
Участник
|
Я уже попробовал совсем по простому сделать, запихал текст функции в процедуру, теперь она работает до end в цикле while @@FETCH_Status=0, то есть проходит один раз цикл и все, больше не работает
Я уже даже не знаю что думать... почему так происходит, ведь процедуру отрабатывает сервак так? и простой EXECUTE из Query Analizer с тестовыми переменными тоже отрабатывает тотже сервак, так почему результат такой разный! |
|
25.09.2005, 21:44 | #20 |
Участник
|
Извините, сначала пара мелких придирок. Первое, что увидел - форматирование даты. Я бы сделал так
ds = date2str(PeriodBegin, 213, 2, 3, 2, 3, 4); Теперь по хранимой процедуре. Для принимаемых параметров процедуры для даты можно указать тип datetime (конвертиция не требуется) Под каким пользователем вы запускали процедуру из Axapta'ы и из SQL Analyzer'а? Может проблема с правами? Как вы устанавливаете, где прерывается выполнение процедуры? Если через SQL Profiler - то там должна быть более полная информация, где конкретно останавливается выполнение. Если нет, то воспользуйтесь им.
__________________
Axapta v.3.0 sp5 kr2 |
|
|
|