如何将MySQL Blob字段转换为用于插入语句的字符串

时间:2019-06-29 09:00:05

标签: delphi

我正在为我的应用程序创建“备份/还原”功能,但遇到了问题 将blob转换为sql语句。我有此代码:

function GetDatasetValues(dataSet: TDataSet): string;
var
  i: Integer;
  ms: TStream;
  ss: TStringStream;
  sTemp : string;
begin
  Result := '';

  for i := 0 to Pred(dataSet.FieldCount) do
  begin

    if not dataSet.Fields[i].IsNull then
    begin

      case dataSet.Fields[i].DataType of
        TFieldType.ftGraphic, TFieldType.ftBlob, TFieldType.ftStream:
        begin
          ms := TMemoryStream.Create;
          try
            TBlobField(dataSet.Fields[I]).SaveToStream(ms);
            ms.Position := 0;
            ss := TStringStream.Create;
            try
              TNetEncoding.Base64.Encode(ms, ss);

              Result := Result + ss.DataString + ',';
            finally
              ss.Free;
            end;
          finally
            ms.Free;
          end;
        end;
// more codes...

结果是:

insert into `tb1`(f_int,f_varchar,f_blob) values 
(1,'1',e1xydGYxXGFuc2lcZGVmZjB7XGZvbnR0Ymx7XGYwXGZuaWwgXCdjZVwnYTJcJ2M4XCdlZFwnZDFc
J2M1XCdiYVwnZGE7fXtcZjFcZm5pbFxmY2hhcnNldDEzNCBcJ2NlXCdhMlwnYzhcJ2VkXCdkMVwn
YzVcJ2JhXCdkYTt9fQ0Ke1xjb2xvcnRibCA7XHJlZDMyXGdyZWVuMzFcYmx1ZTUzO30NCntcKlxn
ZW5lcmF0b3IgTXNmdGVkaXQgNS40MS4yMS4yNTEwO31cdmlld2tpbmQ0XHVjMVxwYXJkXGNmMVxs
YW5nMjA1MlxmMFxmczE4IFQwMzE3MCB4eSBTaW1vbiBcZjFcJ2I2XCdhM1wnYjVcJ2IxXCdjM1wn
YTggXCdiN1wnYzVcJ2NhXCdkNlwnYzhcJ2E1XCdkN1wnZjZcJ2EzXCdhY1wnYzFcJ2VkXCdjZFwn
ZTJcJ2QwXCdjMlwnY2FcJ2MwXCdiZFwnZTdcJ2IyXCdiYlwnZDNcJ2MzXCdiNVwnYzhcJ2I1XCdi
ZFwnYzhcJ2FiXCdiMlwnYmZcJ2JiXCdkOFwnYjFcJ2JlXCdkNFwnZDlcJ2I3XCdkNlwnYmFcJ2Vj
XHBhcg0KXHBhcg0KVDAzMTcwIFwnYzFcJ2JkXCdiOFwnZjZcJ2NhXCdjMlwnYzdcJ2U5XHBhcg0K
XHBhcg0KMVwnYTFcJ2EyXCdkMFwnYzJcJ2NhXCdjMFwnYmRcJ2U3XCdiMlwnYmJcJ2QzXCdjM1wn
YjVcJ2M4XCdiNVwnYmRcJ2M4XCdhYlwnYjJcJ2JmXCdiYlwnZDhcJ2IxXCdiZVwnZDRcJ2Q5XCdi
N1wnZDZcJ2JhXCdlY1wnYjBcJ2M5XCdhM1wnYWNcJ2JmXCdjOVwnZDJcJ2Q0XCdiZlwnYWFcJ2Nh
XCdiY1wnYzJcJ2JkXCdkMFwnZjhcJ2M0XCdjM1wnYjNcJ2Y2XCdkMlwnYmJcJ2IyXCdiZlwnYjdc
J2Q2XCdkN1wnZjZcJ2I3XCdkNlwnYmFcJ2VjXCdhM1wnYWNcJ2QyXCdiYlwnYjJcJ2JmXCdiN1wn
ZDZcJ2JiXCdiOVwnY2RcJ2I2XCdkN1wnY2FcJ2JmXCdlZVwnYTNcJ2FjXCdjNFwnZTNcJ2M4XCdh
NVwnY2ZcJ2ViXCdjZlwnZWJcJ2I3XCdiZFwnYjBcJ2I4XCdhMVwnYTNccGFyDQpccGFyDQoyXCdh
MVwnYTJ4eVwnY2ZcJ2VlXCdjNFwnYmZcJ2EzXCdhY1wnYjdcJ2M1XCdjYVwnZDZcJ2JkXCdiYlwn
YjhcJ2Y4XCdjNFwnZTNcJ2JhXCdjZFwnYjZcJ2EzXCdiNVwnYjFcJ2MzXCdhOFwnYzhcJ2E1XCdk
N1wnZjZcJ2EzXCdhY1wnYmZcJ2M5XCdkMlwnZDRcJ2I0XCdmM1wnZDZcJ2MyXCdkMFwnYjRcJ2I4
XCdmNlwnYjdcJ2EyXCdkNVwnYjlcJ2I3XCdiZFwnYjBcJ2I4XCdiOFwnZjhcJ2NlXCdkMlwnYTFc
J2EzXHBhcg0KXGYwXHBhcg0KfQ0KAA==);

