Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi INSERT INTO SELECT ohne Spaltenliste (https://www.delphipraxis.net/163828-insert-into-select-ohne-spaltenliste.html)

Alex.G 18. Okt 2011 07:45

Datenbank: MSSQL • Version: 2005 • Zugriff über: ADO

INSERT INTO SELECT ohne Spaltenliste
 
Moin!

Ich will alle Daten einer Datenbank (aus jeder Tabelle) in eine Zweite identisch aufgebaute Datenbank übertragen. Da dies in Delphi mit einer For-Schleife abläuft, kann ich keine feste Spaltenliste eintragen. Habe auch schon gegooglet und diese Variante gefunden:
Code:
INSERT INTO TestDB2.dbo.Kunden SELECT * FROM TestDB1.dbo.Kunden
Leider bekomme ich eine Exception, da keine Spaltenliste angegeben ist. Gibt es eine Möglichkeit die Spaltenliste auszulassen bzw. variabel anzugeben?

Gruß
Alex

DeddyH 18. Okt 2011 07:52

AW: INSERT INTO SELECT ohne Spaltenliste
 
Evtl. mit Delphi-Referenz durchsuchenTDataset.GetFieldNames und die Liste dann als Delphi-Referenz durchsuchenTStrings.CommaText übergeben?

Bernhard Geyer 18. Okt 2011 07:53

AW: INSERT INTO SELECT ohne Spaltenliste
 
Du müsstest erst z.B. mit einem
Code:
Select * from TestDB1.dbo.Kunden where 1=2
dir die Liste der Ergebnisspalten liefern und dann das SQL-Statement entsprechend erweitern.

Bummi 18. Okt 2011 10:05

AW: INSERT INTO SELECT ohne Spaltenliste
 
Code:
Select *
Into NewTable
From OldTable
gegf.
Code:
Select *
Into AndereDB.dbo.NewTable
From OldTable

Alex.G 18. Okt 2011 11:04

AW: INSERT INTO SELECT ohne Spaltenliste
 
Danke für die Antworten!
Was aber, wenn die Datenbanken auf verschiedenen Servern laufen?

Bernhard Geyer 18. Okt 2011 11:10

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Alex.G (Beitrag 1131008)
Danke für die Antworten!
Was aber, wenn die Datenbanken auf verschiedenen Servern laufen?

Dann müsstest du versuchen einen (bei MS SQL Server heißt Linked Server) "Verbindungsserver" einzurichten.
Ist je nach DMBS unterschiedlich aufwändig und Fehleranfällig.

Alex.G 18. Okt 2011 11:22

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1131011)
Zitat:

Zitat von Alex.G (Beitrag 1131008)
Danke für die Antworten!
Was aber, wenn die Datenbanken auf verschiedenen Servern laufen?

Dann müsstest du versuchen einen (bei MS SQL Server heißt Linked Server) "Verbindungsserver" einzurichten.
Ist je nach DMBS unterschiedlich aufwändig und Fehleranfällig.

Meinst Du einen "Verbindungsserver" mit Delphi einrichten?
Wie müsste ich da vorgehen?

Bernhard Geyer 18. Okt 2011 11:24

AW: INSERT INTO SELECT ohne Spaltenliste
 
Guckst du in der MSDN

Alex.G 18. Okt 2011 12:01

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1131016)
Guckst du in der MSDN

Vielen Dank! Werde mich mal reinarbeiten :wink:

joachimd 18. Okt 2011 13:18

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Bummi (Beitrag 1131000)
Code:
Select *
Into NewTable
From OldTable

das erstellt aber eine neue Tabelle! Ein INSERT INTO...SELECT FROM fügt in eine vorhandene ein. Ja nachdem, welcher Befehl verwendet wird und ob die Tabelle schon existiert wird beim einen oder beim anderen ein Fehler geworfen.

Bummi 18. Okt 2011 13:30

AW: INSERT INTO SELECT ohne Spaltenliste
 
@joachimd
Du hast recht, ich hatte nicht gesehen dass er die Tabellen schon angelegt hatte ....

Alex.G 21. Okt 2011 07:34

AW: INSERT INTO SELECT ohne Spaltenliste
 
