Entwickler-Ecke

Datenbanken - INSERT-Anweisung fehlerhaft


bis11 - Sa 05.07.03 18:29
Titel: INSERT-Anweisung fehlerhaft
Hallo Leutz,

ich bin es mal wieder. Ich habe folgendes Problem :


Quelltext
1:
2:
3:
4:
INSERT INTO ZS42
(NR,Auftragsnr,Auftragsart,Auftragsdatum,Erledigtbis,vorname,nachname,strasse,PLZ,Ort,Telefonnr,AUFTRAGSTEXTZS42,checknewZS42,offen,inwork,closed)
VALUES
(0,'TESTNR','Umzug','05.07.2003','11.07.2003','dfgdfg','sgdsdg','sdgsdfg',12345,'dsgdsgsgsg','sdgsdfgsg','DS21|sdfgsdgsdfgsfg,DS21|dgsdgsgs,ZS42|sdfgsfdgsdfgsgf',1, 1, 0, 0);


Dieses ist meine SQL-Anweisung, die mir immer einen Fehler ausspuckt, womit ich nicht zurande komme :

Zitat:

Conversion error from string "BLOB"
Statement: INSERT INTO ZS42
(NR,Auftragsnr,Auftragsart,Auftragsdatum,Erledigtbis,vorname,nachname,strasse,PLZ,Ort,Telefonnr,AUFTRAGSTEXTZS42,checknewZS42,offen,inwork,closed)
VALUES
(0,'TESTNR','Umzug','05.07.2003','11.07.2003','dfgdfg','sgdsdg','sdgsdfg',12345,'dsgdsgsgsg','sdgsdfgsg','DS21|sdfgsdgsdfgsfg,DS21|dgsdgsgs,ZS42|sdfgsfdgsdfgsgf',1, 1, 0, 0)


Hier noch mein Delphi-Code wie ich die Tabelle erstelle :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
procedure CreateBasket;                                                         // Die Postkörbe der Abteilungen erstellen
var
  abteilung : TStringList;
  i : integer;
begin
  abteilung := TStringList.Create;
  with IBDataModule.IBQueryCategory do begin
    Sql.Clear;
    Sql.Add('SELECT DISTINCT abteilung FROM auftrmgtconfig WHERE childnr>1;');
    Open;
    Active := True;
    while not EOF do begin
      abteilung.Add(Fields[0].AsString);
      next;
    end;
    Active := false;
  end;
  for i := 0 to abteilung.Count-1 do begin
    if SearchTable(abteilung[i],'bisbasket.gdb') = -1 then begin
      with IBDataModule.IBDBPostkorbQuery do begin
        Sql.Clear;
        Sql.Add('CREATE DOMAIN ' + abteilung[i] + 'counter AS SMALLINT;');
        ExecSql;
        Sql.Clear;
        Sql.Add('CREATE GENERATOR ' + abteilung[i] + 'AutoInc;');
        ExecSql;
        Sql.Clear;
        Sql.Add('SET GENERATOR ' + abteilung[i] + 'AutoInc TO 1;');
        ExecSql;
        Sql.Clear;
        Sql.Add('CREATE TABLE ' + abteilung[i] + ' (');
        Sql.Add('nr            ' + abteilung[i] + 'counter NOT NULL PRIMARY KEY,');
        Sql.Add('auftragsnr      VARCHAR(10),');
        Sql.Add('auftragsart     VARCHAR(20),');
        Sql.Add('auftragsdatum   VARCHAR(10),');
        Sql.Add('erledigtbis     VARCHAR(10),');
        Sql.Add('Vorname         VARCHAR(20),');
        Sql.Add('Nachname        VARCHAR(20),');
        Sql.Add('Strasse         VARCHAR(40),');
        Sql.Add('PLZ             INTEGER,');
        Sql.Add('Ort             VARCHAR(40),');
        Sql.Add('Telefonnr       VARCHAR(20),');
        Sql.Add('auftragstext' + abteilung[i] + ' BLOB(240,1),');
        Sql.Add('checknew' + abteilung[i] + ' INTEGER,');
        Sql.Add('offen           INTEGER,');
        Sql.Add('inwork          INTEGER,');
        Sql.Add('closed          INTEGER);');
        ExecSql;
        Sql.Clear;
        Sql.Add('  CREATE TRIGGER AutoInc'+ abteilung[i] + ' FOR ' + abteilung[i]);
        Sql.Add('  BEFORE INSERT AS');
        Sql.Add('  BEGIN');
        Sql.Add('    new.nr = gen_id(' + abteilung[i] + 'AutoInc, 1);');
        Sql.Add('  END');
        ExecSql;
        Sql.Clear;
        Sql.Add('CREATE VIEW status' + abteilung[i] + ' AS');
        Sql.Add('SELECT nr,checknew' + abteilung[i] + ',offen, inwork, closed ');
        Sql.Add(' FROM ' + abteilung[i] + ';');
        ExecSql;
      end;
    end;
  end;
end;


Ich arbeite mit der Interbase Datenbank. Vielleicht kann mir ja jemand weiterhelfen, da ich dieses Problem bis jetzt noch nicht hatte.


UGrohne - So 06.07.03 12:08

Du kannst ein BLOB-Feld nicht als String übergeben, Du musst das schon mit Streams machen, so wie in meinem Tutorial beschrieben.

