ADOStoredProc+Parameter+Boolean+Input

CrazyAdmin
Дата: 02.07.2009 13:16:17
Возникла у меня проблема, так что может кто сталкивался или вариант предложит получше...

В Delphi7 в DBGrid по 2-ому клику выполняется такой код:
if n3.Checked=true then
    begin
      try
       idcont:=DMsuddel.QMain.FieldValues['ID_ARBITRAG'];
      except
        on E:EVariantTypeCastError do
        begin
          ShowMessage('Нет данных для обнавления.'#10#10'Добавьте данные');
          Exit;
        end;
      end;

      valcont:=DMsuddel.QMain.FieldValues['CONTROL'];

      i:=MessageDlg('Вы уверенны?',mtConfirmation,[mbYes,mbNo],0);
      if i=6 then
        begin
          FMain.Enabled:=false;
            with DMsuddel.SPAddDir do
              begin
                try
                ProcedureName:='UPD_ARBCONT';
                Parameters.Add;
                Parameters.Add;

                Parameters[0].Name:='id_cont';
                Parameters[0].DataType:=ftInteger;
                Parameters[0].Direction:=pdInput;
                Parameters[0].Precision
                Parameters[0].Value:=idcont;

                Parameters[1].Name:='val_con';
                Parameters[1].DataType:=ftBoolean;
                Parameters[1].Direction:=pdInput;
                Parameters[1].Value:=valcont;
               
                Prepared:=True;
                ExecProc;
                Parameters[1].Destroy;
                Parameters[0].Destroy;
... и т. д.
В результате чего в ХП передается значение ID поля и его текущее значение (True или False).
Хранимка в Oracle 9i (SQLPlus ее выполняет на все 100% с требуемым результом) обновляет данные в таблице в зависимости от полученного значения, т. е. Если получено True меняет на False и наоборот. Текст ХП:
 (id_cont in admin.arbitrag.id_arbitrag%type,
  val_con in boolean)
is
rec_upd admin.arbitrag%rowtype;
begin

select * into rec_upd from admin.arbitrag
where id_arbitrag=id_cont
for update nowait;

if (val_con = true) then
  begin
  rec_upd.control:='0';
  end;
else
  begin
  rec_upd.control:='-1';
  end;
end if;

Соль в том, что при запуске в Delphi ХП рисует ошибку такого содержания:
"Неопознаная ошибка"...

гром не грянет... админ не забекапиться...
Petro123
Дата: 02.07.2009 13:54:15
ado не работает с курсорами в оракле и такой сложноватой логикой.
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
lazy cat1
Дата: 02.07.2009 14:20:44
У оракла boolean немножко странный. В pl/sql'е он как бы есть, а вот заводить такого типа столбцы низзя, и передавать через OCI - тоже. Так что используй какой-нибудь другой тип данных.
Petro123
Дата: 02.07.2009 14:54:53
lazy cat1,
+1
CrazyAdmin
Дата: 02.07.2009 15:12:40
Ну как-бы курсор я неиспользую тут...
Насчет хранения boolean типа в таблице оракла это прописная истина... там и нет такого типа)
Храню я логику в виде типа Varchar2(2) со значениями -1 = True и 0 = False, а данная процедура Оракла в зависимости от полученного True or False обновляет данные...
А вот передача типа Boolean через OCI это интересно так как в самом оракле все превосходно функционирует, а ошибка происходит при выполнении этои процедуры через ADOStoredProc.

Щас накидал код вроде работает... без передачи через ХП типа Boolean...
Все дело в делфи а не в оракле... а точнее в Ado.

ЗЫ: Если всетаки кто-то знает о передачи типа Boolean через ХП напишите из зачего ошибка...
CrazyAdmin
Дата: 10.07.2009 08:18:54
Малясь не совсем по теме но все-же. Возникла еще один вопрос как передать в ХП Oracle 9i из Delphi 7 посредствам ADO и драйвера OraOLEDB.Oracle 12 переменных.
Подскажите кто как делает?
Альт
Дата: 13.07.2009 08:09:15
Никаких проблем в работе с SYS_REFCURSOR нет. "Пакет":
+
+
create or replace package P_TEST is

  -- Author  : alt0
  -- Created : 13.07.2009 11:46:14
  -- Purpose : Demos
  
function REF_TEST return SYS_REFCURSOR;

end P_TEST;
/

create or replace package body P_TEST is

function REF_TEST return SYS_REFCURSOR is
  Result SYS_REFCURSOR;
begin
  open Result for
  select 'Preved, medved \o/' from dual;
  return(Result);
end REF_TEST;

end P_TEST;
/

 
Package created
 
Package body created

"Клиент":
+
+
program Project1;

{$APPTYPE CONSOLE}

uses
  ADODb, ActiveX, SysUtils;

const
  CONSTR = 'Provider=OraOLEDB.Oracle;PLSQLRSet=1;' +
    'Persist Security Info=True;Data Source=%s;User ID=%s;Password=%s;';

begin
  CoInitialize(nil);
  with TADODataSet.Create( nil ) do
  try
    ConnectionString := Format( CONSTR, [ 'source', 'user', 'pws' ] );
    CommandType := cmdStoredProc;
    CommandText := 'P_TEST.REF_TEST';
    Open;
    WriteLn( 'RecordCount: ', Recordset.RecordCount );
    while not Eof do
    begin
      WriteLn( 'Say: ', Fields[ 0 ].AsString );
      Next;
    end;
    ReadLn;
  finally
    Free
  end;
end.

"Результат":
RecordCount: 1
Say: Preved, medved \o/

Значения bool (-1 = True и 0 = False) вы завели против правил...
+
+
SQL> begin
  2    dbms_output.put_line('TRUE:  ' || SYS.diutil.bool_to_int( true ) );
  3    dbms_output.put_line('FALSE: ' || SYS.diutil.bool_to_int( false ) );
  4    dbms_output.put_line('NULL:  ' || SYS.diutil.bool_to_int( null ) );
  5  end;
  6  /
 
TRUE:  1
FALSE: 0
NULL:  
 
PL/SQL procedure successfully completed
 
SQL> 


Что не так с параметрами? Разговаривайте кодом, а то будете получать только фиктивные "знания" теоретиков.
CrazyAdmin
Дата: 13.07.2009 14:38:19
Альт
Никаких проблем в работе с SYS_REFCURSOR нет. Не слушайте теоретика Петра... он не ведает, что творит своим бессмысленным бредогенератором. "Пакет":

Спасибо за исходник, буду пробовать...
Альт
Значения bool (-1 = True и 0 = False) вы завели против правил...

Да согласен, это я уже исправил, почему было так (-1 = True и 0 = False), потомучто если выполнить такую простую функцию в Delphi:
 BoolToStr 
То получим:
True -> -1
False -> 0
Было удомнее работать так и снижалось количество кода...
Anatoly Podgoretsky
Дата: 13.07.2009 14:50:24
Считать, что Bool имеет особое значение - неправильно, рано или поздно по зубам, надо считать, что Bool <> 0

--
http://www.podgoretsky.com
Альт
Дата: 13.07.2009 15:06:18
CrazyAdmin, вы, как и Анатолий, теряете главное... в сиквеле логика трехзначна (троична)... $FFFFFFFF для положительных значений... впрочем как и "неравен нулю"... пройденный этап
Дельфи - это инструмент создания клиента... не он диктует... BoolToStr в 2009 году не пример )