Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi String-Literale (https://www.delphipraxis.net/92555-string-literale.html)

handson 22. Mai 2007 10:44


String-Literale
 
Hallo!

Ich hab folgendes Problem. Beim kompilieren bekomme ich diese Fehlermeldung:

Zitat:

[Fehler] DataKundenObj.pas(64): String-Literale können maximal 255 Elemente besitzen
Und dieser Passiert an dieser Stelle:

Delphi-Quellcode:
Procedure PutKundeObj(AOwner : TComponent; DataModule : TMySQLModule; MandantenId : String;KundenObjData : TKundenObj);
Var
  Stmt : String;
  i : Integer;

Begin
  Try
    Screen.Cursor := crSQLWait;
    DataModule.KundenObjQuery.Close;
    DataModule.KundenObjQuery.SQL.Clear;

    Stmt                       := UTF8Encode('INSERT INTO KundenObj (mandantenid, objnr, kundnr, typnr, typ,'+
                                              ' umsatz1, umsatz2, umsatz3, umsatz4, umsatz5, umsatz6, umsatz7, umsatz8, umsatz9, umsatz10, umsatz11, umsatz12, umsatz13, umsatz4,'+
                                              ' ertrag1, ertrag2, ertrag3, ertrag4, ertrag5, ertrag6, ertrag7, ertrag8, ertrag9, ertrag10, ertrag11, ertrag12, ertrag13, ertrag4,'+
                                              ' anzahl1, anzahl2, anzahl3, anzahl4, anzahl5, anzahl6, anzahl7, anzahl8, anzahl9, anzahl10, anzahl11, anzahl12, anzahl13, anzahl4) VALUES '+
                                              '('''+KundenObjData.MandantenId+''','+   // An dieser Stelle, bei dieser Variable tritt der Fehler auf
                                              ''''+KundenObjData.ObjNr+''','+
                                              ''''+KundenObjData.KundNr+''','+
                                              ''''+KundenObjData.TypNr+''','+
                                              IntToStr(KundenObjData.Typ)+',');
:
:
:
Und der Witz an der Geschichte ist, in einer anderen Unit funktioniert die Konstellation.
Hab ich da was übersehen? Oder wo liegt das Problem? :gruebel:

Stephan

handson 22. Mai 2007 10:47

Re: String-Literale
 
Eine Sache habe ich vergessen. Die Variable KundenObjData.MandantenID ist von Typ String[3].

SubData 22. Mai 2007 10:49

Re: String-Literale
 
Dein String is einfach zu lang ... schreib einfach mal mitten in den String '+' rein, danach dürfte das funktionieren :)

Edit: Ja, mit den Hochkomma...

handson 22. Mai 2007 12:43

Re: String-Literale
 
Das klappt leider nicht.

Das komische ist, wenn ich die Variable MandantenID (Typ String) aus dem Procedure-Kopf nehme, dann geht es.

Schaedel 22. Mai 2007 12:52

Re: String-Literale
 