Oder Du änderst Deine Tabelle und zwar den Auftragstext als VARCHAR deklarieren. VARCHAR kann mit bis zu 32000 Zeichen aufnehmen, würde vll. für den Auftragstext ausreichen.


bis11 - So 06.07.03 12:28

Danke erstmal für Deine schnelle Antwort. Die Daten für das Feld Auftragstext, kommen aus einer Stringlist. Nur wenn ich Dein FAQ benutze, bekomme ich schon gleich eine Fehlermeldung in der Zeile :


Delphi-Quelltext
1:
    blob:=IBDataModule.CreateOrderQuery.CreateBlobStream(IBDataModule.CreateOrderQuery.FieldByName('blobdata'),bmWrite);                    


Mit folgendem Text : undefinierter Bezeichner bmWrite

Ich habe natürlich vorher die Stringlist in eine TXT-Datei abgespeichert. Gibt es dort auch eine Möglichkeit ohne das zwischenspeichern ?
Was habe ich verkehrt gemacht ? Ich benutze das erste Mal Streams.


UGrohne - So 06.07.03 17:04

OK, Versuchs mal mit bmReadWrite, vll. geht das.

Zu Deiner StringList: Die hat die Methode SaveToStream, die Du mit blob als Parameter aufrufen kannst, dann gehts ohne zwischenspeichern :wink:


bis11 - So 06.07.03 17:17

Es funktioniert keiner von den beiden Befehlen weder bmWrite noch bmReadWrite. Vielleicht sollte ich noch sagen, dass ich die Komponenten von Zeos benutze um auf die IB-Datenbank zuzugreifen.


UGrohne - So 06.07.03 17:18

Ahsooooo, dann musste da in der Hilfe schauen, was die da als Konstante für definiert haben, kenn mich mit ZEOS nit aus.


hansa - So 06.07.03 20:38

UGrohne hat folgendes geschrieben:
Ahsooooo, dann musste da in der Hilfe schauen, was die da als Konstante für definiert haben, kenn mich mit ZEOS nit aus.


Wieder wunderhübsche Stilblüte, hehe. Ich liebe die Hinweise auf irgendeine Hilfe, weil die bei mir im Moment sowieso nicht geht. :mrgreen:

Aber ich habe eine Frage, die könnte trotzdem hierhin passen. Ich habe ein Insert, welches funktioniert. Nur was ist, wenn ein Datensatz in der DB schon drinne ist, so daß eigentlich ein Update nötig wäre ? Muß ich da mit Select und IsEmpty vorher das prüfen oder wie?


UGrohne - So 06.07.03 20:42

Wenn Du das BLOB-Feld updaten willst, musst Du nur den entsprechenden Datensatz aktiv haben in der Datenmenge und dann wie beim Speichern das BLOB-Feld einwerfen :wink:. Den Rest (also alle anderen Felder) machste wie gewohnt über Update

//EDIT: Gerade in den ZEOS nachgeguckt:
Zitat:
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
Provides the interface for a method that creates a blob stream for a Binary large object (BLOB) field in the dataset.
bmRead - The stream is used to read from a BLOB field.
bmWrite - The stream is used to write to a BLOB field.
bwReadWrite - The stream is used to modify a BLOB field's value.

Gibts ne HTML-Datei in den Libs


hansa - So 06.07.03 20:45

Hi UGrohne,

die letzte Frage kam von mir. Das hat zumindest vorerst nichts mit blob zu tun, sondern mit dem Insert/update Kram.


UGrohne - So 06.07.03 20:51

uups, verwechselt, macht aber nix, das Zitat passt trotzdem.

Also Du hast also folgendes: Du willst einen neuen Datensatz eingeben, weißt aber net, ob der schon existiert?

Solltest Du natürlich vorher überprüfen, denn INSERT bringt einen Fehler, wenn z.B. der Primary-Key, den Du eingeben willst, schon vorhanden ist,e r will ja neu anlegen. Also erstmal mit SELECT überprüfen und dann den INSERT oder ein UPDATE machen. Handarbeit ist angesagt :wink:

Aber im Normalfall versucht man eh zu vermeiden, dass man sowas überprüfen muss, sondern Client-Seitig legt man fest, ob man einen Datensatz bearbeitet oder einen neuen erstellt.


hansa - So 06.07.03 21:02

UGrohne hat folgendes geschrieben:
Aber im Normalfall versucht man eh zu vermeiden, dass man sowas überprüfen muss, sondern Client-Seitig legt man fest, ob man einen Datensatz bearbeitet oder einen neuen erstellt.


Eben, genau so. Nur wie vermeide ich das ? Ich brauche ein Kriterium, ob Update oder Insert gemacht wird. Mir fällt nur SELECT ein. Aber eine Abfrage auf Fehlermeldungen wäre wohl besser, also bei fehlerhaftem Insert ein Update. Immer noch Fehler : Abbruch.


bis11 - So 06.07.03 21:18

@UGrohne

ich habe diese Befehle aus der Hilfe benutzt, er gibt mir aber immer noch undefinierter Bezeichner aus. Liegt es vielleicht daran, das ich ein Datenmodul benutze ? Welche Komponenten benutzt Du um auf eine IB-Datenbank zu kommen.


UGrohne - So 06.07.03 21:21

Ich verwende immer noch IBX. Hast Du schonmal bwReadWrite verwendet?


bis11 - So 06.07.03 21:24

Ich habe alle drei Sachen genommen. nichts funktioniert.