AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.06.2011, 12:18   #1  
uchenik is offline
uchenik
Участник
 
119 / 20 (1) +++
Регистрация: 15.12.2008
Добавление записей в таблицу БД через CCADOCommand
Само добавление вопросов не вызывает.
А вот как бы получить хоть какие-нибудь сведения о добавленной записи?
Или необходимо самому заполнять необходимы идентификатор и по нему потом выискивать?
Старый 28.06.2011, 14:34   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
А что получить-то надо?
Старый 28.06.2011, 17:58   #3  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Единственное, что можно получить - это возможные ошибки выполнения, если опять же правильно написана хранимая процедура и в ней присутствет
X++:
raiserror
__________________
Axapta book for developer
Старый 29.06.2011, 10:22   #4  
uchenik is offline
uchenik
Участник
 
119 / 20 (1) +++
Регистрация: 15.12.2008
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
А что получить-то надо?
Есть прога, использующая SQL базу, необходимо в аксапте сформировать документ и поместить его в одну из таблиц базы, используемой данной прогой.
Документ состоит из заголовка и строк, хранящихся в разных таблицах.
Соответственно нужно при добавлении заголовка получить обратно какой-нибудь идентификатор (к слову сам идентификатор генерится в той базе автоматически), для правильного добавления строк.
Старый 29.06.2011, 10:33   #5  
AlGol is offline
AlGol
Участник
 
277 / 93 (4) ++++
Регистрация: 24.12.2001
Адрес: Тверь.
Может стоит подумать о реализации немножко другого способа:
- Перед созданием записи вызвать из этой базы процедуру которая даст вам нужный идентификатор.
- И уже с нужным идентификатором вы спокойно создаете строки.
__________________
Ален ноби, ностра алис.
Что означает - если один человек построил, другой завсегда разобрать может.
Старый 29.06.2011, 10:40   #6  
uchenik is offline
uchenik
Участник
 
119 / 20 (1) +++
Регистрация: 15.12.2008
Цитата:
Сообщение от AlGol Посмотреть сообщение
Может стоит подумать о реализации немножко другого способа:
- Перед созданием записи вызвать из этой базы процедуру которая даст вам нужный идентификатор.
- И уже с нужным идентификатором вы спокойно создаете строки.
Т.е. процедура создаст в базе нужную мне строку, вернет идентификатор, а я потом строку обновлю? И так для всех строк? Громоздко и медленнее похоже в разы будет.
Логичнее было бы иметь хотя бы recid после добавления строки...

AlGol, но все равно, можно поподробнее о Вашем способе?

P.S. - есть еще ограничение на возможность внесения изменений логики работы второй системы (как в самой проге, так и в базе).
Старый 29.06.2011, 10:50   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от uchenik Посмотреть сообщение
Есть прога, использующая SQL базу, необходимо в аксапте сформировать документ и поместить его в одну из таблиц базы, используемой данной прогой.
Документ состоит из заголовка и строк, хранящихся в разных таблицах.
Соответственно нужно при добавлении заголовка получить обратно какой-нибудь идентификатор (к слову сам идентификатор генерится в той базе автоматически), для правильного добавления строк.
У Вас неправильное представление о том, что есть ADO и ODBC. Это всего-лишь "переводчики". Т.е. они "переводят" команды от клиента к северу и возвращают результат выполнения этой команды клиенту.

Вставка записи - это команда INSERT. И вот что может вернуть подобная команда как результат своей работы? Ну, максимум, количество вставленных записей.

Идентификатор записи - не есть некая структурная характеристика базы данных. Т.е. что именно является идентификатором - это, скорее, логическая характеристика. Нет каких-либо однозначных критериев, по которым можно было бы сказать, что вот это есть идентификатор.

Ну, предположим, что идентификатор - это то, по чему построен Primary Index. Однако, как минимум, это может быть несколько полей! И какое из них предлагаете возвращать?

Так что, Ваше предположение о поиске записи после ее вставки по значению альтернативных ключей, в общем случае, единственно верное. Нет, конечно, есть еще варианты, если ключевое поле - это поле со свойством Identity. Но это уже частный случай.
Старый 29.06.2011, 12:10   #8  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
У Вставка записи - это команда INSERT. И вот что может вернуть подобная команда как результат своей работы? Ну, максимум, количество вставленных записей.
Здрасьте...
А как же
PHP код:
Insert into .. Returning .. 
?
__________________
Zhirenkov Vitaly
Старый 29.06.2011, 12:49   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от ZVV Посмотреть сообщение
Здрасьте...
А как же
PHP код:
Insert into .. Returning .. 
?
Так это же только для Oracle возможно
http://ru.wikipedia.org/wiki/Insert_(SQL)/Получение ключа

Последний раз редактировалось S.Kuskov; 29.06.2011 в 12:51.
Старый 29.06.2011, 13:34   #10  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Для автоинкрементных полей в MS SQL можно воспользоваться вызовом
X++:
select @@identity
после вставки

