Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Falsche Zeichen in einem DB-Feld per SQL finden (https://www.delphipraxis.net/117348-falsche-zeichen-einem-db-feld-per-sql-finden.html)

mkinzler 16. Jul 2008 15:15

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Wrum? Ein Trigger läuft doch in der Datenbank und reagiert auf das Schreiben durch das Programm

nachtstreuner60 16. Jul 2008 15:16

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hallo Union,

habe noch nie mit Triggern gearbeitet, wie funktionieren die ?

Muss hierfür in der Firebird Datenbank etwas gecodet werden ?

Union 16. Jul 2008 15:21

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Ja, sowas wie:
SQL-Code:
CREATE TRIGGER IDOC_CHECK FOR IDOC_REAL
ACTIVE AFTER INSERT
AS
begin
  if (INSERTING) then ...
end

nachtstreuner60 16. Jul 2008 15:32

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hallo union,

wenn ich das richtig verstanden habe, müsste ich in dem Abschnitt

Delphi-Quellcode:
if (INSERTING) then ...
prüfen, ob die Zeichenfolge ab der zweiten Stelle keine Zahl ist ?

Aber wie sieht der Code hierzu aus ?

Wenn es sich um einen Fehlerhaften Datensatz handelt, muss dieser in eine andere tabelle geschrieben werden?
Oder reicht es aus, wenn ich in der Ursprungsdatenbank ein zusätzliches Feld wie etwa (STATUS = 'F') anlege u. dieses dann
je nach Ergebnis mit einem F fülle ?

mkinzler 16. Jul 2008 15:47

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Ich würde den Trigger nicht im AFTER INSERT sondern BEFORE INSERT machen. Dann kannst du die einzufügenden Werte noch ändern oder weitere Werte setzen (z.B. den Status)
http://udf.adhoc-data.de/dokumentati...eu_string.html

nahpets 16. Jul 2008 17:04

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hallo,

versuch doch mal sowas:

SQL-Code:
Select *
from IDOC_REAL where
replace(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
replace(
replace(Idoc_REAL."ScanCode",1,''),2,''),3,''),4,''),5,''),6,''),7,''),8,''),9,''),0,'')
<> 'F'
Beim SQL-Server und Postgres funktioniert das.

Eventuell könntest Du auch noch das F mit rausfiltern und dann auf einen Leerstring abfragen.
Die Umwandlung in eine Zahl wird scheitern, da beim CAST(ScanCode as INT) beim ersten Satz, der ein ungültiges Zeichen enthält, ein Ausnahme geworfen wird. Die müsstest Du dann auch noch abfangen.

Stephan

nachtstreuner60 16. Jul 2008 19:53

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hallo Stephan,

danke für deine Antwort. Ich steige bei diesem SQL Statement nicht durch. Kannst Du mir etwas genauer erklären, was dieses Statement macht. Insbesondere das REPLACE .

Danke schon mal

dataspider 16. Jul 2008 20:31

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hi,

ich würde für den Test eine Procedure schreiben:

SQL-Code:
SET TERM ^ ;

CREATE PROCEDURE CHECK_BARCODE (
    barcode varchar(20))
returns (
    result char(1))
as
begin
  /* check barcode */
  result = 'F';
  if (substring(:barcode from 1 for 1) <> 'F') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 2 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 3 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 4 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 5 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 6 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  if (substring(:barcode from 7 for 1) not between '0' and '9') then
  begin
    suspend;
    exit;
  end
  result = 'T';
  suspend;
end^
SET TERM ; ^
das where sollte dann so aussehen:

SQL-Code:
where (select result from check_barcode(ScanCode)) = 'F'
Cu, Frank

alex517 16. Jul 2008 21:30

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
Hi

du könntest neben dem Feld SCANCODE ein zweites Feld z.B. "SCANCODE_CLEARED" in der Tabelle führen in der die bereinigten Scancodes stehen.
Dieses Feld "SCANCODE_CLEARED" wird immer durch einen Insert/Update-Trigger gesetzt.


SQL-Code:
CREATE OR ALTER TRIGGER SCANCODES_BI FOR SCANCODES
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_SCANCODES_ID,1);

  NEW.SCANCODE_CLEARED = 'F'||F_STRIPSTRINGHOLD( F_STRCOPY(NEW.SCANCODE, 1, 10), '0123456789');
END
F_STRIPSTRINGHOLD() und F_STRCOPY() sind Funktionen aus der FreeAdHocUDF.
Die musst du natürlich vorher einbinden.

Abfrage für fehlerhaften Sätze:
SQL-Code:
select
  S.ID,
  S.SCANCODE,
  S.SCANCODE_CLEARED
from
  SCANCODES S
where
  S.SCANCODE <> S.SCANCODE_CLEARED
Abfrage für korrekte Sätze:
SQL-Code:
select
  S.ID,
  S.SCANCODE,
  S.SCANCODE_CLEARED
from
  SCANCODES S
where
  S.SCANCODE = S.SCANCODE_CLEARED
Das geht natürlich auch ohne extra Feld nur mit einen Select-Statement.
Kommt darauf an wie oft du Werte benötigst.
SQL-Code:
select
  S.ID,
  S.SCANCODE,
  'F'||F_STRIPSTRINGHOLD( F_STRCOPY(S.SCANCODE, 1, 10), '0123456789')
from SCANCODES S
where
  S.SCANCODE <> 'F'||F_STRIPSTRINGHOLD( F_STRCOPY(S.SCANCODE, 1, 10), '0123456789')
alex

omata 16. Jul 2008 23:23

Re: Falsche Zeichen in einem DB-Feld per SQL finden
 
SQL-Code:
SET TERM ^ ;
CREATE OR ALTER PROCEDURE CLEARNUMERIC (
  INPUTSTR Varchar(100)
)
RETURNS (Result Varchar(100)) AS
BEGIN
  Result = '';
  WHILE (InputStr <> '') DO BEGIN
    IF ('0123456789' NOT LIKE '%' || SUBSTRING(InputStr FROM 1 FOR 1) || '%') THEN
    BEGIN
      Result = Result || SUBSTRING(InputStr FROM 1 FOR 1);
    END
    InputStr = SUBSTRING(InputStr FROM 2);
  END
  SUSPEND;
END^
SET TERM ; ^
SQL-Code:
SELECT *
FROM IDOC_REAL
WHERE (SELECT result FROM CLEARNUMERIC(ScanCode)) <> 'F'


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:34 Uhr.
Seite 2 von 4     12 34      

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