AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi SQL-Abfrage so "direkt" wie möglich in csv-Datei speichern
Thema durchsuchen
Ansicht
Themen-Optionen

SQL-Abfrage so "direkt" wie möglich in csv-Datei speichern

Ein Thema von juergen · begonnen am 20. Jun 2007 · letzter Beitrag vom 21. Jun 2007
Antwort Antwort
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#1

SQL-Abfrage so "direkt" wie möglich in csv-Datei s

  Alt 20. Jun 2007, 21:47
Datenbank: Pervasive SQL • Version: 8.x-9.x • Zugriff über: ODBC
Hallo zusammen,

nun bin ich schon eine ganze Weile am suchen...
Ich möchte ein Progrämmchen erstellen, welches jeden Tag 2-6 mal zu einer festgelegten Uhrzeit durch den Windows Taskplaner aufgerufen werden soll.
Dieses Progrämmchen soll dann aus einer Ini-Datei einen oder auch mehrere dort hinterlegte SQL-Abfrage(n) absetzen und das Ergebnis in eine csv-Datei schreiben.
Pro SQL-Abfrage soll dann das Ergebnis in eine Datei an einen in der ini-Datei hinterlegten Pfad gespeichert werden.
Im Prinzip soll der Benutzer davon gar nichts mitbekommen; es soll über den beschriebenen Weg völlig autom. laufen; möglichst ohne große "Umwege".

Ich bin jetzt soweit, dass ich die Ergebnisse habe (im Moment in einem DBGrid), mit der ini-Datei auch alles funktioniert, aber ich nun nicht weiter weiß, wie ich die Ergebnisse in eine csv-Datei abspeichern kann.

Jetzt hatte ich schon mehrere Varianten gefunden.
Mein derzeitiger Favorit:
- ein DBGrid (wäre eine kostenpflichtige Komponente), welche direkt SaveToFile-mäßig parametriert werden kann.

Gibt es Alternativen? Also vllt. ohne den "Umweg" über ein DBGrid.
Gibt es Empfehlungen für eine Komponente, welche dieses Vorhaben unterstützt?

Da ich mich bis jetzt noch gar nicht mit DB beschäftigt habe, hoffe ich, dass diese Frage nicht zu trivial ist...

Bin für jeden Hinweis dankbar!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#2

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 20. Jun 2007, 22:06
Ich denk eine recht geschickte Lösung wäre der Weg über Class Helper
Delphi-Quellcode:
TYourDataset = class helper for TDataset
public
    procedure Save (Filename : string) ;
end;
Danach steht dir in allen TDataset Erben (TADOQuery usw.) direkt die Methode Save zur Verfügung. Du musst nicht mal casten.

Save musst du halt nur noch implementieren, aber das sollte nicht so kompliziert sein.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.541 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 20. Jun 2007, 22:09
Hallo, ich habe vor Jahren mal eine Unit erstellt, die die Daten eines DBGrid als *.csv exportiert. Sie ist mit einiger Sicherheit ziemlich buggy, aber vielleicht reicht es Dir ja so. Ansonsten steht es Dir (und anderen) frei, sie zu verbessern.
Delphi-Quellcode:
unit DetDBExport;

interface

uses Windows, Classes, FileCtrl, SysUtils, DBGrids, DB, DBTables;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string);overload;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean);overload;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean);overload;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean;
                            ForceDestDir: Boolean);overload;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean;
                            ForceDestDir: Boolean;
                            AskUser: Boolean);overload;

procedure ExportDBGridToXML(TheGrid: TDBGrid;
                            const FileName, DataDescription: string);

implementation

function GetNiceName(const sDir: string): string;
begin
  Result := '';
  if Length(sDir) = 0 then exit;
  if AnsiLastChar(sDir) = '\then
    Result := Copy(sDir,1,Length(sDir) - 1)
  else
    Result := sDir;
