2

Delphi 2010、UniDAC コンポーネント、Firebird 2.5 SuperServer を使用。データベースの文字セットは ISO_8559_1 (私の Windows のデフォルト) です。

Access データベースから同一のテーブル構造を持つ Firebird データベースにデータを転送するためのデータ転送アプリケーションを作成しています。ADOQuery コンポーネントを使用してソース テーブルからすべての行を選択し、そのレコードセットをループして、パラメーターを含む INSERT ステートメントで UniSQL コンポーネントを使用し、対応するソース データセット フィールド値からパラメーター値を割り当てています。

挿入コマンドを実行すると、「不正な文字列」例外がスローされます。立ち往生しており、問題を解決するために助けが必要です。

コードは次のとおりです。

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; 

ティア、スティーヴル

4

1 に答える 1

0

s := StringReplace(s, '"', '""', [rfReplaceAll]); を s := StringReplace(s, '''''', '''', [rfReplaceAll]) に置き換えようとすると、 ; そして行のコメントを外します;

于 2010-11-11T10:54:28.330 に答える