INSERT INTO KundenObj (mandantenid, objnr, kundnr, typnr, typ,'+
' umsatz1, umsatz2, umsatz3, umsatz4, umsatz5, umsatz6, umsatz7, umsatz8, umsatz9, umsatz10, umsatz11, umsatz12, umsatz13, umsatz4,'+
' ertrag1, ertrag2, ertrag3, ertrag4, ertrag5, ertrag6, ertrag7, ertrag8, ertrag9, ertrag10, ertrag11, ertrag12, ertrag13, ertrag4,'+
' anzahl1, anzahl2, anzahl3, anzahl4, anzahl5, anzahl6, anzahl7, anzahl8, anzahl9, anzahl10, anzahl11, anzahl12, anzahl13, anzahl4) VALUES

Dieser String hängt zusammen und er hat mehr als 255 Zeichen.
Splitte den string auf und speichere ihn in eine Variable zwischen.

WS1976 22. Mai 2007 12:52

Re: String-Literale
 
Hallo,

Ist doch logisch. Im Kopf deklarierst du mandantenid als string (unbegrenzt).
Wie du geschrieben hast ist der Typ den du übergibst string[3].
Irgendwie passt das nicht zusammen.

OK vergiss meinen Beitrag! Mein Vorgänger hat Recht.

Grüsse

Hawkeye219 22. Mai 2007 13:29

Re: String-Literale
 
Hallo Stephan,

hast du in dieser Unit den Typ String umdefiniert? Ich vermute, daß du mit einem ShortString arbeitest, anders ist die Fehlermeldung nicht zu erklären. Suche in der Unit mal nach den Compilerdirektiven

Delphi-Quellcode:
{$H-} bzw. {$LONGSTRINGS OFF}
Überprüfe auch die Compilereinstellung in den Projektoptionen ("Huge-String").

Gruß Hawkeye

uligerhardt 22. Mai 2007 13:33

Re: String-Literale
 
Du könntest es auch so machen:
Delphi-Quellcode:
procedure PutKundeObj(AOwner: TComponent; KundenObjData: TKundenObj);
const
  cStmt = 'INSERT INTO KundenObj (mandantenid, objnr, kundnr, typnr, typ,' +
    ' umsatz1, umsatz2, umsatz3, umsatz4, umsatz5, umsatz6, umsatz7, umsatz8, umsatz9, umsatz10, umsatz11, umsatz12, umsatz13, umsatz4,' +
    ' ertrag1, ertrag2, ertrag3, ertrag4, ertrag5, ertrag6, ertrag7, ertrag8, ertrag9, ertrag10, ertrag11, ertrag12, ertrag13, ertrag4,' +
    ' anzahl1, anzahl2, anzahl3, anzahl4, anzahl5, anzahl6, anzahl7, anzahl8, anzahl9, anzahl10, anzahl11, anzahl12, anzahl13, anzahl4) VALUES ' +
    '(''%s'',''%s'',''%s'',''%s'',%i,';
var
  Stmt: string;
begin
  Stmt := UTF8Encode(Format(cStmt,
    [KundenObjData.MandantenId, KundenObjData.ObjNr, KundenObjData.KundNr,
     KundenObjData.TypNr, KundenObjData.Typ]));
end;
Das ist IMHO auch lesbarer. Bei 4 Hochkommas hintereinander wird mir schwummerig. :-)

Oder erzeug den ersten Teil des Strings mit 14x "umsatzN", "ertragN", "anzahlN" in einer Schleife.

Uli.

handson 22. Mai 2007 13:36

Re: String-Literale
 
Standardmäßig wird unter Delphi ein String als Ansistring gespeichert, d.h. er kann ca. 2^31 Zeichen (bis 4 GB) speichern.

Das mit dem String-Splitting passt nicht mit dem Phänomän zusammen. Außerdem kann ich in einer anderen Unit weitaus größere
Strings erstellen ohne Meldung.

Ich habe auch keine Compilerdirektiven verändert bzw. hinzugefügt.

Ich hab so das Gefühl, dass mein Delphi 7 ne Macke hat...

Stephan

Hawkeye219 22. Mai 2007 13:48

Re: String-Literale
 
Hallo Stephan,

ich habe die Zeichen in der Stringkonstanten nicht gezählt. Falls es jedoch mehr als 255 sind, kann das zu Problemen führen:

Delphi-Quellcode:
procedure Test;
const
  s8   = '12345678';
  s32  = s8 + s8 + s8 + s8;
  s127 = s32 + s32 + s32 + s8 + s8 + s8 + '1234567';
  s128 = s32 + s32 + s32 + s32;
  s255 = s128 + s127;
  s256 = s128 + s128;
var
  s1 : AnsiString;
  s2 : ShortString;
begin
  s1 := s256;
  s2 := s255;
  s2 := s256;
end;
Die Fehlermeldung dürfte dir bekannt vorkommen...

Gruß Hawkeye

Ralf Kaiser 22. Mai 2007 16:01

Re: String-Literale
 
Zitat:

Zitat von handson
Standardmäßig wird unter Delphi ein String als Ansistring gespeichert, d.h. er kann ca. 2^31 Zeichen (bis 4 GB) speichern.

Das mit dem String-Splitting passt nicht mit dem Phänomän zusammen. Außerdem kann ich in einer anderen Unit weitaus größere
Strings erstellen ohne Meldung.

Strings können unter Delphi 4GB speichern, das ist schon richtig. Stringliterale aber eben nicht. Ein Stringliteral ist ein einziger direkt definierter String also z.B. 'Ich bin ein Literal' (Das sagt ja auch schon die Meldung: Da ist nicht von zu langen String die Rede, sondern von einem zu langen String-Literal)

