TADOStoredProc + Oracle

giigro
Дата: 18.05.2011 17:34:05
Здравствуйте, уважаемые форумеры

Не могу побороть глюкодром с ADO
Процедура с DML создает новую запись и возвращает её id:
 package body MYPCK
 ...
 procedure INSERTSh(
          prm_desc in UITS.DESCR%TYPE,
          l_sid out UITS.ID%TYPE
          )
 is
 begin
         insert into UITS (descr, is_closed)
         values (prm_desc, 0);

         commit; 
         
         select UITS.CURRVAL into l_sid from dual;
         return;
 end INSERTSuit;
Вызова на стороне клиента, используется TADOStoredProc, параметры формиру.тся run-time
  //присваивание имени процедуры и прочая хрень
  // ...
  // каждый из двух параметров добавляется так:
  ADOProc1.Parameters.Items[cnt].Name := p_name;
  ADOProc1.Parameters.Items[cnt].DataType := p_datatype;
  ADOProc1.Parameters.Items[cnt].Direction := p_dir;
  ADOProc1.Parameters.Items[cnt].Value := p_val;
  ADOProc1.Parameters.Items[cnt].Size := SIZEOF(p_val);
  // вызов
  ADOProc1.Open;
Валится с ошибкой PLS-00306: Неверное количество или типы аргументов для вызова. То есть модуль процедуру находит и пытается вызвать, но ему не нравятся параметры. Все параметры параметров (сори за тавталогию) проверены десять раз и стопудово правильные. Есть ещё параметр Type у параметра Value, но я к нему так и не нашел доступ. Может, нужно ещё что-то указать? В чем может быть косяк?
энди
Дата: 19.05.2011 08:26:09
А разве АДО сам не рефрешит параметры? Зачем вы их руками создаете?
Да и вообще, знающие люди рекомендуют пользовать TADODataset а не его наследников.
andreymx
Дата: 19.05.2011 08:39:33
giigro
         insert into UITS (descr, is_closed)
         values (prm_desc, 0);

         commit; 
         
         select UITS.CURRVAL into l_sid from dual;
неверный алгоритм
1. в многопользовательском режиме вы поимеете непонятные проблемы
2. в будущем возможно изменения поведения триггера - например, использование другой последовательности

так что почитайте про RETURNING

ЗЫ: а почему процедура, а не функция?
giigro
Дата: 19.05.2011 08:50:30
andreymx
giigro
         insert into UITS (descr, is_closed)
         values (prm_desc, 0);

         commit; 
         
         select UITS.CURRVAL into l_sid from dual;
неверный алгоритм
1. в многопользовательском режиме вы поимеете непонятные проблемы
2. в будущем возможно изменения поведения триггера - например, использование другой последовательности

так что почитайте про RETURNING

ЗЫ: а почему процедура, а не функция?

Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?
alsov
Дата: 19.05.2011 09:05:52
giigro
Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?


Это кто сказал, что нельзя DML в оракловых функциях делать. Не путайте с mssql.
Ramin Hashimzade
Дата: 19.05.2011 09:08:52
giigro
andreymx
пропущено...
неверный алгоритм
1. в многопользовательском режиме вы поимеете непонятные проблемы
2. в будущем возможно изменения поведения триггера - например, использование другой последовательности

так что почитайте про RETURNING

ЗЫ: а почему процедура, а не функция?

Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?


select UITS.CURRVAL into l_sid from dual;
уже не правильно , так как не факт что CURRVAL это ИД только что добавленный записи
giigro
Дата: 19.05.2011 09:11:18
alsov
giigro
Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?


Это кто сказал, что нельзя DML в оракловых функциях делать. Не путайте с mssql.

Есkи можно, то это бы в корне поменяло дело и не пришлось прибегать к извращениям вроде TADOStoredProc :) Если не трудно, напишите, как?
select * from somefunc_withDML --такое не прокатывает
alsov
Дата: 19.05.2011 09:13:03
Ramin
giigro
пропущено...

Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?


select UITS.CURRVAL into l_sid from dual;
уже не правильно , так как не факт что CURRVAL это ИД только что добавленный записи


А разве CURRVAL можно без NEXTVAL вызывать?
giigro
Дата: 19.05.2011 09:13:17
andreymx, Ramin - спасибо! действительно косяк
tru55
Дата: 19.05.2011 09:13:51
giigro
Потому что в функции нельзя выполнять операции DML. А как ещё можно получить ID добавленной записи?

1. в функции нельзя выполнять DML, если она вызывается в SQL. Если она вызывается в PL/SQL, то таких ограничений нет
2. про RETURNING уже сказали
INSERT INTO ...
VALUES
RETURNING id INTO v_Id;