Einzelnen Beitrag anzeigen

berens

Registriert seit: 3. Sep 2004
421 Beiträge
 
Delphi 2010 Professional
 
#1

Leeren Text "" in MS-SQL Feld NOT NULL Problem

  Alt 30. Jun 2020, 11:16
Datenbank: MS SQL [Express] • Version: 2019 • Zugriff über: TAdoConnection
Hallo zusammen,
ich sitze gerade daran, meine Software mit Access-Datenbank auf einen SQL skalieren zu können.

Siehe dazu auch https://www.delphipraxis.net/204437-...g-welches.html .

Um direkt in Zukunft Probleme wie dieses vermeiden zu können: https://www.delphipraxis.net/204363-...oder-null.html
lege ich nun auf dem Server direkt alle Felder aller Tabellen mit "NOT NULL" und "DEFAULT 0" oder "DEFAULT ''" an:

Delphi-Quellcode:
function CreateTable_Layout(_DatabaseType: TDatabaseType; q: TADOQuery): Boolean;
begin
  Result := False;
  try
    try
      q.Close;
      q.SQL.Clear;

      q.SQL.Add('CREATE TABLE Layout');
      q.SQL.Add(' ( ' );
      q.SQL.Add('ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL, ' );
      // viele weitere Felder
      q.SQL.Add('MeinText TEXT NOT NULL DEFAULT '''' ' );
      q.SQL.Add(' ) ' );

      q.Prepared := True;
      q.ExecSQL;

      Result := True;
    finally
      q.Close;
      q.SQL.Clear;
    end;
  except
    on E: SysUtils.Exception do begin
      Log('CreateTable_Layout', M, E.Message, ws_SEVERITY_EXCEPTION);
    end;
  end;
end;
Das Problem ist, wenn ich einen leeren, aber -meine erachtens- nicht-NULL String speichern möchte, er meckert, dass keine NULL-Werte in diesem Feld zulässig sind. Scheinbar werden Felder vom Typ TEXT doch anders gespeichert als VARCHAR(255), und er wandelt leere Strings Server-intern in NULL um?
Delphi-Quellcode:
          
var
  t: string;
begin
  _Target.Insert;
  _Target.FieldByName('Foo').AsInteger := _Source.FieldByName('Foo').AsInteger;
  _Target.FieldByName('Bar').AsInteger := _Source.FieldByName('Bar').AsInteger;
  t := '';
  _Target.FieldByName('MeinText').AsString := t;
  _Target.Post; // Fehler: MeinText darf nicht NULL sein!
In anderen Beiträgen wurde geraten, die TEXT-Felder der Tabelle auf VARCHAR(MAX) zu ändern. Zwar glaube ich eigentlich nicht, dass "MeinText" jemals größer als ~65000 Zeichen werden sollte, da die Access-Datenbank aber mit dem "MEMO"-Feldtyp (Neuerdings bezeichnet als "Langer Text") bis k.a. wieviel MB/GB Daten aufnehmen konnte, würde ich nun ungern in mein Programm eine zusätzliche Fehlerquelle einbauen indem sich die Feldtypen in der Access-Datenbank von den Feldtypen auf dem SQL-Server unterscheiden.

Andererseits sind die meisten "TEXT"-Felder auf der neuen Server Datenbank wirklich so "irrelevant", dass sie wahrscheinlich in den Abfragen eh nicht namentlich gefiltert werden, und es letztendlich wirklich egal wäre, ob sie leer, NULL und gefüllt sind.

Dennoch geht es mir hier auch ein wenig um's Prinzip:
Wie kann ich leere Strings über TAdoQuery in einen MS-SQL Server speichern, bei dem das TEXT Feld NOT NULL DEFAULT "" ist?

Vielen Dank für Meldungen und Meinungen zu dem Thema!



Edit 1:
Es könnte an der Umwandlung von AsString liegen? So würde es gehen, schließlich ist #0 kein NULL String. Aber diese Nachverarbeitung an allen Stellen im Quelltext für alle Datenfelder vom Typ TEXT, *obwohl* ein DEFAULT-Wert vorgegeben ist, ist imo vom Aufwand her nicht begründbar.
Delphi-Quellcode:
  t := trim(_Source.FieldByName(MeinText).AsString);
  if trim(t) = 'then begin
    _Target.FieldByName(MeinText).AsString := #0;
  end else begin
    _Target.FieldByName(MeinText).AsString := t;
  end;
Delphi 10.4 32-Bit auf Windows 10 Pro 64-Bit, ehem. Delphi 2010 32-Bit auf Windows 10 Pro 64-Bit

Geändert von berens (30. Jun 2020 um 11:22 Uhr)
  Mit Zitat antworten Zitat