Als erstes mache ich ein SELECT * ... über eine ADOConnection zum ersten Server. Danach über eine zweite Connection ein INSERT INTO ...
Leider funktioniert das ganze nicht richtig. Mit diesem Quelltext...
Delphi-Quellcode:
  for i := 0 to qryMaster.Recordset.RecordCount-1 do
  begin
    columnList := '';
    valList   := '';
    qryMasterExec.SQL.Text := 'SELECT * FROM '
      + qryMaster.Recordset.Fields.Item['TABLE_NAME'].Value;
    qryMasterExec.Open;
    qryMasterExec.Requery;
    qryMasterExec.Recordset.MoveFirst;

    for n := 0 to qryMasterExec.Recordcount-1 do
    begin
      for t := 0 to qryMasterExec.RecordCount-1 do
      begin
        columns[t] := qryMaster.Recordset.Fields.Item['COLUMN_NAME'].Value;
        values[t] := qryMasterExec.Recordset.Fields.Item[columns[t]].Value;
      end;
      qryMasterExec.Recordset.MoveNext;
    end;
    for e := 0 to High(values)-1 do
    begin
      columnlist := columnlist + columns[e] + ' ';
      valList := valList + values[e] + ' ';
      mSQL.Lines.Add('INSERT INTO '
        + qryMaster.Recordset.Fields.Item['TABLE_NAME'].Value
        + ' ('+columnList+') VALUES'
        + ' ('+valList+')'
        );
    end;
    qryMaster.Recordset.MoveNext;
  end;
...bekomme ich leider nur Insert's wie:
Code:
INSERT INTO Rechnung (ID ) VALUES (4 )
INSERT INTO Rechnung (ID ID ) VALUES (4 4 )
INSERT INTO Rechnung (ID ID ID ) VALUES (4 4 4 )
INSERT INTO Rechnung (KID ) VALUES (2 )
INSERT INTO Rechnung (KID KID ) VALUES (2 2 )
INSERT INTO Rechnung (KID KID KID ) VALUES (2 2 2 )
INSERT INTO Rechnung (PID ) VALUES (1 )
INSERT INTO Rechnung (PID PID ) VALUES (1 1 )
INSERT INTO Rechnung (PID PID PID ) VALUES (1 1 1 )
INSERT INTO Kunde (ID ) VALUES (3 )
INSERT INTO Kunde (ID ID ) VALUES (3 3 )
INSERT INTO Kunde (ID ID ID ) VALUES (3 3 3 )
INSERT INTO Kunde (Name ) VALUES (Plaum               )
INSERT INTO Kunde (Name Name ) VALUES (Plaum               Plaum               )
INSERT INTO Kunde (Name Name Name ) VALUES (Plaum               Plaum               Plaum               )
INSERT INTO Kunde (Vorname ) VALUES (Jürgen              )
INSERT INTO Kunde (Vorname Vorname ) VALUES (Jürgen              Jürgen              )
INSERT INTO Kunde (Vorname Vorname Vorname ) VALUES (Jürgen              Jürgen              Jürgen              )
INSERT INTO Kunde (Ort ) VALUES (Siegen              )
INSERT INTO Kunde (Ort Ort ) VALUES (Siegen              Siegen              )
INSERT INTO Kunde (Ort Ort Ort ) VALUES (Siegen              Siegen              Siegen              )
INSERT INTO Produkt (ID ) VALUES (2 )
INSERT INTO Produkt (ID ID ) VALUES (2 2 )
INSERT INTO Produkt (ID ID Ort ) VALUES (2 2 Siegen              )
INSERT INTO Produkt (Name ) VALUES (Lenovo R500          )
INSERT INTO Produkt (Name Name ) VALUES (Lenovo R500          Lenovo R500          )
INSERT INTO Produkt (Name Name Ort ) VALUES (Lenovo R500          Lenovo R500          Siegen              )
INSERT INTO Produkt (Kommentar ) VALUES (Lenovo Thinkpad Laptop                            )
INSERT INTO Produkt (Kommentar Kommentar ) VALUES (Lenovo Thinkpad Laptop                            Lenovo Thinkpad Laptop                            )
INSERT INTO Produkt (Kommentar Kommentar Ort ) VALUES (Lenovo Thinkpad Laptop                            Lenovo Thinkpad Laptop                            Siegen              )
(Alle Daten sind ausgedacht!)
Was mache ich falsch?