Wenn ein einzelnes Literal länger als 255 Zeichen ist kommt diese Fehlermeldung.

Lösung: das gesamte Literal an einigen Stellen splitten und mit "+" verbinden:

variable := 'Stell dir vor dieses Literal sei länger als 255 Zeichen...'; // geht nicht

variable := 'Stell dir vor dieses' + 'Literal sei länger als 255 Zeichen...'; // geht!!


Ciao,
Ralf

handson 23. Mai 2007 10:42

Re: String-Literale
 
@Alfi001: Hmm, wenn ich mir deine Erklärung anschaue und meinen Source-Code, habe ich ja schon den String in einzelne "Literale" aufgeteilt. Beim groben durchzählen der einzelnen Literale komme ich auf max. ca. 135 Zeichen... Es hätte also funktionieren müssen, oder?

Der ganze Witz an der Geschichte ist, nehme ich statt der Variable KundenObjData.MandantenId, die Variable MandantenID aus dem Procedure-Kopf dann geht es und an den Literalen habe ich nichts verändert. Also kann es nicht an den Literalen liegen. Es muss was anderes sein und da komme ich einfach nicht hinter.
:coder2:

uligerhardt 23. Mai 2007 12:02

Re: String-Literale
 
Zitat:

Zitat von handson
Der ganze Witz an der Geschichte ist, nehme ich statt der Variable KundenObjData.MandantenId, die Variable MandantenID aus dem Procedure-Kopf dann geht es und an den Literalen habe ich nichts verändert. Also kann es nicht an den Literalen liegen. Es muss was anderes sein und da komme ich einfach nicht hinter.

Das ganze scheint mir wirklich ein Bug im Compiler zu sein. Ist ja vielleicht ein Fall für die QC.

Hawkeye219 23. Mai 2007 18:50

Re: String-Literale
 
Hallo Stephan,

wenn du dem Compiler deinen ShortString als AnsiString verkaufst, könnte es funktionieren:

Delphi-Quellcode:
'anzahl8, anzahl9, anzahl10, anzahl11, anzahl12, anzahl13, anzahl4) VALUES '+
//                                              '('''+KundenObjData.MandantenId+''','+
                                              '('''+string(KundenObjData.MandantenId)+''','+
                                              ''''+KundenObjData.ObjNr+''','+
Ich kann nur vermuten, daß der Compiler hier Code für die Addition zweier ShortStrings durchführen möchte, und dafür ist die zusammengesetzte Stringkonstante wirklich zu lang. Ein ähnliches Verhalten findet man bei arithmetischen Operationen. Sie werden immer mit dem kleinstmöglichen gemeinsamen Datentyp durchgeführt - es sein denn, man führt einen expliziten TypeCast eines Operanden durch.

Gruß Hawkeye

handson 24. Mai 2007 10:52

Re: String-Literale
 
Hallo!

Das ist es auch gewesen, er hat die ganzen Dinger als ShortStrings gesehen, daher nur 255 Zeichen. Mit der String-Umwandlung solls funktionieren.

Da muss auch einer erstmal drauf kommen... :wall:

Vielen Dank nochmal an alle für die schnelle Hilfe und Unterstützung!

Stephan

alzaimar 24. Mai 2007 11:12

Re: String-Literale
 
Wieso bastelt ühr überhaupt so bescheuret Eure Strings zusammen? Entschuldigung, aber in jedem dritten Post sehe ich sowas.

Verwende doch einfach die Format-Funktion und deklariere den SQL-Befehl als Konstante. Das sieht wesentlich übersichtlicher aus, ist es auch und man vermeidet solche Fallstricke. Wenn Du dann den Befehl ändern musst, dann geht das auch viel schneller.

SQL-Code:
Const
  sSQLBefehl = 'insert into Foobar (.....) Values (%s, %s, %s)';

Begin
  MyDataSet.CommandText := Format (sSQLBefehl, [param1, QuotedStr(param2), param3]);
...
Ja gut eh, mit Parametern geht's auch...

handson 25. Mai 2007 13:13

Re: String-Literale
 
Du hast eigentlich recht, allerdings ist es für mich wesentlich übersichtlicher und lesbarer, wenn ich sie so zusammenbaue.
Ich denke, dass ist eine reine Philosophie-Frage. Fehler können überall auftreten. :)

Stephan


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:21 Uhr.

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