#1 2012-07-03 02:52:16

profh
Member
Registered: 2010-07-02
Posts: 161

about blob column

i retrieve blob data from database using TSQLDBStatement,but the Query.TotalRowsRetrieved is always zero:

var
  OleDBConnectionProperties:TOleDBConnectionProperties;
  SQLDBConnection:TSQLDBConnection;
  Query: TSQLDBStatement;
......

  OleDBConnectionProperties := TOleDBConnectionProperties.Create('','','','');
  OleDBConnectionProperties.ConnectionString := myrdbmstr;

  try
    SQLDBConnection := OleDBConnectionProperties.NewConnection;
  except
    OleDBConnectionProperties.Free;
    exit;
  end;

  try
    Query := SQLDBConnection.NewStatement;
  except
    SQLDBConnection.Disconnect;
    SQLDBConnection.Free;
    OleDBConnectionProperties.Free;
    exit;
  end;

  try
    Query.Execute('select blobfield from mytable where id=100',true);
    aParams.Resp := Query.ColumnBlob(0);
  except
    Query.Free;
    SQLDBConnection.Disconnect;
    SQLDBConnection.Free;
    OleDBConnectionProperties.Free;
    aParams.Resp := '';
    exit;
  end;

Offline

#2 2012-07-03 08:50:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

You need to call the "Step" method before accessing the columns, as stated by the documentation.

Offline

#3 2012-07-03 09:11:13

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

i add step(true) or step(false) before "aParams.Resp := Query.ColumnBlob(0);",it is just the same problem.

i think 'select blobfield from mytable where id=100' makes the mistake,but it is really a correct SQL statement.

Offline

#4 2012-07-03 11:19:14

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: about blob column

Is you query return rows?
try this code:

if Query.Step then
  aParams.Resp := Query.ColumnBlob(0)
else
  // no rows return


TotalRowsRetrieved increased only after Step() call - see TOleDBStatement.Step source.

Offline

#5 2012-07-03 12:09:50

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

if Query.Step then
  aParams.Resp := Query.ColumnBlob(0)
else
  // no rows return

i check that Query.Step returns false.

but,'select blobfield from mytable where id=100' does return one row, and "blobfield" is text type of Mysql.

Offline

#6 2012-07-03 12:36:59

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

Is it a BLOB/binary or a TEXT column?

If it is a TEXT, you would rather use Query.ColumnUTF8().

It will also depend on your OleDB provider.

Offline

#7 2012-07-03 13:30:19

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

yes, it is a TEXT column,i use Query.ColumnUTF8(), and i also got nothing.

IMHO,Query.Execute('select blobfield from mytable where id=100',true) returns empty,
but 'select blobfield from mytable where id=100' does return one row.

Offline

#8 2012-07-03 13:43:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

You should better use

Query := OleDBConnectionProperties.Execute('select blobfield from mytable where id=100',[]); 

or

