#2 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-07-11 06:01:46

I could test the fix, it works now. The max. number of parameters is 666! Thanks a lot!

I have one question regarding this ReplaceParamsByNames function:

You remove the last ';', saying it can couse problem.
But when I create a stored procedure the sytax requires a ';' at the end of the "create procedure ..." command.
So I always have to make manual changes to this ReplaceParamsByNames function when a version is introduced.

Could you make some workaround to keep this last ";" for Oracle?

Thanks,

Tibor

#3 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-07-01 05:09:35

With 95 parameters the named params seems (and fails execution):

'insert into insdemo values(:AA,:BA,:CA,:DA,:EA,:FA,:GA,:HA,:IA,:JA,:KA,:LA,:MA,:NA,:OA,:PA,:QA,:RA,:SA,:TA,:UA,:VA,:WA,:XA,:YA,:ZA,:ZB,:ZC,:ZD,:ZE,:ZF,:ZG,:ZH,:ZI,:ZJ,:ZK,:ZL,:ZM,:ZN,:ZO,:ZP,:ZQ,:ZR,:ZS,:ZT,:ZU,:ZV,:ZW,:ZX,:ZY,:ZZ,:Z[,:Z\,:Z],:Z^,:Z_,:Z`,:Za,:Zb,:Zc,:Zd,:Ze,:Zf,:Zg,:Zh,:Zi,:Zj,:Zk,:Zl,:Zm,:Zn,:Zo,:Zp,:Zq,:Zr,:Zs,:Zt,:Zu,:Zv,:Zw,:Zx,:Zy,:Zz,:Z{,:Z|,:Z},:Z~,:Z'#$7F',:Z'#$80',:Z'#$81',:Z'#$82',:Z'#$83',:Z'#$84',:Z'#$85',:Z'#$86')'


From today I will be on holiday, so probably will not be able to make further tests.

Tibor

#4 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-06-30 14:59:38

When 94 params (no error):
insert into insdemo values(:AA,:BA,:CA,:DA,:EA,:FA,:GA,:HA,:IA,:JA,:KA,:LA,:MA,:NA,:OA,:PA,:AB,:BB,:CB,:DB,:EB,:FB,:GB,:HB,:IB,:JB,:KB,:LB,:MB,:NB,:OB,:PB,:AC,:BC,:CC,:DC,:EC,:FC,:GC,:HC,:IC,:JC,:KC,:LC,:MC,:NC,:OC,:PC,:AD,:BD,:CD,:DD,:ED,:FD,:GD,:HD,:ID,:JD,:KD,:LD,:MD,:ND,:OD,:PD,:AE,:BE,:CE,:DE,:EE,:FE,:GE,:HE,:IE,:JE,:KE,:LE,:ME,:NE,:OE,:PE,:AF,:BF,:CF,:DF,:EF,:FF,:GF,:HF,:IF,:JF,:KF,:LF,:MF,:NF)

When 95 params (fails):

insert into insdemo values(:AA,:BA,:CA,:DA,:EA,:FA,:GA,:HA,:IA,:JA,:KA,:LA,:MA,:NA,:OA,:PA,:AB,:BB,:CB,:DB,:EB,:FB,:GB,:HB,:IB,:JB,:KB,:LB,:MB,:NB,:OB,:PB,:AC,:BC,:CC,:DC,:EC,:FC,:GC,:HC,:IC,:JC,:KC,:LC,:MC,:NC,:OC,:PC,:AD,:BD,:CD,:DD,:ED,:FD,:GD,:HD,:ID,:JD,:KD,:LD,:MD,:ND,:OD,:PD,:AE,:BE,:CE,:DE,:EE,:FE,:GE,:HE,:IE,:JE,:KE,:LE,:ME,:NE,:OE,:PE,:AF,:BF,:CF,:DF,:EF,:FF,:GF,:HF,:IF,:JF,:KF,:LF,:MF,:NF,:OF)


So the issue is with the 'OF' named parameter.
I modified the value with the debugger to have 'PF' instead of 'OF' and it was executed without any problem.

#6 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-06-29 19:07:16

I made two kind of tests:

1. Using PL/SQL Developer a I made the same SQL operations. Created the table, created procedure to insert the values using params and it can handle more than a hundred params without any problem.

2. With the Mormot framework I inserted the values as constants, not using params. It is working.

Here is the code:

  num_of_fields := 120;

  SQL := 'drop table insdemo ';
  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  Statement.Free;

  SQL := 'create table insdemo (';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100))'
                                                    else SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100),';

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  j := Statement.UpdateCount;
  Statement.Free;
  Memo1.Lines.Add('create j: ' + IntToStr(j));

  SQL := 'insert into insdemo values(';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + '''b' + FormatFloat('000',i)+ ''')' else SQL := SQL + '''b' + FormatFloat('000',i)+ ''',';

  Memo1.Lines.Add('Sql command to execute: ' + SQL);

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);

  Statement.ExecutePrepared;

  j := Statement.UpdateCount;
  Statement.Free;

  Memo1.Lines.Add('j: ' + IntToStr(j));