Если для ADO, то это будет выглядеть примерно так
X++:
    CCADOConnection con = new CCADOConnection();
    CCADORecordSet  rec;
    ;
    con.open('настройка для подключения');

    rec = new CCADORecordset();
    rec.open("set nocount on\n insert into tablex (name) values ('Name3')\n select @@identity as ident", con);
    if (rec.fields().count() > 0)
    {
        print rec.fields().itemIdx(0).value();
        rec.close();
    }
    con.close();
    pause;
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: uchenik (1).
Старый 29.06.2011, 14:07   #11  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Если у Вас MS SQL Server, то вот пример:
1) Создайте на MS SQL таблицу, в которой одно поле текстовое, второе поле со свойством identity.
2) Создайте на MS SQL хранимую процедуру с названием "spTestReturnRecordset", в теле которой напишите что-то наподобие
X++:
INSERT INTO MyTable (MyFieldName) Values ('Дядя Петя')
SELECT @@identity
3) Напишите в Аксапте джоб
В результате работы этого джоба в инфологе Аксапты будет отображен идентификатор добавленой записи.
X++:
static void DD_StoredProcReturnRecordsetTest(Args _args) 
{ 
    str     serverName      = "Server"; 
    str     baseName        = "Database"; 
    str     userId          = "UserId"; 
    str     userPassword    = "Password"; 
    CCADOConnection         cn; 
    COM                     comCN; 
    COM                     cmd; 
    CCADORecordset          rs; 
    int                     i; 
    ; 

    cn = new CCADOConnection(); 
    cn.open( 
        "Provider=SQLOLEDB;"+ 
        "Data Source="      + serverName    +   ";" + 
        "Initial Catalog="  + baseName      +   ";" + 
        "uid="              + userId        +   ";" + 
        "pwd="              + userPassword); 

    comCN = cn.connection(); 

    cmd     = new COM("ADODB.Command"); 
    cmd.activeConnection(comCN); 
    cmd.commandType(4);  //adCmdStoredProc, see ObjectBrowser in VBA   
    cmd.CommandText("spTestReturnRecordset"); 
    rs = new CCADORecordset(cmd.Execute()); 
    while (!rs.eof()) 
    { 
        info(strfmt("%1", rs.fields().itemIdx(0).value())); 
        rs.movenext(); 
    } 

    cn.close(); 
}
ЗЫ: уже опередили

Последний раз редактировалось Ace of Database; 29.06.2011 в 14:09.
Старый 29.06.2011, 14:44   #12  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от AndyD Посмотреть сообщение
Для автоинкрементных полей в MS SQL можно воспользоваться вызовом
X++:
select @@identity
после вставки
Угу. Только следует помнить, что @@identity относится к последнему созданному значению в любой таблице

В данном случае, например, если таблица tablex имеет триггер на вставку в котором происходит вставка в связанную таблицу, которая тоже имеет поле со свойством Identity, то в результате @@identity вернет не код записи таблицы tablex, а код записи подчиненной таблицы.

Поэтому в данном конкретном случае лучше использовать функцию SCOPE_IDENTITY(). Примерно так

X++:
stringSQL = " set nocount on;" + "\n" + 
                   " insert into tablex (name) values ('Name3');" + "\n" +
                   " SELECT NewIdent=SCOPE_IDENTITY()" + 
                    "";
rec.open(stringSQL);
Если же используется версия MS SQL 2005 или старше, то есть более строгое решение с использованием опции OUTPUT

X++:
stringSQL = " set nocount on;" + "\n" + 
                   " declare @retVal table(f1 integer)"
                   " insert into tablex (name) output inserted.f1 into @retVal values ('Name3');" + "\n" +
                   " SELECT f1 from @retVal" + 
                    "";
rec.open(stringSQL);
В данном случае я предполагаю, что таблица имеет поле f1 типа integer со свойством identity

Другими словами, одной команды INSERT явно не достаточно. Нужно либо писать процедуру, либо посылать повторный запрос для поиска только что вставленной записи. Что для Вас проще и привычнее, то и делайте.
Старый 29.06.2011, 15:25   #13  
AlGol is offline
AlGol
Участник
 
277 / 93 (4) ++++
Регистрация: 24.12.2001
Адрес: Тверь.
Цитата:
Сообщение от uchenik Посмотреть сообщение
Т.е. процедура создаст в базе нужную мне строку, вернет идентификатор, а я потом строку обновлю? И так для всех строк? Громоздко и медленнее похоже в разы будет.
Логичнее было бы иметь хотя бы recid после добавления строки...

AlGol, но все равно, можно поподробнее о Вашем способе?

P.S. - есть еще ограничение на возможность внесения изменений логики работы второй системы (как в самой проге, так и в базе).
Я имел ввиду механизм похожий на номерные серии Аксапты:
- сначала выделяется индентификатор, сохраняется до следующего раза, и возвращается вам в Аксапту.
- затем в другом запросе вставляется запись с этим идентификатором.
При этом, скорее всего, придется переделывать систему с которой вы стыкуетесь.

Если у вас идентификатор - это автоинкрементое поле - наверняка проще сделать так, как вам советуют выше, с помощью получения @@Identity из запроса или процедуры вставки записей.
__________________
Ален ноби, ностра алис.
Что означает - если один человек построил, другой завсегда разобрать может.
Теги
ado, insert, odbc, ключ

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Axapta 3.0 Добавление записей во врем. таблицу vagon DAX: Функционал 1 14.02.2011 13:56
Массовое удаление записей через CCADOConnection Shirmin Oleg DAX: Программирование 68 04.05.2010 15:49
добавление поля в таблицу с огромным количеством записей rpr DAX: Программирование 22 24.04.2009 14:13
Задвоение RecId при вставке записей через COM коннектор db DAX: Программирование 1 23.04.2009 15:12
К чему приводит добавление поля в таблицу. si DAX: Программирование 6 21.05.2002 11:54

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:43.