Sir Rufo 21. Okt 2011 07:55

AW: INSERT INTO SELECT ohne Spaltenliste
 
Nimm den Debugger und steppe mal durch die Anwendung.

Richte dein Augenmerk besonders auf die Laufvariablen aus den For-Schleifen ;)

DeddyH 21. Okt 2011 08:12

AW: INSERT INTO SELECT ohne Spaltenliste
 
Nur so ein Gedanke: könnte man nicht das SQL über GetFieldnames zusammensetzen? Aus der hohlen Hand:
Delphi-Quellcode:
InitialSQL := 'INSERT INTO %s(%s) VALUES(%s)';
ADOConnection.GetFieldNames(<Tabellenname>, <Feldliste>);
FieldnameStr := <Feldliste>.CommaText;
for i := 0 to <Feldliste>.Count - 1 do
  <Feldliste>[i] := ':' + <Feldliste>[i];
ParamnameStr := <Feldliste>.CommaText;
InsertQuery.SQL.Text := Format(InitialSQL, [<Tabellenname>, FieldnameStr, ParamnameStr]);
Anschließend könnte man dann in einer Schleife den Parametern die aktuellen Werte zuweisen.

Alex.G 21. Okt 2011 08:23

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von DeddyH (Beitrag 1131621)
Nur so ein Gedanke: könnte man nicht das SQL über GetFieldnames zusammensetzen? Aus der hohlen Hand:
Delphi-Quellcode:
InitialSQL := 'INSERT INTO %s(%s) VALUES(%s)';
ADOConnection.GetFieldNames(<Tabellenname>, <Feldliste>);
FieldnameStr := <Feldliste>.CommaText;
for i := 0 to <Feldliste>.Count - 1 do
  <Feldliste>[i] := ':' + <Feldliste>[i];
ParamnameStr := <Feldliste>.CommaText;
InsertQuery.SQL.Text := Format(InitialSQL, [<Tabellenname>, FieldnameStr, ParamnameStr]);
Anschließend könnte man dann in einer Schleife den Parametern die aktuellen Werte zuweisen.

Ergibt leider:
Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt pDatenbankabgleich.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 0046A3CE in Modul 'pDatenbankabgleich.exe'. Schreiben von Adresse 0048AAA8'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
EDIT: Exception kommt bei conMaster.GetFieldNames(tableName, fieldList);

Bummi 21. Okt 2011 08:25

AW: INSERT INTO SELECT ohne Spaltenliste
 
Warum richtest Du keinen Verbindungsserver ein, geht auch über Script und fährst

Insert into Ziel
Select * from verbindungsserver.ddo.quelle

DeddyH 21. Okt 2011 08:25

AW: INSERT INTO SELECT ohne Spaltenliste
 
Die Feldliste hast Du aber erzeugt, und die Connection ist aktiv?

Alex.G 21. Okt 2011 08:30

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Bummi (Beitrag 1131626)
Warum richtest Du keinen Verbindungsserver ein, geht auch über Script und fährst

Insert into Ziel
Select * from verbindungsserver.ddo.quelle

Soll es ohne einen Verbindungsserver lösen :wink:

Zitat:

Zitat von DeddyH (Beitrag 1131627)
Die Feldliste hast Du aber erzeugt, und die Connection ist aktiv?

Es ist früh am Morgen... :-D habe es jetzt erzeugt, trotzdem eine Exception bei columnList := fieldList.CommaText;
Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt pDatenbankabgleich.exe ist eine Exception der Klasse EAbstractError aufgetreten. Meldung: 'Abstrakter Fehler'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------

DeddyH 21. Okt 2011 08:33

AW: INSERT INTO SELECT ohne Spaltenliste
 
Von welchem Typ ist denn Fieldlist? Falls TStrings, dann mach mal TStringlist daraus.

himitsu 21. Okt 2011 08:49

AW: INSERT INTO SELECT ohne Spaltenliste
 
Und wie sieht es mit sowas aus?
Delphi-Quellcode:
Source.SQL.Text := 'SELECT * FROM ' + TableName;
Source.ExecSQL;
InsertStr := '';
ValueStr := '';
for i := 0 to Source.ParamCount - 1 do begin
  InsertStr := InsertStr + IfThen(InsertStr <> '', ', ', '')  + Source.Fields[i].FieldName;
  ValueStr := ValueStr + IfThen(ValueStr <> '', ', :', ':') + Source.Fields[i].FieldName;
