Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Paradox nach MSSQL (https://www.delphipraxis.net/198865-paradox-nach-mssql.html)

egentur 6. Dez 2018 09:23

Datenbank: Paradox • Version: 4 • Zugriff über: BDE

Paradox nach MSSQL
 
Hallo Zusammen,

Ich habe eine Paradox DB mit Memofeldern die allerdings binäre Daten enthalten
und muss diese nach MSSQL wieder in Memofelder übertragen.

Allerdings habe ich keine direkte Verbindung beider DBs.
Ich müsste aus der Paradox DB ein Schript erzeugen das ich in der MSSQL wieder einspielen kann.

Das Erzeugen des Scripts (Lesen aus Paradox) klappt.
Ich konvertieren die Binärdaten in Hex ( 0x123... ).

Meine Frage : wie bekomme ich die Daten ( 0x123...) wieder in das MSSQL Memofeld
sodass diese dort wieder binär vorliegen ?

Danke für jeden Hinweis !

hoika 6. Dez 2018 10:05

AW: Paradox nach MSSQL
 
Hallo,
ich hatte mir damals für den Umstieg von Paradox auf Interbase ein eigenes Programm geschrieben,
eben u.a. weil ich die Kontrolle über die Blobs haben wollte.

TigerLilly 6. Dez 2018 10:45

AW: Paradox nach MSSQL
 
Ab MSSQL 2008:

SELECT
CONVERT(varbinary(64), '0x16004D616E75623232', 1),
CONVERT(varchar(64), 0x16004D616E75623232, 1),
CONVERT(varchar(64), 0x16004D616E75623232, 2);

Siehe auch CONVERT() in BOL.

egentur 6. Dez 2018 11:07

AW: Paradox nach MSSQL
 
Danke TigerLilly

Ich brauche das Insert Statement für MSSQL
Insert into Table(Field) values ('0x123')

Wobei Field vom Type Text ist.
z.B.
Insert into Table(Field) values ('0x414243')

und der Inhalt des Feldes soll dann 'ABC' sein

eine Idee ?

TigerLilly 6. Dez 2018 12:53

AW: Paradox nach MSSQL
 
Du möchtest aus den Hex kodierten Zeichen die ursprünglichen Zeichen wiederherstellen? Also aus 414243 soll ABC werden?


Code:
CREATE FUNCTION [dbo].[f_hextostr] (@hexstring VARCHAR(512))
RETURNS VARCHAR(256)
AS
begin
declare @char1 char(1), @char2 char(1), @strlen int, @currpos int, @result varchar(256)
set @strlen=len(@hexstring)
set @currpos=1
set @result=''
while @currpos<@strlen
begin
set @char1=substring(@hexstring,@currpos,1)
set @char2=substring(@hexstring,@currpos+1,1)
if (@char1 between '0' and '9' or @char1 between 'A' and 'F')
and (@char2 between '0' and '9' or @char2 between 'A' and 'F')
set @result=@result+
char((ascii(@char1)-case when @char1 between '0' and '9' then 48 else 55 end)*16+
ascii(@char2)-case when @char2 between '0' and '9' then 48 else 55 end)
set @currpos = @currpos+2
end
return @result
end

Code:
insert into …. () values (f_hextostr(hexstring)

Achtung: Die Funktion geht davon aus, dass die Hex Zeichen in jeweils 2 Zeichen kodiert werden.

Uwe Raabe 6. Dez 2018 13:10

AW: Paradox nach MSSQL
 
Du könntest auch das Bulk Copy Programm verwenden. Das benötigt einfach nur eine Textdatei, in der die Records mit CRLF und die Felder mit TAB getrennt sind. Blob-Felder werden dabei als Block von Hexbytes dargestellt. Damit lassen sich auch große Tabellen ziemlich schnell übertragen.

https://docs.microsoft.com/de-de/sql...ql-server-2017

egentur 6. Dez 2018 14:22

AW: Paradox nach MSSQL
 
Hallo TigerLilly

Vielen Dank,
das war genau das was ich brauchte.

Ich muss halt nur die Funktion in der Ziel DB anlegen.

Viele Grüße
und schöne Weihnachten schonmal

NormanNG 6. Dez 2018 14:34

AW: Paradox nach MSSQL
 
Hi,

oder ohne funktion mittels dynamic sql

Code:
 declare @data varchar(100)
 select @data = '0x414243'

 exec ( 'SELECT CONVERT(varchar(36),' + @data + ')')

egentur 7. Dez 2018 12:45

AW: Paradox nach MSSQL
 
Hallo Zusammen

Jetzt muss ich doch nochmal nachfragen.
Beim Exportieren aus Paradox erhalte ich Strings wie z.B.

INSERT INTO MyTable(
Counter,SData) values (
176,dbo.f_hextostr('0x2620DB8A0000173A83B1DAB9ACB9 A90760400512940C89B...'))

Jetzt ist der Value von SData, sprich der Wert für 0x262... doch teilweise sehr groß,
ca. 23k

Nun kann das SSMS (Sql Server Management Studio) diesen String nicht interpretieren (weil zu lang)
auch SQLCMD bringt hier Syntaxfehler beim Versuch zu importieren.

Gibt es einen anderen Weg die Daten wieder einzuspielen ?

Dank für eure Hinweise

Uwe Raabe 7. Dez 2018 13:12

AW: Paradox nach MSSQL
 
Zitat:

Zitat von egentur (Beitrag 1420303)
Gibt es einen anderen Weg die Daten wieder einzuspielen ?

Siehe https://www.delphipraxis.net/1420237-post6.html

Wenn du einer Routine zum Export eines DataSet in dem für bcp erwarteten Formats brauchst, kann ich vielleicht damit dienen (muss nur etwas graben).

TigerLilly 7. Dez 2018 13:13

AW: Paradox nach MSSQL
 
Welchen Fehler bekommst du denn genau?

Versuch mal den Text zu casten: auf varchar(max) oder teile den string in Teil auf auf und CONCAT die.

https://stackoverflow.com/questions/...sert-statement
https://stackoverflow.com/questions/...-in-sql-server

egentur 7. Dez 2018 13:18

AW: Paradox nach MSSQL
 
Ich muss hier aber die Liste der Felder bime Insert mit angeben,
da die Zieltabelle mehr Felder als die Quelltabelle hat.

Uwe Raabe 7. Dez 2018 13:39

AW: Paradox nach MSSQL
 
Zitat:

Zitat von egentur (Beitrag 1420306)
Ich muss hier aber die Liste der Felder bime Insert mit angeben,
da die Zieltabelle mehr Felder als die Quelltabelle hat.

Ich nehme mal an, das bezieht sich auf den bcp-Import? Dann ist das kein Problem. Das bcp erwartet eine Textdatei, die dem Feldaufbau der Tabelle entspricht. Man muss also lediglich beim Erstellen der Datei den Feldaufbau der Zieltabelle kennen und die Felder in der passenden Reihenfolge ausgeben bzw. leer lassen.

Wenn wirklich echtes Interesse besteht, würde ich das ja mal an einem konkreten Beispiel aufzeigen.

egentur 7. Dez 2018 13:49

AW: Paradox nach MSSQL
 
Hallo Herr Raabe

Dsa wäre sehr nett !!

Gruß
egentur

HolgerX 7. Dez 2018 13:56

AW: Paradox nach MSSQL
 
Hmm..

(Mal ganz D6 Progger, Quick and Dirty);

Ich würde nen keines Tool schreiben, welches eine Connection per ADO zur Paradox-Datenbank öffnet, nen query mit dem Select für die benötigten Daten.
(Alles simple per Button click)

Delphi-Quellcode:
ADOQuery.Open;
ADOQuery.SaveToFile(ExtractFilePath(ParamStr(0)) + 'Test.Dat', pfXML);
ADOQuery.Close;
Somit werden alle Daten in eine XML-Datei geschrieben (natürlich den Dateinamen nach deinen Wünschen ändern.

Über einen 2. Button das selbe Tool verwenden, um eine Verbindung zur MSSQL-Datenbank zu öffen (ebenfalls per ADO)
und dann kannst Du mit

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  ADOQuery.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Test.Dat');
  ADOQuery.First;
  While not ADOQuery.Eof do begin
    // Insert mit den Daten aus ADOQuery....

    ADOQuery.Next;
  end;
  ADOQuery.Close;
end;
einen gezielten Insert machen, ganz nach deinen Wünschen..

Hierbei werden die Daten 1:1 übertragbar...

Somit bei Paradox Button1, Datendatei und Tool auf anderen Server mitnehmen und per Button2 dort in die MSSQL Datenbank schieben...

Geschrieben in wenigen Minuten...

(Nur so nen Gedanke.. ;) )

Uwe Raabe 7. Dez 2018 22:39

AW: Paradox nach MSSQL
 
Hier eine kleine Routine, die ein DataSet in eine BCP-Importdatei schreibt. Die Felder der Quell- und Zieltabelle müssen dabei in Reihenfolge und Typ übereinstimmen (Namen sind egal).
Delphi-Quellcode:
procedure ExportDataSetToBCP(DataSet: TDataSet; const FileName: string);

  function GetBytesText(const ABytes: TBytes): string;
  var
    B: Byte;
  begin
    Result := '';
    for B in ABytes do
      Result := Result + IntToHex(B, 2);
  end;

var
  fld: TField;
  S: string;
  sep: string;
  writer: TStreamWriter;
begin
  writer := TStreamWriter.Create(FileName, False, TEncoding.ANSI);
  try
    DataSet.Active := true;
    DataSet.First;
    while not DataSet.Eof do begin
      sep := '';
      for fld in DataSet.Fields do begin
        Writer.Write(sep);
        if not fld.IsNull then begin
          case fld.DataType of
            ftDate: S := FormatDateTime('yyyy-mm-dd', fld.AsDateTime);
            ftTime: S := FormatDateTime('hh:nn:ss', fld.AsDateTime);
            ftDateTime: S := FormatDateTime('yyyy-mm-dd hh:nn:ss', fld.AsDateTime);
            ftTimeStamp: S := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', fld.AsDateTime);
            ftBlob: S := GetBytesText(fld.AsBytes);
          else
            S := fld.DisplayText;
          end;
          Writer.Write(S);
        end;
        sep := #9;
      end;
      Writer.WriteLine;
      DataSet.Next;
    end;
  finally
    writer.Free;
  end;
end;
Der passende BCP-Aufruf sehe dann folgendermaßen aus:
Code:
bcp <Database>.dbo.<Table> in "<ImportFile>" -b 10000 -c -C ACP -e "<ErrorFile>" -E -T -S <Server>
Die Platzhalter in spitzen Klammern müssen natürlich durch die tatsächlichen Werte ersetzt werden.

TigerLilly 8. Dez 2018 09:24

AW: Paradox nach MSSQL
 
Weil diese Importsachen in der Praxis so kompliziert sein können:

- Wenn ein Text TAB oder CR/LF enthält, stört das das BCP gar nicht?
- Sollten die Hexzeichen nicht mit 0x eingeleitet werden?
- Sollten nicht Floats auch in Standard-US-Format gebracht werden?

Uwe Raabe 8. Dez 2018 10:02

AW: Paradox nach MSSQL
 
Zitat:

Zitat von TigerLilly (Beitrag 1420354)
Weil diese Importsachen in der Praxis so kompliziert sein können:

- Wenn ein Text TAB oder CR/LF enthält, stört das das BCP gar nicht?
- Sollten die Hexzeichen nicht mit 0x eingeleitet werden?
- Sollten nicht Floats auch in Standard-US-Format gebracht werden?

Das gezeigte Beispiel entstammt einer konkreten Portierung von NexusDB nach MSSQL, erhebt keinen Anspruch auf Vollständigkeit und deckt vermutlich auch nur den damals tatsächlich importiereten Datenbestand ab. Es ist aber leicht ersichtlich, wo und wie die übrigen Fälle behandelt werden müssen. Für genauere Spezifikationen des erwarteten Formats verweise ich jetzt einfach mal auf die Dokumentation zu BCP.

Zu den konkreten Fragen:
- In dem Fall muss man halt andere Feld- bzw. Record-Trennzeichen(-folgen) definieren, die nicht zu Kollisionen mit dem Datenbestand führen.
- Nicht wenn das Feld in MSSQL als VARBINARY angelegt ist. Andernfalls wäre die Hexdarstellung auch wohl nicht geeignet.
- Vermutlich ja, aber das war in diesem Fall schon von der Einstellung in Windows vorgegeben.

TigerLilly 8. Dez 2018 15:10

AW: Paradox nach MSSQL
 
:thumb:

egentur 14. Dez 2018 14:04

AW: Paradox nach MSSQL
 
Hallo TigerLilly, hallo Herr Raabe

die Funktion
f_hextostr(hexstring)
hat schon funktioniert, da das Zielfeld vom Typ Memo war.

Nochmals vielen Dank
egentur


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:09 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