2010-11-06 23 views
2

Utilisation de Delphi 2010, de composants UniDAC, de Firebird 2.5 SuperServer. Le jeu de caractères de la base de données est ISO_8559_1 (mon Windows par défaut). Je suis en train d'écrire une application de transfert de données pour transférer des données d'une base de données Access à une base de données Firebird qui a une structure de table identique. J'utilise un composant ADOQuery pour sélectionner toutes les lignes de la table source, puis boucler dans ce jeu d'enregistrements et utiliser le composant UniSQL avec une instruction INSERT avec des paramètres, en affectant des valeurs de paramètre à partir des valeurs de champ de dataset source correspondantes. Lors de l'exécution de la commande d'insertion, une exception "Chaîne mal formée" est générée. Je suis coincé et j'ai besoin d'aide pour résoudre le problème.Exception "Chaîne mal formée" lors de l'insertion dans Firebird (paramètres Delphi, UniDAC, UniSQL, INSERT, etc.)

Code suit:

function TDataTransfer.BeginTransfer(AProgressCallback: TProgressCallback): Boolean; 
var 
    slSQLSelect, slSQLInsert: TStringList; 
    i, f, z: Integer; 
    cmdS, cmdI: String; 
    adods: TADODataSet; 
    fbcmd: TUniSQL; 
    fbscript: TUniscript; 
    q: String; 
    s : WideString; 
begin 
    FProgressCallback := AProgressCallback; 

    fbscript := TUniscript.Create(nil); 
    try 
    fbscript.Connection := FirebirdConnection; 
    FirebirdConnection.StartTransaction; 
    try 
     fbscript.Delimiter := ';'; 
     fbscript.ExecuteFile(ExtractFilePath(ParamStr(0)) + 'Firebird_Script_0.txt'); 
     FirebirdConnection.CommitRetaining; 

     slSQLSelect := TStringList.Create; 
     slSQLInsert := TStringList.Create; 
     adods := TADODataSet.Create(nil); 
     fbcmd := TUniSQL.Create(nil); 
     try 
     adods.Connection := AccessConnection; 
     fbcmd.Connection := FirebirdConnection; 

     slSQLSelect.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Access_Select.txt'); 
     slSQLInsert.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Firebird_Insert.txt'); 

     z := slSQLSelect.Count - 1; 
     for i := 0 to z do begin 
      cmdS := slSQLSelect[i]; 
      cmdI := slSQLInsert[i]; 

      adods.CommandText := cmdS; 
      fbcmd.SQL.Text := cmdI; 

      adods.Open; 

      while not adods.Eof do begin 
      for f := 0 to adods.FieldCount - 1 do 
       try 
       if adods.FieldDefs[f].DataType = ftWideString then begin 
        s := adods.Fields[f].AsAnsiString ; 
        q := '"'; 
//     if AnsiStrPos(PAnsiChar(@s), PAnsiChar(q)) <> nil then 
//     s := StringReplace(s, '"', '""', [rfReplaceAll]); 
        fbcmd.Params[f].Value := s; 
       end 
       else 
       if adods.FieldDefs[f].DataType = ftWideMemo then 
        fbcmd.Params[f].SetBlobData(adods.CreateBlobStream(adods.Fields[f], bmRead)) 
       else 
        fbcmd.Params[f].Value := adods.Fields[f].Value; 
       except 
       raise; 
       end; 

      try 
       fbcmd.Execute; 
       // FirebirdConnection.CommitRetaining; 
      except 
       raise; 
      end; 
      adods.Next; 
      end; 
      adods.Close; 

      FProgressCallback((i + 1) * 100 div (z + 1), 10); 
     end; 
     finally 
     slSQLSelect.Free; 
     slSQLInsert.Free; 
     adods.Free; 
     fbcmd.Free; 
     end; 

     fbscript.ExecuteFile(ExtractFilePath(ParamStr(0)) + 'Firebird_Script_1.txt'); 

     FirebirdConnection.Commit; 

     Result := True; 
    except 
     FirebirdConnection.Rollback; 
     Result := False; 
    end; 
    finally 
    fbscript.Free; 
    end; 


end; 

TIA, SteveL

+1

Vous pouvez enregistrer l'instruction dans un fichier juste avant fbcmd.Execute. ce qui est dans votre fichier (ou la dernière déclaration si vous l'ajoutez) est le coupable –

+0

Essayez de remplacer "s: WideString;" avec "s: AnsiString;" – oodesigner

+1

Il s'agit d'un champ Blob provoquant l'erreur. Que dois-je faire pour corriger l'erreur? – SteveL

Répondre

0

Si vous essayez de remplacer s: = StringReplace (s, '"', ' ""', [rfReplaceAll]); avec s : = StringReplace (s, '' '' '', '' '', [rfReplaceAll]) et décommentez la ligne;