end;
Dest.SQL.Text := Format('INSERT INTO %s (%s) VALUES(%s)', [TableName, InsertStr, ValueStr]);
while not Source.Eof do begin
  Dest.Insert;
  for i := 0 to Source.ParamCount - 1 do
    Dest.Params.ParamByName(Source.Fields[i].FieldName).Value
      := Source.Fields.FieldByName(Source.Fields[i].FieldName).Value;
  Dest.Post;
end;
Und ich glub das Quoten der Values wurden oftmals vergessen.
(entfällt bei dem Preparedzeugs aber)

DeddyH 21. Okt 2011 08:52

AW: INSERT INTO SELECT ohne Spaltenliste
 
First nach ExecSQL? Geht sowas in ADO?

Alex.G 21. Okt 2011 09:09

AW: INSERT INTO SELECT ohne Spaltenliste
 
Delphi-Quellcode:
for i := 0 to qryMasterExec.Parameters.Count - 1 do begin
Diese Zeile verstehe ich nicht. Müsste da nicht ein Recordcount hin? Wenn ich ein Breakpoint setze, sehe ich bei Parameters.Count den Wert 0.

himitsu 21. Okt 2011 09:25

AW: INSERT INTO SELECT ohne Spaltenliste
 
@DeddyH: Frag mich doch nicht. :lol: (ich fang auch grad erst mit diesem ganzen Zeugs an)

(hab mir erst letzte Woche mein erstes kleines brennendes Vögelchen zugelegt)


RecordCount = Anzahl der Zeilen/Datensätze
Parameters.Count = Anzahl der Splten/Parameter

DeddyH 21. Okt 2011 09:32

AW: INSERT INTO SELECT ohne Spaltenliste
 
Du hast doch ein Abfrageergebnis, was soll es da für Parameter geben? Nimm statt Parameters einmal Fields.

Bummi 21. Okt 2011 09:50

AW: INSERT INTO SELECT ohne Spaltenliste
 
Du willst keinen Verbindugsserver aufbauen und hast die Zieltabellen schon?
Die Insert-SQL's aufzubauen mit Berücksichtigung aller Besonderheiten bzgl. Feldtypen, Codierung etc. wird Dich einige Zeit kosten, warum nicht die billige Variante


ExDataset = Select * from Quelle
Ads= Select * from Ziel
Delphi-Quellcode:


While (not ExDataset.EOF) do
      begin

      Ads.Append;
      for i:=0 to Ads.Fieldcount-1 do
          begin
          Ads.Fields[i].Assign(ExDataset.FieldByName(Ads.Fields[i].FieldName));
          end;
      ads.Post;
      ExDataset.Next;
      end;

Alex.G 21. Okt 2011 10:35

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Bummi (Beitrag 1131657)
... warum nicht die billige Variante

Weil es meine Aufgabe ist :wink:

himitsu 21. Okt 2011 10:38

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Alex.G (Beitrag 1131669)
Weil es meine Aufgabe ist :wink:

Aufgabe?

Hatte das schonmal wer hier erwähnt`?

Alex.G 21. Okt 2011 10:42

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von himitsu (Beitrag 1131671)
Zitat:

Zitat von Alex.G (Beitrag 1131669)
Weil es meine Aufgabe ist :wink:

Aufgabe?

Hatte das schonmal wer hier erwähnt`?

Bisher noch nicht.
Ich habe es nun mit:
Delphi-Quellcode:
InsertStr := InsertStr + IfThen(InsertStr <> '', ', ', '') + qryMasterExec.Parameters[i].Name;
und
Delphi-Quellcode:
InsertStr := InsertStr + IfThen(InsertStr <> '', ', ', '') + qryMasterExec.Fields[i].Name;
probiert. Wenn ich ein Breakpoint setze, sehe ich, dass InsertStr leider nach Ablauf der Schleife immer leer bleibt.

DeddyH 21. Okt 2011 10:45

AW: INSERT INTO SELECT ohne Spaltenliste
 
Was ist denn mit der Vorgehensweise nach #14 bis #19?

