Discussion of open issues, suggestions and bugs regarding ODAC (Oracle Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Thu 10 Jan 2008 08:58
As I said, I do not always know the exact datatype of the target column (LONG RAW or BLOB).
Is this an Oracle specific thing or does this issue only happen in ODAC?
I'm a bit stuck here
--
Martijn Tonies
Upscene Productions
-
decimator
- Posts: 1
- Joined: Thu 10 Jan 2008 15:22
Post
by decimator » Thu 10 Jan 2008 15:33
Hello,
I have a similar (I think) question.
I'm trying to insert LONG RAW field as a parameter
using dbExpress'es TSQLQuery. My paramater is
ptInput and ftBlob. When I try to execute the SQL
I get the following:
ORA-01465: invalid hex number
Any suggestions?
I read somewhere that rawtohex() function in Oracle
might help. It actually helped me to insert a text
file in the field but when I tried inserting a jpeg - it
inserted only 4 bytes or something like that (the
field after inserting certainly didn't contain picture).
Thank you in advance.
Momchil Ivanov
-
Plash
- Devart Team
- Posts: 2844
- Joined: Wed 10 May 2006 07:09
Post
by Plash » Fri 11 Jan 2008 08:57
upscene wrote:As I said, I do not always know the exact datatype of the target column (LONG RAW or BLOB).
Is this an Oracle specific thing or does this issue only happen in ODAC?
I'm a bit stuck here
It is Oracle specific. In some cases it cannot convert LONG RAW value to BLOB.
-
Plash
- Devart Team
- Posts: 2844
- Joined: Wed 10 May 2006 07:09
Post
by Plash » Fri 11 Jan 2008 11:35
decimator wrote:Hello,
I have a similar (I think) question.
I'm trying to insert LONG RAW field as a parameter
using dbExpress'es TSQLQuery. My paramater is
ptInput and ftBlob. When I try to execute the SQL
I get the following:
ORA-01465: invalid hex number
Any suggestions?
This error occurs when parameter data type is ftString or ftUnknown. In this case Oracle consider that value is in hex format.
The data type can be changed to ftString if you set value using AsString property. You should use AsBlob property to set value of LONG RAW parameter.
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Wed 27 Oct 2010 13:04
Plash wrote:upscene wrote:As I said, I do not always know the exact datatype of the target column (LONG RAW or BLOB).
Is this an Oracle specific thing or does this issue only happen in ODAC?
I'm a bit stuck here
It is Oracle specific. In some cases it cannot convert LONG RAW value to BLOB.
This issue is still bugging me: I need a routine that can write binary data to both BLOB and LONG RAW.
I cannot change the datatype, either ftBlob or ftOraBlob.
Is that possible?
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Tue 02 Nov 2010 05:45
upscene wrote:Plash wrote:upscene wrote:As I said, I do not always know the exact datatype of the target column (LONG RAW or BLOB).
Is this an Oracle specific thing or does this issue only happen in ODAC?
I'm a bit stuck here
It is Oracle specific. In some cases it cannot convert LONG RAW value to BLOB.
This issue is still bugging me: I need a routine that can write binary data to both BLOB and LONG RAW.
I cannot change the datatype, either ftBlob or ftOraBlob.
Is that possible?
Any tips? Is there possible code that works for both datatypes?
-
AlexP
- Devart Team
- Posts: 5530
- Joined: Tue 10 Aug 2010 11:35
Post
by AlexP » Fri 05 Nov 2010 11:02
You can write binary data to the BLOB and LONG RAW fields like this:
SimpleDataSet1.DataSet.ParamByName('TST_LONG_ROW').LoadFromFile('e:\1.bmp',ftBlob);
SimpleDataSet1.DataSet.ParamByName('TST_BLOB').LoadFromFile('e:\1.bmp',ftBlob);
where text query is:
INSERT INTO TST_TABLE
(TST_BLOB, TST_LONG_ROW)
VALUES
(:TST_BLOB, :TST_LONG_ROW)
and the types of param are:
TST_BLOB - ftOraBlob;
TST_LONG_ROW - ftOraBlob
but you can't insert both fields simultaneously if the size of data is more than 4000 bytes, because Oracle can't bind more than 4000 bytes with LOB and LONG columns in one command.
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Fri 05 Nov 2010 11:15
AlexP wrote:You can write binary data to the BLOB and LONG RAW fields like this:
SimpleDataSet1.DataSet.ParamByName('TST_LONG_ROW').LoadFromFile('e:\1.bmp',ftBlob);
SimpleDataSet1.DataSet.ParamByName('TST_BLOB').LoadFromFile('e:\1.bmp',ftBlob);
where text query is:
INSERT INTO TST_TABLE
(TST_BLOB, TST_LONG_ROW)
VALUES
(:TST_BLOB, :TST_LONG_ROW)
and the types of param are:
TST_BLOB - ftOraBlob;
TST_LONG_ROW - ftOraBlob
but you can't insert both fields simultaneously if the size of data is more than 4000 bytes, because Oracle can't bind more than 4000 bytes with LOB and LONG columns in one command.
How can I push more than 4000 bytes then? A LONG RAW should support gigs of data?
-
AlexP
- Devart Team
- Posts: 5530
- Joined: Tue 10 Aug 2010 11:35
Post
by AlexP » Fri 05 Nov 2010 12:27
Hello,
You can't insert data in the LOB and LONG fields simultaneously.
But you can insert data in turns by inserting one field during one execution.
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Fri 05 Nov 2010 12:33
AlexP wrote:Hello,
You can't insert data in the LOB and LONG fields simultaneously.
But you can insert data in turns by inserting one field during one execution.
I'm not saying I'm inserting both at the same time, I'm saying I cannot use the same code for both BLOB and LONG RAW fields
-
AlexP
- Devart Team
- Posts: 5530
- Joined: Tue 10 Aug 2010 11:35
Post
by AlexP » Fri 05 Nov 2010 14:27
hello,
Please execute the following code to insert the LOB and LONG data:
procedure TForm1.Button1Click(Sender: TObject);
var
SqlConnection: TSQLConnection;
SimpleDataSet: TSimpleDataSet;
begin
SqlConnection:= TSQLConnection.Create(nil);
SimpleDataSet:= TSimpleDataSet.Create(nil);
SqlConnection.DriverName:= 'DevartOracle';
SqlConnection.VendorLib := 'oci.dll';
SqlConnection.libraryName := 'dbexpoda.dll';
SqlConnection.GetDriverFunc := 'getSQLDriverORA';
SqlConnection.Params.Clear();
SqlConnection.Params.Add('Database=ORA1110');
SqlConnection.Params.Add('User_Name=SCOTT');
SqlConnection.Params.Add('Password=tiger');
SqlConnection.Connected := true;
SimpleDataSet.Connection := SqlConnection;
SimpleDataSet.DataSet.CommandText := 'INSERT INTO ALEXP_BLOB(ID, TST_BLOB) VALUES(:ID, :TST_BLOB)';
SimpleDataSet.DataSet.ParamByName('ID').AsInteger := 1;
SimpleDataSet.DataSet.ParamByName('TST_BLOB').LoadFromFile('e:\1.bmp',ftBlob);
SimpleDataSet.Execute;
SimpleDataSet.DataSet.CommandText := 'UPDATE alexp_blob SET TST_LONG_ROW = :TST_LONG_ROW WHERE ID = :ID';
SimpleDataSet.DataSet.ParamByName('ID').AsInteger := 1;
SimpleDataSet.DataSet.ParamByName('TST_LONG_ROW').LoadFromFile('e:\1.bmp',ftBlob);
SimpleDataSet.Execute;
SimpleDataSet.Close;
end;
Oracle doesn't allow to insert both fields simultaneously if the total size of data is more than 4000 bytes.
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Fri 05 Nov 2010 14:31
AlexP wrote:hello,
Please execute the following code to insert the LOB and LONG data:
procedure TForm1.Button1Click(Sender: TObject);
var
SqlConnection: TSQLConnection;
SimpleDataSet: TSimpleDataSet;
...
Oracle doesn't allow to insert both fields simultaneously if the total size of data is more than 4000 bytes.
As you can see in the rest of the topic, I'm using ODAC.
-
AlexP
- Devart Team
- Posts: 5530
- Joined: Tue 10 Aug 2010 11:35
Post
by AlexP » Fri 05 Nov 2010 15:08
Hello,
This piece of code demonstrates how to use ODAC when inserting data:
OraQuery1.SQL.Clear;
OraQuery1.SQL.Text := 'SELECT * FROM ALEXP_BLOB';
OraQuery1.Open;
OraQuery1.Append;
OraQuery1.FieldByName('id').AsInteger :=1;
(OraQuery1.FieldByName('TST_BLOB') as TBlobField).LoadFromFile('e:\1.bmp');
(OraQuery1.FieldByName('TST_LONG_ROW') as TBlobField).LoadFromFile('e:\1.bmp');
OraQuery1.post;
-
upscene
- Posts: 306
- Joined: Thu 19 Oct 2006 08:13
Post
by upscene » Fri 05 Nov 2010 15:12
AlexP wrote:Hello,
This piece of code demonstrates how to use ODAC when inserting data:
OraQuery1.SQL.Clear;
OraQuery1.SQL.Text := 'SELECT * FROM ALEXP_BLOB';
OraQuery1.Open;
OraQuery1.Append;
OraQuery1.FieldByName('id').AsInteger :=1;
(OraQuery1.FieldByName('TST_BLOB') as TBlobField).LoadFromFile('e:\1.bmp');
(OraQuery1.FieldByName('TST_LONG_ROW') as TBlobField).LoadFromFile('e:\1.bmp');
OraQuery1.post;
As you can see in the rest of the post, I'm using a parameterized INSERT statement (no files involved).
For some reason, a LONG RAW always fails on insert data longer than 2000 or 4000 bytes.
BLOB works fine though.
When I change the code, LONG RAW appears to work fine, but BLOB fails.
I would like to have code that works with both.
-
AlexP
- Devart Team
- Posts: 5530
- Joined: Tue 10 Aug 2010 11:35
Post
by AlexP » Mon 08 Nov 2010 09:38
Hello,
You should set the OraQuery1.Options.TemporaryLobUpdate property to true, the TOraQuery parameters for BLOB should be DataType = OraBlob and ParamType = ptInput, and for LONG RAW they should be DataType = Blob and ParamType = ptInput.
The sql statment:
INSERT INTO TEST_BLOB
(ID, TST_LONG_ROW, TST_BLOB)
VALUES
(:ID, :TST_LONG_ROW, :TST_BLOB)
To insert data use the following code:
OraQuery1.ParamByName('ID').AsInteger:= 1;
OraQuery1.ParamByName('TST_LONG_ROW').LoadFromStream(stream,ftBlob);
OraQuery1.ParamByName('TST_BLOB').LoadFromStream(stream, ftOraBlob);
OraQuery1.Execute;
It this case all data (BLOB and LONG RAW) will be inserted correctly.