end;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  Liste := TStringList.Create;
  with TheGrid.DataSource.DataSet do
    try
      First;
      if ShowFieldNames then
        begin
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].FieldName;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
        end;
      for i := 0 to RecordCount - 1 do
        begin
          Zeile := '';
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].AsString;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
          Next;
        end;
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  Liste := TStringList.Create;
  with TheGrid.DataSource.DataSet do
    try
      First;
      if ShowFieldNames then
        begin
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].FieldName;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
        end;
      for i := 0 to RecordCount - 1 do
        begin
          Zeile := '';
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].AsString;
              if QuoteStrings and (Fields[j] is TStringField) then
                Feld := '"' + Feld + '"';
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
          Next;
        end;
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  Liste := TStringList.Create;
  with TheGrid.DataSource.DataSet do
    try
      First;
      if ShowFieldNames then
        begin
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].FieldName;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
        end;
      for i := 0 to RecordCount - 1 do
        begin
          Zeile := '';
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].AsString;
              if QuoteStrings and (Fields[j] is TStringField) then
                Feld := '"' + Feld + '"';
              Zeile := Zeile + Feld + Trenner;
            end;
          if DeleteLastLimiter then
            System.Delete(Zeile,Length(Zeile) - Pred(Length(Trenner)),Length(Zeile));
          Liste.Add(Zeile);
          Next;
        end;
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean;
                            ForceDestDir: Boolean);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  if not DirectoryExists(ExtractFilePath(FileName)) then
    begin
      if ForceDestDir then
        begin
          ForceDirectories(ExtractFilePath(FileName));
          if not DirectoryExists(ExtractFilePath(FileName)) then
            begin
              MessageBox(0,
                         PChar(Format('Das Verzeichnis %s konnte nicht angelegt'
                         +#13#10+' werden.',
                         [GetNiceName(ExtractFilePath(FileName))])),
                         'Fehler',
                         MB_OK or MB_ICONERROR);
              exit;
            end;
        end
      else
        begin
          MessageBox(0,
                     PChar(Format('Das Verzeichnis %s existiert nicht.',
                     [GetNiceName(ExtractFilePath(FileName))])),
                     'Fehler',
                     MB_OK or MB_ICONERROR);
          exit;
        end;
    end;
  Liste := TStringList.Create;
  with TheGrid.DataSource.DataSet do
    try
      First;
      if ShowFieldNames then
        begin
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].FieldName;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
        end;
      for i := 0 to RecordCount - 1 do
        begin
          Zeile := '';
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].AsString;
              if QuoteStrings and (Fields[j] is TStringField) then
                Feld := '"' + Feld + '"';
              Zeile := Zeile + Feld + Trenner;
            end;
          if DeleteLastLimiter then
            System.Delete(Zeile,Length(Zeile) - Pred(Length(Trenner)),Length(Zeile));
          Liste.Add(Zeile);
          Next;
        end;
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

procedure ExportDBGridToCSV(TheGrid: TDBGrid;
                            ShowFieldNames: Boolean;
                            const FileName, Trenner: string;
                            QuoteStrings: Boolean;
                            DeleteLastLimiter: Boolean;
                            ForceDestDir: Boolean;
                            AskUser: Boolean);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  if not DirectoryExists(ExtractFilePath(FileName)) then
    begin
      if (MessageBox(0,
                     PChar(Format('Das Verzeichnis %s existiert nicht.' +#13#10+
                     'Soll es angelegt werden?',
                      [GetNiceName(ExtractFilePath(FileName))])),
                      'Verzeichnis nicht gefunden',
                      MB_OKCANCEL or MB_ICONQUESTION) = idOK) and ForceDestDir
       then
        begin
          ForceDirectories(ExtractFilePath(FileName));
          if not DirectoryExists(ExtractFilePath(FileName)) then
            begin
              MessageBox(0,
                         PChar(Format('Das Verzeichnis %s konnte nicht' +
                         ' angelegt werden.',
                         [GetNiceName(ExtractFilePath(FileName))])),
                         'Fehler',
                         MB_OK or MB_ICONERROR);
              exit;
            end;
        end
      else
        begin
          if not ForceDestDir then
            MessageBox(0,
                       PChar(Format('Das Verzeichnis %s existiert nicht.',
                       [GetNiceName(ExtractFilePath(FileName))])),
                       'Fehler',
                       MB_OK or MB_ICONERROR);
          exit;
        end;
    end;
  Liste := TStringList.Create;
  with TheGrid.DataSource.DataSet do
    try
      if ShowFieldNames then
        begin
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].FieldName;
              Zeile := Zeile + Feld + Trenner;
            end;
          Liste.Add(Zeile);
        end;
      First;
      for i := 0 to RecordCount - 1 do
        begin
          Zeile := '';
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Feld := Fields[j].AsString;
              if QuoteStrings and (Fields[j] is TStringField) then
                Feld := '"' + Feld + '"';
              Zeile := Zeile + Feld + Trenner;
            end;
          if DeleteLastLimiter then
            System.Delete(Zeile,Length(Zeile) - Pred(Length(Trenner)),Length(Zeile));
          Liste.Add(Zeile);
          Next;
        end;
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

procedure ExportDBGridToXML(TheGrid: TDBGrid;
                            const FileName, DataDescription: string);
var i, j: integer;
    Liste: TStringList;
    Zeile, Feld, Desc: string;