himitsu 21. Okt 2011 10:48

AW: INSERT INTO SELECT ohne Spaltenliste
 
Und
Delphi-Quellcode:
qryMasterExec.Fields[i].FieldName
?

Sir Rufo 21. Okt 2011 11:14

AW: INSERT INTO SELECT ohne Spaltenliste
 
Ich bin hierfür (mal eben herunter getippt)
Delphi-Quellcode:
procedure CopyADOData( SrcCon, TarCon : TADOConnection; const TableName : string );
var
  SrcData :  TADOTable;
  TarData :  TADOQuery;
  SqlStrFld : string;
  SqlStrPar : string;
  fld :      TField;
begin
  SrcData := TADOTable.Create( nil );
  TarData := TADOQuery.Create( nil );
  try

    SrcData.Connection := SrcCon;
    SrcData.TableName := TableName;
    SrcData.FieldDefList.Update;

    TarData.Connection := TarCon;

    SqlStrFld := '';
    SqlStrPar := '';

    for fld in SrcData.Fields do
      begin
        if not( SqlStrFld = '' )
        then
          SqlStrFld := SqlStrFld + ', ';
        SqlStrFld := SqlStrFld + fld.FieldName;

        if not( SqlStrPar = '' )
        then
          SqlStrPar := SqlStrPar + ', ';
        SqlStrPar := SqlStrPar + ':' + fld.FieldName;
      end;

    TarData.SQL.Text := 'INSERT INTO ' + TableName + ' ( ' + SqlStrFld + ' ) VALUES ( ' + SqlStrPar + ' )';

    TarData.Prepared := True;
    try

      SrcData.Open;
      try

        while not SrcData.Eof do
        begin
          for fld in SrcData.FieldList do
          begin
            TarData.Parameters.ParamByName(fld.FieldName).Value := fld.Value;
          end;
          TarData.ExecSQL;
          SrcData.Next;
        end;

      finally
        SrcData.Close;
      end;

    finally
      TarData.Prepared := False;
    end;

  finally
    TarData.Free;
    SrcData.Free;
  end;
end;

Alex.G 21. Okt 2011 11:15

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von himitsu (Beitrag 1131678)
Und
Delphi-Quellcode:
qryMasterExec.Fields[i].FieldName
?

Das funktioniert!
Eine (hoffentlich) letzte Sache noch:
Delphi-Quellcode:
  qrySlaveExec.SQL.Text := Format('INSERT INTO %s (%s) VALUES(%s)', [TableName, InsertStr, ValueStr]);
  while not qryMasterExec.Eof do begin
    qrySlaveExec.Insert;
Ist bei geschlossener Datenmenge nicht möglich. Ein qrySlaveExec.Open kann ich aber, soweit ich weiß, nur bei einem SELECT nutzen.

Bummi 21. Okt 2011 11:15

AW: INSERT INTO SELECT ohne Spaltenliste
 
zum fertigbasteln:
Delphi-Quellcode:

Function GetTableValueScript(Ads:TAdodataset;const tableName:String;HasIdentity:Boolean):String;
var

  FieldNames:TStringList;
  Values:TStringList;
  i:Integer;
  FieldNamesStr:String;
  Function Prepare(f:TField):String;
    begin
       if f.IsNull then Result := 'NULL'
       else
       Case
         f.DataType of
          ftSmallint, ftInteger, ftWord,ftAutoInc,ftLargeint,
          ftFloat, ftCurrency, ftBCD ,ftFMTBcd,ftLongWord, ftShortint, ftByte, ftExtended ,ftSingle: Result := Stringreplace(f.AsString, ',','.',[]) ;
          ftString,ftWideString,ftGuid : Result := QuotedStr(f.AsString);
          ftDate, ftDateTime, ftTime : Result := QuotedStr(FormatdateTime('yyyymmdd hh:nn:ss.zzz',f.AsDateTime));
          ftBoolean: Result := IntToStr(Integer(f.AsBoolean));
          // to be continued
       End;
    end;
  Function GetValues:String;
    begin
        Result := StringReplace(Values.Text,#13#10,', ',[rfReplaceAll]);
        Result := Copy(Result,1,Length(Result) - 2);
    end;
begin

  FieldNames:=TStringList.Create;
  Values:=TStringList.Create;
  try
  Ads.CommandText := 'Select top 100 * from ' + tablename;
  Ads.Open;
  for I := 0 to Ads.FieldCount -1 do FieldNames.Add('[' + Ads.Fields[i].FieldName + ']');
  FieldNamesStr := StringReplace(FieldNames.Text,#13#10,', ',[rfReplaceAll]);
  FieldNamesStr := Copy(FieldNamesStr,1,Length(FieldNamesStr) - 2);
  while not Ads.Eof do
    begin
      Values.Clear;
      for I := 0 to Ads.FieldCount -1 do Values.Add(Prepare(Ads.Fields[i]));
      Ads.Next;
      Result := Result + 'Insert Into ' + tablename + '(' + FieldNamesStr + ') VALUES (' + GetValues + ')' + #13#10#13#10;
    end;
  finally
    FieldNames.Free;
    Values.Free;
  end;
  if HasIdentity then
    Result := 'Set Identity_Insert ' +  tableName +  ' ON' + #13#10
               + Result
               + 'Set Identity_Insert ' +  tableName +  ' OFF' + #13#10

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Text := GetTableValueScript(ADS,'[Adressen]',true);
end;

joachimd 21. Okt 2011 11:34

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Alex.G (Beitrag 1131690)
Delphi-Quellcode:
  qrySlaveExec.SQL.Text := Format('INSERT INTO %s (%s) VALUES(%s)', [TableName, InsertStr, ValueStr]);
  while not qryMasterExec.Eof do begin
    qrySlaveExec.Insert;
Ist bei geschlossener Datenmenge nicht möglich.

Delphi-Quellcode:
  qrySlaveExec.ExecSQL;

Alex.G 21. Okt 2011 11:49

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von joachimd (Beitrag 1131702)
Zitat:

Zitat von Alex.G (Beitrag 1131690)
Delphi-Quellcode:
  qrySlaveExec.SQL.Text := Format('INSERT INTO %s (%s) VALUES(%s)', [TableName, InsertStr, ValueStr]);
  while not qryMasterExec.Eof do begin
    qrySlaveExec.Insert;
Ist bei geschlossener Datenmenge nicht möglich.

Delphi-Quellcode:
  qrySlaveExec.ExecSQL;

ExecSQL bevor man die Parameter angegeben hat?
EDIT: Ergibt wieder eine Exception

Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt pDatenbankabgleich.exe ist eine Exception der Klasse EOleException aufgetreten. Meldung: 'Der Wert NULL kann in die 'ID'-Spalte, 'TestDB2.dbo.Produkt'-Tabelle nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei INSERT'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------

Alex.G 21. Okt 2011 13:49

AW: INSERT INTO SELECT ohne Spaltenliste
 
Delphi-Quellcode:
    while not qryMasterExec.Eof do begin
      for i := 0 to qryMasterExec.Fields.Count - 1 do
        valList.Add(qryMasterExec.Fields[i].Value);

      valueStr := valList.CommaText;
      qrySlaveExec.SQL.Text := Format('INSERT INTO %s (%s) VALUES(%s)',
        [TableName, InsertStr, ValueStr]);
      qrySlaveExec.ExecSQL;
      qryMasterExec.Next;
    end;
Gibt mir wieder eine Exception:
Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt pDatenbankabgleich.exe ist eine Exception der Klasse EOleException aufgetreten. Meldung: 'Der Name "Acer Monitor       " ist in diesem Kontext nicht zulässig. Gültige Ausdrücke sind Konstanten, konstante Ausdrücke und (in bestimmten Kontexten) Variablen. Spaltennamen sind nicht zulässig'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
Wieso sollte Acer Monitor nicht zulässig sein? Es steht an der richtigen Stelle und ist ein 20-Zeichen langer String. (In der Datenbank: nChar(20))

Jumpy 21. Okt 2011 14:04

AW: INSERT INTO SELECT ohne Spaltenliste
 
Es ist ein String, wird aber innerhalb des Strings nicht in Anführungsstrichen stehen. D.h. du musst String-Felder in deinem Value-String in Gänsefüßchen setzen, also wäre der Sting gleich:

'1,1,Acer Monitor,10.10.2011' müsste er eigentlich sein:
'1,1,'Acer Monitor','10.10.2011'' und noch eigentlicher, müssten die Anführungsstrich maskiert werden, also:
'1,1,''Acer Monitor'',''10.10.2011''' und das Datumfeld müsste ggf. nochmal anders behandelt werden. In Oracle säh das z.B. evtl. so aus:
'1,1,''Acer Monitor'',To_Date(''10.10.2011'',''dd.mm.yyyy'')'

Besser wäre es glaub ich generell mit Parametern zu arbeiten, dann haste das Problem nicht, denn in der Form wie du das machst, müssteste je nach Feldtyp in der Mastertabelle die Elemente des Value-Strings anpassen.

Edit: Siehe z.B. mal wie Bummi das in #33 gemacht hat!

Der Passus hier:
Delphi-Quellcode:
if f.IsNull then Result := 'NULL'
       else
       Case
         f.DataType of
          ftSmallint, ftInteger, ftWord,ftAutoInc,ftLargeint,
          ftFloat, ftCurrency, ftBCD ,ftFMTBcd,ftLongWord, ftShortint, ftByte, ftExtended ,ftSingle: Result := Stringreplace(f.AsString, ',','.',[]) ;
          ftString,ftWideString,ftGuid : Result := QuotedStr(f.AsString);
          ftDate, ftDateTime, ftTime : Result := QuotedStr(FormatdateTime('yyyymmdd hh:nn:ss.zzz',f.AsDateTime));
          ftBoolean: Result := IntToStr(Integer(f.AsBoolean));
          // to be continued
End

Alex.G 21. Okt 2011 14:11

AW: INSERT INTO SELECT ohne Spaltenliste
 
Zitat:

Zitat von Jumpy (Beitrag 1131758)
Es ist ein String, wird aber innerhalb des Strings nicht in Anführungsstrichen stehen. D.h. du musst String-Felder in deinem Value-String in Gänsefüßchen setzen, also wäre der Sting gleich:

'1,1,Acer Monitor,10.10.2011' müsste er eigentlich sein:
'1,1,'Acer Monitor','10.10.2011'' und noch eigentlicher, müssten die Anführungsstrich maskiert werden, also:
'1,1,''Acer Monitor'',''10.10.2011''' und das Datumfeld müsste ggf. nochmal anders behandelt werden. In Oracle säh das z.B. evtl. so aus:
'1,1,''Acer Monitor'',To_Date(''10.10.2011'',''dd.mm.yyyy'')'

Besser wäre es glaub ich generell mit Parametern zu arbeiten, dann haste das Problem nicht, denn in der Form wie du das machst, müssteste je nach Feldtyp in der Mastertabelle die Elemente des Value-Strings anpassen.

Edit: Siehe z.B. mal wie Bummi das in #33 gemacht hat!

Der Passus hier:
Delphi-Quellcode:
if f.IsNull then Result := 'NULL'
       else
       Case
         f.DataType of
          ftSmallint, ftInteger, ftWord,ftAutoInc,ftLargeint,
          ftFloat, ftCurrency, ftBCD ,ftFMTBcd,ftLongWord, ftShortint, ftByte, ftExtended ,ftSingle: Result := Stringreplace(f.AsString, ',','.',[]) ;
          ftString,ftWideString,ftGuid : Result := QuotedStr(f.AsString);
          ftDate, ftDateTime, ftTime : Result := QuotedStr(FormatdateTime('yyyymmdd hh:nn:ss.zzz',f.AsDateTime));
          ftBoolean: Result := IntToStr(Integer(f.AsBoolean));
          // to be continued
End

Es soll ja noch gar kein Datum rein. Werde es morgen oder so mal fertig machen. Allen vielen Dank für die Hilfe! :thumb:

himitsu 21. Okt 2011 14:20

AW: INSERT INTO SELECT ohne Spaltenliste
 
Und dafür war die parametrisierte Variante vorgesehn ... dort muß man sich um nichts kümmern,
aber irgendwo sollte es auch eine QuoteString-Funktion geben, welche die ' für dich setzt.

DeddyH 21. Okt 2011 16:02

AW: INSERT INTO SELECT ohne Spaltenliste
 
Wenn Du Parameter benutzt brauchst Du keine Quoted Strings.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:30 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz