refactor this Delphi procedure to a function so its result is a string  with the concatenated results of writeln:

procedure GenerateUpdateStatements(AClass: TClass);
var
  Context: TRttiContext;
  RttiType: TRttiType;
  Field: TRttiField;
  Attr: TCustomAttribute;
  TableName: string;
  RefColumn: string;
  IsPrimaryKey: Boolean;
  TableFields: TObjectDictionary<string, TList<TRttiField>>;
  FieldsList: TList<TRttiField>;
  NonPKColumns: TList<string>;
  PKColumns: TList<string>;
  UpdateSQL: string;
  Key: string;
begin
  TableFields := TObjectDictionary<string, TList<TRttiField>>.Create([doOwnsValues]);
  try
    Context := TRttiContext.Create;
    RttiType := Context.GetType(AClass);
    for Field in RttiType.GetFields do
    begin
      TableName := '';
      RefColumn := '';
      IsPrimaryKey := False;

      for Attr in Field.GetAttributes do
      begin
        if Attr is TableAttribute then
          TableName := TableAttribute(Attr).TableName
        else if Attr is RefColumnAttribute then
          RefColumn := RefColumnAttribute(Attr).ColumnName
        else if Attr is PrimaryKeyAttribute then
          IsPrimaryKey := True;
      end;

      if (TableName <> '') then
      begin
        if not TableFields.TryGetValue(TableName, FieldsList) then
        begin
          FieldsList := TList<TRttiField>.Create;
          TableFields.Add(TableName, FieldsList);
        end;
        FieldsList.Add(Field);
      end;
    end;

    // Generate SQL Update statements
    for Key in TableFields.Keys do
    begin
      FieldsList := TableFields[Key];
      NonPKColumns := TList<string>.Create;
      PKColumns := TList<string>.Create;
      try
        for Field in FieldsList do
        begin
          RefColumn := '';
          IsPrimaryKey := False;

          for Attr in Field.GetAttributes do
          begin
            if Attr is RefColumnAttribute then
              RefColumn := RefColumnAttribute(Attr).ColumnName
            else if Attr is PrimaryKeyAttribute then
              IsPrimaryKey := True;
          end;

          // Use the field name if RefColumn is not specified
          if RefColumn = '' then
            RefColumn := Copy(Field.Name, 2, MaxInt); // Remove leading 'F'

          if IsPrimaryKey then
            PKColumns.Add(Format('%s = :%s', [RefColumn, RefColumn]))
          else
            NonPKColumns.Add(Format('%s = :%s', [RefColumn, RefColumn]));
        end;

        // Build SET and WHERE clauses
        if NonPKColumns.Count = 0 then
        begin
          WriteLn('No non-primary key columns to update for table ', Key);
          Continue;
        end;

        if PKColumns.Count = 0 then
        begin
          WriteLn('No primary key columns found for table ', Key, '. Cannot generate UPDATE statement.');
          Continue;
        end;

        UpdateSQL := Format('UPDATE %s SET %s WHERE %s;',
          [Key,
           String.Join(', ', NonPKColumns.ToArray),
           String.Join(' AND ', PKColumns.ToArray)]);

        // Output the generated SQL
        WriteLn('Generated SQL for table ', Key, ':');
        WriteLn(UpdateSQL);
        WriteLn;
      finally
        NonPKColumns.Free;
        PKColumns.Free;
      end;
    end;
  finally
    TableFields.Free;
    Context.Free;
  end;
end;