begin
  if not(Assigned(TheGrid) and Assigned(TheGrid.DataSource)) then exit;
  if Length(trim(DataDescription)) < 1 then exit;
  Liste := TStringList.Create;
  Liste.Add('<?xml version="1.0" encoding="ISO-8859-1" ?>');
  try
    Desc := TDBDataSet(TheGrid.DataSource.DataSet).DataBaseName;
  except
    Desc := 'Datensatz';
  end;
  Liste.Add(Format('<%s>',[Desc]));
  with TheGrid.DataSource.DataSet do
    try
      First;
      for i := 0 to RecordCount - 1 do
        begin
          Liste.Add(Format(' <%s>',[DataDescription]));
          for j := 0 to TheGrid.FieldCount - 1 do
            begin
              Zeile := Format(' <%s>',[Fields[j].FieldName]);
              Feld := Fields[j].AsString;
              Feld := StringReplace(Feld,'&','&amp;',[rfReplaceAll]);
              Feld := StringReplace(Feld,'>','>',[rfReplaceAll]);
              Feld := StringReplace(Feld,'<','<',[rfReplaceAll]);
              Feld := StringReplace(Feld,'"','&quot;',[rfReplaceAll]);
              Feld := StringReplace(Feld,'''','&apos;',[rfReplaceAll]);
              Zeile := Zeile + Feld + Format('</%s>',[Fields[j].FieldName]);
              Liste.Add(Zeile);
            end;
          Liste.Add(Format(' </%s>',[DataDescription]));
          Next;
        end;
      Liste.Add(Format('</%s>',[Desc]));
    finally
      Liste.SaveToFile(FileName);
      Liste.Free;
    end;
end;

end.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 20. Jun 2007, 22:55
@ Jelly,
vielen Dank für deinen Hinweis! Leider verstehe ich es nicht ganz. Habe da ca. 4 Seiten über Class Helper gelesen, aber nicht so wirklich schlau draus geworden.
Ich hätte dann also eine neue Methode. Und hier müsste ich Save implementieren.
Save würde dann sowas sein wie in DeddyH seiner Unit?
Wo liegen bei deinem Vorschlag die Vorteile gegenüber z.B. der Unit von DeddyH? Das ist mir halt nicht ganz klar.

@ DeddyH,
vielen Dank!
Das hilft mir auf die Schnelle schon mal sehr viel! Ich finde, dass sieht richtig gut aus!
Werde es testen und falls mir Fehler auffallen, diese hier posten.

Also, vielen Dank und
Good Night!
Jürgen
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#5

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 21. Jun 2007, 09:55
Hab auch noch nie wirklich mit Class Helper gearbeitet, aber wie ich es verstanden hab, erweitert ein Class Helper eine bestehende Klasse, in diesem Fall TDataset.

Jeder Abkömmling von TDataset erhält damit also die in der Class Helper definierten Methoden gleich mit. Nutzt du z.B. TADOQuery, das ja auch von TDataset erbt, so kannst du dort direkt die Methoden aus deiner Class Helper Klasse aufrufen.

Delphi-Quellcode:
qry := TADOQuery.Create (Self) ;
qry.connectionstring := 'sss' ;
qry.Save ('c:\test.csv') ;
Du musst also keine externe Funktion deklarieren, der du dann ein Dataset als Parameter übergibst. Class Helper ist demnach etwas objektorientierter.

Würd mich interessieren, obs damit jetzt auch wirklich klappt, denn ich habs ja selbst noch nie wirklich benutzt.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 21. Jun 2007, 10:12
Der Datenexport von einer Datenmenge in eine CSV-Datei hat zunächst mal nichts mit einem DBGrid zu tun.
Ein DBGrid dient lediglich als visuelles Steuerelement (Control) um Daten anzuzeigen.
Also kann die Quelle der Daten nur ein TDataSet sein und das Ziel ist ein Stream oder eine Datei:
Delphi-Quellcode:
procedure ExportDataset2CsvStream(ds:TDataSet; stream:TStream; delimiter, quotechar:Char);
procedure ExportDataset2CsvFile(ds:TDataSet; const filename:string; delimiter, quotechar:Char);
Es macht Sinn den eigentlichen Datenexport in einen Stream vorzunehmen. Der Export in ein File kann dann die Stream-Procedure mitbenutzen.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: SQL-Abfrage so "direkt" wie möglich in csv-Dat

  Alt 21. Jun 2007, 12:50
Hallo shmia,

ich denke, dass ist genau das was ich gesucht habe (halt so direkt wie möglich).

Naja, dann muss ich mich mit dem füllen des Streams und dem eigentlichem Export aus diesem beschäftigen.
Erst mal vielen Dank!

Gruß
Jürgen
Jürgen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz