how can i know a field's fieldtype before call execute?

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
c123321
Posts: 20
Joined: Sat 03 Jul 2010 03:24

how can i know a field's fieldtype before call execute?

Post by c123321 » Mon 12 Mar 2012 08:26

i write comm procedure
Excesql(sqltext:string;params: array of const);

oracle 10G;unidac 4.1.3


procedure TForm1.ExecSql(sql:String;params: array of const);
begin
Self.UniSQL1.SQL.Text := sql;
Self.UniSQL1.Params[0].value := Random(7000);
ShowMessage(IntToStr(params[0].vType)+','+IntToStr(params[1].vType));
//the TDateTime Type be convert to VExtended, when uses the next row, it is ok, else it is error;
//but i can not know the params[1] is TDatatime Field,how can i know? or use other method?
//such as { array of varint} but varint can not pass TStream; i like this procedure is common procedure
Self.UniSQL1.Params[1].DataType := ftDateTime;
Self.UniSQL1.Params[1].value := params[0].VExtended^;
Self.UniSQL1.Params[2].value := params[1].VExtended^;
Self.UniSQL1.Execute;
end;

procedure TForm1.btn3Click(Sender: TObject);
var
dt: TDateTime;
sal: Double;
begin
Randomize;
dt := Now;
sal := dt;
ExecSql('INSERT INTO EMP(EMPNO,hiredate,sal) VALUES (:randnum,:ssdate,:sal)',[dt, sal]);
end;

c123321
Posts: 20
Joined: Sat 03 Jul 2010 03:24

Re: how can i know a field's fieldtype before call execute?

Post by c123321 » Mon 12 Mar 2012 10:34

c123321 wrote:i write comm procedure
Excesql(sqltext:string;params: array of const);

oracle 10G, unidac 4.1.3 unidac demo db;


procedure TForm1.ExecSql(sql:String;params: array of const);
begin
Self.UniSQL1.SQL.Text := sql;
// Self.UniSQL1.Parpare; can use this then the UniSQL1.Params be setted? this value can not;
Self.UniSQL1.Params[0].value := Random(7000);
ShowMessage(IntToStr(params[0].vType)+','+IntToStr(params[1].vType));
//the TDateTime Type be convert to VExtended, when uses the next row, it is ok, else it is error;
//but i can not know the params[1] is TDatatime Field,how can i know? or use other method? i think where i
//such as { array of varint} but varint can not pass TStream; i like this procedure is common procedure
Self.UniSQL1.Params[1].DataType := ftDateTime;
Self.UniSQL1.Params[1].value := params[0].VExtended^;
Self.UniSQL1.Params[2].value := params[1].VExtended^;
Self.UniSQL1.Execute;
end;

procedure TForm1.btn3Click(Sender: TObject);
var
dt: TDateTime;
sal: Double;
begin
Randomize;
dt := Now;
sal := dt;
ExecSql('INSERT INTO EMP(EMPNO,hiredate,sal) VALUES (:randnum,:ssdate,:sal)',[dt, sal]);
end;

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Mon 12 Mar 2012 11:26

Hello,

We cannot define the parameter type created by a user, so we send the value that is set to the parameter (in our case, it is a number) to the server. You should either set the parameter type explicitly

UniSQL1.Params[1].DataType := ftDateTime;

or use casting when setting the parameter type

UniSQL1.Params[1].Value := VarToDateTime(params[0].VExtended^);

else, specify the type you bind

UniSQL1.Params[1].AsDateTime := params[0].VExtended^;

c123321
Posts: 20
Joined: Sat 03 Jul 2010 03:24

Post by c123321 » Mon 12 Mar 2012 15:30

the import thing is that i don't know the type is datetime because i will write a common procedure, why the unisql1.prepare procdure can not set the parameter type ?
AlexP wrote:Hello,

We cannot define the parameter type created by a user, so we send the value that is set to the parameter (in our case, it is a number) to the server. You should either set the parameter type explicitly

UniSQL1.Params[1].DataType := ftDateTime;

or use casting when setting the parameter type

UniSQL1.Params[1].Value := VarToDateTime(params[0].VExtended^);

else, specify the type you bind

UniSQL1.Params[1].AsDateTime := params[0].VExtended^;

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Tue 13 Mar 2012 11:01

Hello,

Automatic definition of user's parameters is not supported for Oracle, the parameter type will remain ffUnknown even after calling the Prepare method. One of the possible ways of realization of such universal method can be transfer of a parameters pair (value-type) to the method

Code: Select all

ExecSql('INSERT INTO EMP(EMPNO,hiredate,sal) VALUES (:randnum,:ssdate,:sal)',[dt, Integer(ftDateTime), sal, Integer(ftFloat)]);


  Self.UniSQL1.Params[1].DataType := TFieldType(params[1].VExtended);
  Self.UniSQL1.Params[1].value := params[0].VExtended^;
  Self.UniSQL1.Params[2].DataType := TFieldType(params[3].VExtended);;
  Self.UniSQL1.Params[2].value := params[2].VExtended^;

c123321
Posts: 20
Joined: Sat 03 Jul 2010 03:24

Post by c123321 » Tue 13 Mar 2012 16:14

thinks, final solve is this:

ExecSql('INSERT INTO EMP(EMPNO,hiredate,sal) VALUES (:randnum,:ssdate,:sal)',[varfromdatetime(dt), sal]);

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Wed 14 Mar 2012 08:18

Hello,

Glad to see that you solved the problem.
If you have any other questions, feel free to contact us.

Post Reply