转换后的Blob字段无法在mysql浏览器中执行。它说语法错误。当尝试使用heidsql备份功能备份数据库时,它产生的sql是:

insert INTO `tb1` (`f_int`, `f_varchar`, `f_blob`) VALUES
    (1, '1', _binary 0x7B5C727466315C616E73695C64656666307B5C666F6E7474626C7B5C66305C666E696C205C2763655C2761325C2763385C2765645C2764315C2763355C2762615C2764613B7D7B5C66315C666E696C5C6663686172736574313334205C2763655C2761325C2763385C2765645C2764315C2763355C2762615C2764613B7D7D0D0A7B5C636F6C6F7274626C203B5C72656433325C677265656E33315C626C756535333B7D0D0A7B5C2A5C67656E657261746F72204D7366746564697420352E34312E32312E323531303B7D5C766965776B696E64345C7563315C706172645C6366315C6C616E67323035325C66305C66733138205430333137302078792053696D6F6E205C66315C2762365C2761335C2762355C2762315C2763335C276138205C2762375C2763355C2763615C2764365C2763385C2761355C2764375C2766365C2761335C2761635C2763315C2765645C2763645C2765325C2764305C2763325C2763615C2763305C2762645C2765375C2762325C2762625C2764335C2763335C2762355C2763385C2762355C2762645C2763385C2761625C2762325C2762665C2762625C2764385C2762315C2762655C2764345C2764395C2762375C2764365C2762615C2765635C7061720D0A5C7061720D0A543033313730205C2763315C2762645C2762385C2766365C2763615C2763325C2763375C2765395C7061720D0A5C7061720D0A315C2761315C2761325C2764305C2763325C2763615C2763305C2762645C2765375C2762325C2762625C2764335C2763335C2762355C2763385C2762355C2762645C2763385C2761625C2762325C2762665C2762625C2764385C2762315C2762655C2764345C2764395C2762375C2764365C2762615C2765635C2762305C2763395C2761335C2761635C2762665C2763395C2764325C2764345C2762665C2761615C2763615C2762635C2763325C2762645C2764305C2766385C2763345C2763335C2762335C2766365C2764325C2762625C2762325C2762665C2762375C2764365C2764375C2766365C2762375C2764365C2762615C2765635C2761335C2761635C2764325C2762625C2762325C2762665C2762375C2764365C2762625C2762395C2763645C2762365C2764375C2763615C2762665C2765655C2761335C2761635C2763345C2765335C2763385C2761355C2763665C2765625C2763665C2765625C2762375C2762645C2762305C2762385C2761315C2761335C7061720D0A5C7061720D0A325C2761315C27613278795C2763665C2765655C2763345C2762665C2761335C2761635C2762375C2763355C2763615C2764365C2762645C2762625C2762385C2766385C2763345C2765335C2762615C2763645C2762365C2761335C2762355C2762315C2763335C2761385C2763385C2761355C2764375C2766365C2761335C2761635C2762665C2763395C2764325C2764345C2762345C2766335C2764365C2763325C2764305C2762345C2762385C2766365C2762375C2761325C2764355C2762395C2762375C2762645C2762305C2762385C2762385C2766385C2763655C2764325C2761315C2761335C7061720D0A5C66305C7061720D0A7D0D0A00);