#7 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-06-28 14:33:21

Yes, the issue is when the params are used/bound.

#8 Re: mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-06-28 13:47:12

When num_of_fields = 4 the SQL statements that gets executed:

- drop table insdemo
- create table insdemo (a001 varchar2(100),a002 varchar2(100),a003 varchar2(100),a004 varchar2(100))
- insert into insdemo values(?,?,?,?)

Before executing the last one, string constants are bound to the params with the Statement.BindTexts function.

The resulting table is like this:

Cols:  A001  A002  A003  A004
Rec1: b001  b002  b003  b004

Which generated variable names sounds invalid?

Tibor

#9 mORMot 1 » Bug in Oracle interface? Please confirm or confute » 2013-06-28 09:24:12

peak.tibor
Replies: 17

I have already posted this earlier, but no reply received.

Mormot OCI cannot handle more than 94 params!

I think it is a Mormot framework bug, as I know Oracle itself does not have this limit.
I receive the following error message when trying to use more than 94 params: ORA-01745:invalid host/bind variable name.

Here the code I use to test the situation:
It runs OK if num_of_fields=94, fails if 95 or greater.

  num_of_fields := 95;

  SQL := 'drop table insdemo ';
  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  Statement.Free;

  SQL := 'create table insdemo (';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100))'
                                                    else SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100),';

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  j := Statement.UpdateCount;
  Statement.Free;
  Memo1.Lines.Add('create j: ' + IntToStr(j));

  SQL := 'insert into insdemo values(';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + '?)' else SQL := SQL + '?,';

  Memo1.Lines.Add('Sql command to execute: ' + SQL);

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);

  for i := 1 To num_of_fields Do Statement.BindTexts(i,'b' + FormatFloat('000',i));

  Statement.ExecutePrepared;
  Statement.Free;

#10 mORMot 1 » Oracle interface fails if number of parameters is more then 94 » 2013-05-30 13:03:26

peak.tibor
Replies: 0

I think it is a Mormot framework bug, as I know Oracle itself does not have this limit.
I receive the following error message when trying to use more than 94 params: ORA-01745:invalid host/bind variable name.

Here the code I use to test the situation:
It runs OK if num_of_fields=94, fails if 95 or greater.



  num_of_fields := 95;

  SQL := 'drop table insdemo ';
  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  Statement.Free;

  SQL := 'create table insdemo (';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100))'
                                                    else SQL := SQL + 'a' + FormatFloat('000',i) + ' varchar2(100),';

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);
  Statement.ExecutePrepared;
  j := Statement.UpdateCount;
  Statement.Free;
  Memo1.Lines.Add('create j: ' + IntToStr(j));

  SQL := 'insert into insdemo values(';
  for I := 1 to num_of_fields do if i=num_of_fields then SQL := SQL + '?)' else SQL := SQL + '?,';

  Memo1.Lines.Add('Sql command to execute: ' + SQL);

  Statement := props.NewThreadSafeStatement;
  Statement.Prepare(SQL,False);

  for i := 1 To num_of_fields Do Statement.BindTexts(i,'b' + FormatFloat('000',i));

  Statement.ExecutePrepared;
  Statement.Free;

#11 mORMot 1 » How to create Oracle Stored Procedure through OCI » 2013-04-29 12:04:50

peak.tibor
Replies: 0

When trying to create programmatically stored procedure I execute the appropriate "CREATE OR REPLACE PROCEDURE ... " sql command.
And I have an issue with the ";" at the end of the line. I think it is needed but the interface drops it (ReplaceParamsByNames procedure in the SynDb source).

Any idea how to solve this?

Thanks in advance.

Tibor

#14 mORMot 1 » BindNull may have an issue when used with OCI » 2013-04-03 21:06:26

peak.tibor
Replies: 4

I'm experiencing problems when trying to pass null values to a stored procedure using the OCI interface: when the last param is NULL, all the params become NULL!

Here is my example:

I create a simple table:

CREATE TABLE nullch1 (
  FILL char(13 CHAR) NOT NULL
, INFO char(20 CHAR) NULL
, SZOVEG char(10 CHAR) NULL  )

Here is the stored procedure:

CREATE OR REPLACE PROCEDURE nullch1_Proc(FILL   in char default null,
                                         INFO   in char default null,
                                         SZOVEG in char default null) AS
BEGIN
  INSERT INTO nullch1 VALUES (FILL, INFO, SZOVEG);
END;


Here is the Statement I prepare, bind values then execute:

call nullch1_Proc(FILL=> ? ,INFO=> ? ,SZOVEG=> ? )

Here is how I use it:

   
    SQL_SP := 'call nullch1_Proc(FILL=> ? ,INFO=> ? ,SZOVEG=> ? )';
    Statement := TSQLDBOracleStatement(con.NewStatement);
    Statement.Prepare(SQL_SP,False);
    FILL_value := 'Demo1'; INFO_value := 'Demo2'; SZOVEG_value := 'Demo3';
    Statement.BindTextS(1,FILL_value);
    Statement.BindNull(2);
    Statement.BindTextS(3,SZOVEG_value);
    Statement.ExecutePrepared; // This will work

    Statement.BindTextS(1,FILL_value);
    Statement.BindTextS(2,INFO_value);
    Statement.BindNull(3);
    Statement.ExecutePrepared; // This will fail, because the stored procedure will get ALL the params as NULL values!


Do I make any mistake?
Or does really have the Mormot Library some bug?

As a workaround currently I always define an 'dummy' parameter for the stored parameter as the last one. This last parameter is not used for anything, but is there to avoid the above issue.

Thanks in advance.

Tibor

#15 mORMot 1 » suggest another 'ALTER SESSION...' in SynDBOracle.Pas » 2013-04-03 20:35:42

peak.tibor
Replies: 2

In the TSQLDBOracleConnection.Connect procedure there is the following useful statement:

Execute('ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD-HH24:MI:SS''',false);

I suggest to also include the following one:

Execute('ALTER SESSION SET NLS_NUMERIC_CHARACTERS=''' + DecimalSeparator + ThousandSeparator + '''',false);

This would help us who use not the '.', but the ',' as a decimal separator (e.g. in Hungary, where I live).
As I experience, the Thousandseparator is not automatically used, but the DecimalSeparator YES, so I included this statement into my library.

Tibor

#16 Re: mORMot 1 » ReUse of SQLDBOracleStatement fails: ORA-24333 zero iteration count » 2013-02-28 12:00:36

My stored procedure is quite simple:

create or replace procedure ins_inv_data_1
  (inv_id in number
  ,cust_id in number
  ,order_dt in varchar2
  ,ship_dt in varchar2
  ,cicus out number
  )
as
Begin
insert into invoice values(
inv_id,cust_id, to_date(order_dt,'yyyy.mm.dd'),to_date(ship_dt,'yyyy.mm.dd')
);
cicus := 2;
end;

I do not know whether I should make any modification on it regarding this error message.
But I applied your modification in SynDBOracle.pas and the error disappeared!

So thanks a lot, this helped.
If you think I should also make some modifications in my stored procedure, I'm ready to do it.

Regards,

Tibor

#17 mORMot 1 » ReUse of SQLDBOracleStatement fails: ORA-24333 zero iteration count » 2013-02-28 09:37:02

peak.tibor
Replies: 3

in SynDbOracle it is stated that you could reuse a Statement "with Prepare once followed by several  ExecutePrepared methods" :

  TSQLDBOracleStatement = class(TSQLDBStatementWithParamsAndColumns)
  ............
  public
    {{ create an OCI statement instance, from an existing OCI connection
     - the Execute method can be called once per TSQLDBOracleStatement instance,
       but you can use the Prepare once followed by several  ExecutePrepared methods
     - if the supplied connection is not of TOleDBConnection type, will raise
       an exception }
    constructor Create(aConnection: TSQLDBConnection); override;


It really works when it is a simple "select * count .." statement. But ...

I created a stored procedure with params that inserts data values into a table as a new record (insert into ...). I would like to use one statement (that calls this stored procedure) to insert several records.
And I got this Oracle error:  ORA-24333 zero iteration count

Do I misunderstand something?

Here is my code:

  SQL := 'call ins_inv_data_1(?,?,?,?,?) ';
  Statement := props.NewThreadSafeStatement;

  Statement.Prepare(SQL,False);

  Statement.Bind(1,inv_id,paramIn);
  Statement.Bind(2,cust_id,paramIn);
  Statement.BindTextS(3,order_dt);
  Statement.BindTextS(4,ship_dt);
  Statement.Bind(5,cicus,paramOut);
  Statement.ExecutePrepared;                      // this works OK
  j := Statement.UpdateCount;
  Statement.ParamToVariant(5,out1,true);

  Statement.Reset;
  Statement.Bind(1,inv_id,paramIn);
  Statement.Bind(2,cust_id,paramIn);
  Statement.BindTextS(3,order_dt);
  Statement.BindTextS(4,ship_dt);
  Statement.Bind(5,cicus,paramOut);

  Statement.ExecutePrepared;

Here I receive the above error! Can any one help?

Thanks

Tibor

#19 mORMot 1 » ORACLE OCI params count limit » 2013-02-22 14:36:32

peak.tibor
Replies: 2

I found the following limit for number of params:

function TSQLDBStatementWithParams.CheckParam(Param: Integer;
  NewType: TSQLDBFieldType; IO: TSQLDBParamInOutType): PSQLDBParam;
begin
  if self=nil then
    raise ESQLDBException.Create('Invalid Bind*() call');
  if (Param<=0) or (Param>64) then
    raise ESQLDBException.CreateFmt('Bind*(%d) should be 1..64',[Param]);
  if Param>fParamCount then
    fParam.Count := Param; // resize fParams[] dynamic array if necessary
  result := @fParams[Param-1];
  result^.VType := NewType;
  result^.VInOut := IO;
end;

As I know ORACLE itself does not have this max 64 param count limit.

I would need more.
Can I simple change '64' in the source to a greater number?

Thanks,

Tibor

Board footer

Powered by FluxBB