Query := OleDBConnectionProperties.Execute('select blobfield from mytable where id=?,[100]); 

Offline

#9 2012-07-03 14:00:55

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

it does not work,and also returns nothing.

the OleDB Provider i use is:mysql-connector-odbc-5.1.11-win32.msi.

Offline

#10 2012-07-03 19:06:50

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

Did you try with ado?

Did you try with syndbexplorer?

Offline

#11 2012-07-03 23:26:01

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

ado and syndbexplorer are the same,
i try syndbexplorer ,if i use "select * from mytable where id = 100",it returns one row with the blobfield empty. if i use 'select blobfield from mytable where id=100',it makes a mistake and popup a error window. the error window just like this:

Error

OLEDB Error 80040E21 - ?? OLE DB
???????????,????? OLEDB ????????????

Exception class:EOleDBException

Offline

#12 2012-07-03 23:30:00

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

i use HeidiSQL 5.0.0.3272 and execute 'select blobfield from mytable where id=100',it can return one row with blobfield content,no error displays.

Offline

#13 2012-07-04 05:40:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

AFAIK HeidiSQL does not use any OleDB provider, but has direct access to the MySQL client library.

That is why I asked about direct ADO access (via your OleDB provider), and also to try with our SynDBExplorer.

The 80040E21 exception is about an unhandled feature of the used OleDB provider.
It sounds like a known limitation of the provider used. See http://www.mysqltalk.org/image-vp435971.html

In order to fix your problem, you'd have to try another OleDB provider (one non using ODBC, but direct MySQL access), like http://cherrycitysoftware.com/ccs/provi … MySQL.aspx or others.

A direct ODBC connection could be a better solution.
The unit is not yet finished. See http://synopse.info/fossil/finfo?name=SynDBODBC.pas

Offline

#14 2012-07-04 08:00:00

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

thanks,
perhaps i should use zeoslib at the server side as i used to.

Offline

#15 2012-07-04 08:33:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

ZeosLib has indeed a direct connector to MySQL.
Could be a better choice in your particular case!

Offline

#16 2012-07-04 09:17:55

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

how long shall the SynDBODBC.pas be finished? is it sutable for my case?
i really want use less third commponent.

thanks again.

Offline

#17 2012-07-04 10:09:49

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

i use sqlite3 and mysql at the same time.

and i used synpdf before,but it can not process chinese font from my emf file,so i pause now, and i shall pick up it later.

i post here before: http://synopse.info/forum/viewtopic.php?id=42

Offline

#18 2012-07-04 10:21:24

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

Direct link to MySQL could make even better sense that the ODBC link.
But I have no MySQL installation at hand, and no need nor time to do it in the close future.
Any contribution is welcome!

About SynPDF, handling font fallback is far from trivial...
Could better be fixed by setting a font explicitly having all chinese glyphs.

Offline

#19 2012-07-04 11:31:01

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

while using ZeosLib,another question is about json:

how to translate between ZeosLib's Query and json?

Offline

#20 2012-07-06 06:45:44

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

here is my code refer syndb,

unit uzjsonquery;

interface

uses Classes,SysUtils, db,ZConnection,ZSqlProcessor,ZDataset,
    SQLite3, SynCommons,syndb,synoledb,SQLite3Commons;

type
  TZJsonQuery = class(TZQuery)
  private
  protected
    procedure ColumnsToJSON(WR: TJSONWriter);
    function  FetchAllToJSON(JSON: TStream; Expanded: boolean): PtrInt;
  public
    function  FetchAllAsJSON(Expanded: boolean; ReturnedRowCount: PPtrInt=nil): RawUTF8;
  end;

implementation

procedure TZJsonQuery.ColumnsToJSON(WR: TJSONWriter);
var col: integer;
    blob: RawByteString;
    tmpstream:TMemoryStream;
begin
  if WR.Expand then WR.Add('{');

  for col := 0 to FieldCount - 1 do begin
    if WR.Expand then
      WR.AddFieldName(Fields[col].FieldName); // add '"ColumnName":'
    if Fields[col].IsNull then
      WR.AddShort('null') else
    case Fields[col].DataType of
      db.ftUnknown:     WR.AddShort('null');
      ftSmallint, ftInteger, ftWord,ftLargeint: WR.Add(Fields[col].AsInteger);
      ftFloat:WR.Add(Fields[col].AsFloat);
      db.ftCurrency: WR.AddCurr64(Fields[col].AsCurrency);
      db.ftDate, db.ftTime, db.ftDateTime: begin
        WR.Add('"');
        WR.AddDateTime(Fields[col].AsDateTime);
        WR.Add('"');
      end;
      ftMemo,ftstring,ftWideString: begin
        WR.Add('"');
        WR.AddJSONEscape(pointer(Fields[col].AsString));
        WR.Add('"');
      end;
      db.ftBlob: begin
        tmpstream := TMemoryStream.Create;
        try
          TBlobField(Fields[col]).SaveToStream(tmpstream);
          tmpstream.Position := 0;
          WR.WrBase64(tmpstream.Memory,tmpstream.Size,true);
        finally
          tmpstream.Free;
          tmpstream := nil;
        end;
      end;
      else raise ESQLDBException.CreateFmt('%s: Invalid ColumnType() %s',
        [ClassName,'']);
    end;
    WR.Add(',');
  end;
  WR.CancelLastComma; // cancel last ','
  if WR.Expand then WR.Add('}');
end;

function TZJsonQuery.FetchAllToJSON(JSON: TStream; Expanded: boolean): PtrInt;
var W: TJSONWriter;
    col: integer;
begin
  result := 0;
  W := TJSONWriter.Create(JSON,Expanded,false);
  try
    SetLength(W.ColNames,FieldCount);//columncount
    for col := 0 to FieldCount-1 do
      W.ColNames[col] := FieldDefList.FieldDefs[col].Name;
    W.AddColumns;
    if Expanded then W.Add('[');
     
    First;
    while (not Eof) do
    begin
      ColumnsToJSON(W);
      W.Add(',');
      inc(result);

      Next;
    end;
    W.CancelLastComma; // cancel last ','
    W.Add(']');
    if not Expanded then W.Add('}');
    W.Add(#10);
    W.Flush;
  finally
    W.Free;
  end;
end;

function TZJsonQuery.FetchAllAsJSON(Expanded: boolean;
                            ReturnedRowCount: PPtrInt=nil): RawUTF8;
var Stream: TRawByteStringStream;
    RowCount: PtrInt;
begin
  Stream := TRawByteStringStream.Create;
  try
    RowCount := FetchAllToJSON(Stream,Expanded);
    if ReturnedRowCount<>nil then ReturnedRowCount^ := RowCount;
      
    result := Stream.DataString;
  finally
    Stream.Free;
  end;
end;

it is ok for me, and i hope it is usful for someone else.

Offline

#21 2012-07-06 08:32:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

The whole idea is good.
Thanks for sharing the code!

I suspect you'll have issues with UTF-8 encoding. You are mixing RawUTF8/UTF-8 buffers and plain String type.
Accents will probably be lost in the process.

Offline

#22 2012-07-06 08:42:38

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

i see, and i will check it.

thanks a lot.

Offline

#23 2012-07-06 08:47:16

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: about blob column

By the way, I'm working on font fall-back for SynPDF.

I hope that it will be able to easily handle Chinese characters soon, without the need to set the explicit font.

Offline

#24 2012-07-06 08:54:51

profh
Member
Registered: 2010-07-02
Posts: 161

Re: about blob column

u are the greatest.

Offline

#25 2012-07-10 09:59:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Offline

Board footer

Powered by FluxBB