,可以在mysql broser中执行。那么如何在MySQL浏览器中将BLOB转换为可执行的sql字符串呢?或如何实现heidisql方式将blob转换为字符串?

2 个答案:

答案 0 :(得分:2)

这应该为您提供一个良好的开端。编码不是base64,而是简单地将字节转换为十六进制字符串。

function BinToHex(Buffer: array of BYTE; BufSize: Integer):string;
var
  I: Integer;
  const Digits:array[0..15] of char='0123456789abcdef';
begin
  for I := 0 to BufSize - 1 do
    begin
      Result := Result + digits[Buffer[i] shr 4]+digits[Buffer[i] and $0F];
   end;
end;


function GetDatasetValues(dataSet: TDataSet): ansistring;
var
  i: Integer;
  ms: TStream;
  ss: TStringStream;
  sTemp : string;
  bytes : TBYTES;
begin
  Result := '';

  for i := 0 to Pred(dataSet.FieldCount) do
  begin

    if not dataSet.Fields[i].IsNull then
    begin

      case dataSet.Fields[i].DataType of
        TFieldType.ftGraphic, TFieldType.ftBlob, TFieldType.ftStream:
        begin
          ms := TMemoryStream.Create;
          try
            TBlobField(dataSet.Fields[I]).SaveToStream(ms);
            ms.Position := 0;
            ss := TStringStream.Create;
            try
              ms.Read(bytes,ms.Size);
              Result := BinToHex(bytes,ms.Size);
            finally
              ss.Free;
            end;
          finally
            ms.Free;
          end;
        end;
      end;
    end;
  end;
end;

答案 1 :(得分:0)

我检查了heidisql的源代码,并混合了Geoff的初始代码,并提出了

function GetDatasetValues(dataSet: TDataSet): string;
var
  i: Integer;
  ms: TStream;
  sTemp : string;
  bytes : TBytes;

  function HexValue(var ByteData: TBytes): String;
  (*
   referenced source : heidisql
   unit : dbconnection
   function : TDBQuery.HexValue(var ByteData: TBytes):
  *)
  var
    BinLen: Integer;
    Ansi: AnsiString;
  begin
    BinLen := Length(ByteData);
    SetString(Ansi, PAnsiChar(ByteData), BinLen);

    if BinLen = 0 then
    begin
      Result := 'null';
    end
    else
    begin
      SetLength(Result, BinLen*2);
      BinToHex(PAnsiChar(Ansi), PChar(Result), BinLen);
      Result := '_binary 0x' + Result;
    end;

  end;
begin
  Result := '';

  for i := 0 to Pred(dataSet.FieldCount) do
  begin

    if not dataSet.Fields[i].IsNull then
    begin

      case dataSet.Fields[i].DataType of
        TFieldType.ftGraphic, TFieldType.ftBlob, TFieldType.ftStream:
        begin

          ms := TMemoryStream.Create;
          try
            TBlobField(dataSet.Fields[I]).SaveToStream(ms);
            ms.Position := 0;

            SetLength(bytes, ms.Size);
            ms.Read(bytes, ms.Size);

            Result := Result + HexValue(bytes) + ',';

          finally
            ms.Free;
          end;
        end;
// more codes

在生产数据库中测试并工作。.