![]() |
Datenbank: Paradox • Version: 7 • Zugriff über: TTable and TQuery
Blob mit SQL nach Teilstring durchsuchen?
Ich habe in meiner Tabelle unteranderem ein BLOB Memo.
Jetzt möchte ich über LocalSQL in diesem Blob einen Teilstring suchen, aber alle Befehle die ich mir angeschaut hab beinhalten die Information das es mit allen Datentypen ausser mit Blobs funktioniert. Weis jemand einen Befehl oder eine Methode wie es mit SQL trotzdem geht? |
Re: Blob...
Das ligt warscheinlich daran das es keine für LocalSQL gibt
|
Re: Blob...
Ach.. deswegen frag ich ja ob jemand was weis.. :gruebel:
|
Re: Blob...
Hai Angel4585,
bitte gebe deinem Thread einen aussagekräftigen Titel. Mit "Blob..." kann keiner etwas anfangen. Danke. :-D |
Re: Blob mit SQL nach Teilstring durchsuchen?
besser so?
|
Re: Blob mit SQL nach Teilstring durchsuchen?
LocalSQL kann keine String-Operatoren auf BLOB-Feldern anwenden. Auch die richtigen SQL-Server bieten ihre Suchfunktionen nur über server-spezifische Erweiterungen an. Mit LocalSQL musst du das Durchsuchen von BLOB-Feldern (nur Memos machen Sinn) im Ereignis OnFilterRecord der Query-Komponente erledigen.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
OK, also ich habe:
Delphi-Quellcode:
1.ich suche doch schon mit SQL..kann ich dann überhaupt noch das ganze mit dem OnFilterRecord verbinden?
procedure TdmMain.SearchQueryFilterRecord(DataSet: TDataSet;
var Accept: Boolean); begin if Pos(SearchString,DataSet.Fields.Fields[1].AsString)<>0 then //Was tu ich dann? end; 2.S.o. Was tu ich dann? |
Re: Blob mit SQL nach Teilstring durchsuchen?
Meines Wissens gibt es da für BLOB-Felder mit Local-SQL nichts. Wenn es geht kann man es in ein Textfeld wandeln. Wenn das nicht groß genug ist, dann kann man den Durchlauf nur per Hand Programmieren, Da es nur Lokal läuft, ist das wohl zu Vertreten.
Grüße // Martin PS: Natürlich kannst Du Deinen additiven Fileter in einem vorgefilterten DataSet verwenden. |
Re: Blob mit SQL nach Teilstring durchsuchen?
Hmm.. Gibt es denn noch eine andere Möglichkeit,einen anderen Datentyp in der Paradoxdatenbank, ausser einem BLOB, ein TextFeld zu speichern und mit welcher ich auch per SQL auf den Teilstring untersuchen kann?
|
Re: Blob mit SQL nach Teilstring durchsuchen?
Das Suchen teils über SQL, teil über den Filter-Mechanismus des DataSet - mir würde diese Lösung auch nicht gefallen. Du kannst deinen Datenentwurf so ändern, dass du die einzelnen Textzeilen aus dem Memo in eine 1:n Beziehung (1 Stammsatz und viele Textzeilen) einbringst. Erzeuge dir doch eine Tabelle MEMO.DB, in der du neben einem AUTOINC Primärschlüssel ID alle Textzeilen in VARCHAR(255) Feldern unterbringst, dazu noch einen Fremdschlüssel für deinen Stammsatz. Schon kannst du wieder mit SQL suchen.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
Problem dabei ist nur das mein Chef meinte ich soll alles in dieser einen Tabelle machen, am besten mit BLOBs und mein Chef ist im Moment auf der Systems
|
Re: Blob mit SQL nach Teilstring durchsuchen?
Meint Dein Chef auch, dass Du das mit Paradox machen mußt. // Martin
PS: Systems steht auch noch auf der ToDo-Liste... |
Re: Blob mit SQL nach Teilstring durchsuchen?
Zitat:
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
Hi Angel4585,
Zitat:
du warst schon dicht dran, versuchs mal damit:
Delphi-Quellcode:
Wie bereits gesagt ist zu überlegen ob es wirklich ein BLOB sein muss oder auch ein String mit 255 Zeichen reicht.
procedure TdmMain.SearchQueryFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin Accept := Pos(SearchString,DataSet.Fields.Fields[1].AsString)<>0; end; ... SearchQuery.filtered := true; // nicht vergessen ... Dann kann man auch wieder mit SQL filtern. Außerdem kann ich nur empfehlen Paradox+BDE in den wohlverdienten Ruhestand zu schicken. Man kann sich damit viel Ärger ersparen. alex |
Re: Blob mit SQL nach Teilstring durchsuchen?
Hmm..
@ALL Es muss ein unbegrenztes Feld sein. Deswegen Memo sonst hätte ich ein einfachen String genommen. @Alex : Bei deiner Lösung kommt die Meldung, das auf das Feld mit dem MemoBlob in einem Filter nicht zugeriffen werden kann. @Marabu : Aufgabenstellung ist die, das ich eine Tabelle mit 60 Feldern habe und ungefähr 10000 Einträgen. Diese soll möglichst schnell durchsucht und gefiltert werden können. Ob mit Table oder Query ist egal. @mschaefer : Ja muss mit Paradox sein, da die Tabelle ja schon existiert und wir hier generell mit Paradox arbeiten. |
Re: Blob mit SQL nach Teilstring durchsuchen?
Unter den Konditionen hast Du die Lösung wie es obern schon durchgesprochen ist. Durchlauf per Hand programieren und im AsString des Blobfeldes den Wert mit Pos suchen. Damit ist das wohl zum neuen Arbeitstag als theoretisch gelöst einzustufen, denn Stringsuche ist sicherlich kein Problem.
Grüße / Martin |
Re: Blob mit SQL nach Teilstring durchsuchen?
Ja aber wie ichs gerade an alex geschrieben habe funktioniert das nicht.. Es kommt die Meldung das auf dieses Feld in einem Filter nicht zugegriffen werden kann.
Muss ich da noch irgendwelche anderen Dinge beachten? Das ganze sieht jetzt so aus.
Delphi-Quellcode:
procedure TdmMain.SearchQueryFilterRecord(DataSet: TDataSet;
var Accept: Boolean); var i : integer; begin Accept:=false; for i:= 0 to SearchQuery.FieldCount - 1 do if (Pos(tfSearch.SearchString,DataSet.Fields.Fields[i].AsString)<>0)then begin Accept := true; break; end; end; |
Re: Blob mit SQL nach Teilstring durchsuchen?
Hallo Martin,
du kannst nicht einfach in MemoField.AsString suchen, denn da steht '(MEMO)' drin. Du musst dir schon den Inhalt des Memos besorgen. Du hast ja schon gemerkt, dass du auf das Memo nicht aus dem Filter-Event zugreifen kannst, also mache es so wie ich:
Delphi-Quellcode:
Grüße vom marabu
procedure TDataForm.TableFilterRecord(DataSet: TDataSet;
var Accept: Boolean); var i: integer; f: TField; s, pkName: string; pkValue: variant; begin Accept:=false; with DataSet do begin pkName := 'Nummer'; pkValue := FieldValues[pkName]; for i := 0 to Pred(FieldCount) do begin f := Fields[i]; case f.DataType of ftMemo: s := GetMemo('int', f.FieldName, pkName, pkValue); ftGraphic: s := ''; else s := f.AsString; end; if AnsiContainsText(s, SearchStr) then begin Accept := true; Break; end; end; end; end; function GetMemo(tblName, fldName, keyName: string; keyValue: variant): string; const SELECT = 'SELECT %s FROM %s WHERE %s = :key'; var strm: TStream; q: TQuery; begin q := TQuery.Create(nil); with q do begin DatabaseName := 'TEST'; SQL.Text := Format(SELECT, [fldName, tblName, keyName]); Params.ParamValues['key'] := keyValue; Open; strm := q.CreateBlobStream(Fields[0], bmRead); SetLength(Result, strm.Size); strm.ReadBuffer(Result[1], strm.Size); strm.Free; Close; end; end; |
Re: Blob mit SQL nach Teilstring durchsuchen?
Ähm.. ja.. mom..
GetMemo(tblName, fldName, keyName: string; keyValue: variant): string; tblName = Tabellenname; fldName = Felder die angezeigt werden sollen; KeyName = Feld das durchsucht werden soll; und KeyValue = Wert der in dem zu durchsuchenden Feld enthalten sein soll, oder? |
Re: Blob mit SQL nach Teilstring durchsuchen?
Nicht ganz:
tblName = Tabellenname fldName = Name des Memo-Feldes, dessen Inhalt geholt werden soll KeyName = Name des Feldes, welches für den Zugriff verwendet werden soll KeyValue = Eindeutiger Schlüsselwert Alles klar? marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
tblName ist dann bei mir 'Int.db'
fldName ist f.FieldName KeyName ist ? =fldName? KeyValue ist SearchString Edit: Und statt AnsiContainsText() => Pos()>0 Edit2: Ich glaub ich stell mich irgendwie hammermäßig dumm an...wenn ich das so mache dann kommt die Meldung"Keine Übereinstimmung der Typen im Ausdruck" sobald die Query geöffnet wird. |
Re: Blob mit SQL nach Teilstring durchsuchen?
Ich habe meinen Code weiter oben etwas mehr an deine Bedürfnisse angepasst. Vielleicht wird ja dadurch alles etwas klarer für dich?
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
Kurze Frage, wie wäre es denn mit:
Delphi-Quellcode:
Hab ich nicht probiert, sollte aber funktionieren, oder?
Var
sString : TStringStream; Begin sString := TStringStream.Create; Try myBlobField.SavetoStream (sString); If Pos ('Foobar', sString.DataString) Then Whatever finally sString.Free End; End; |
Re: Blob mit SQL nach Teilstring durchsuchen?
myBlobField wäre in unserem Beispiel ja dann dataset.Field.Fields[i]
allerdings gibbet da glaub ich kein SaveToStream. |
Re: Blob mit SQL nach Teilstring durchsuchen?
Delphi-Quellcode:
So schon :mrgreen:
TBlobField (MyTable.Fields[i])
|
Re: Blob mit SQL nach Teilstring durchsuchen?
Gefällt mir.
Delphi-Quellcode:
marabu
function GetMemo(tblName, fldName, keyName: string; keyValue: variant): string;
const SELECT = 'SELECT %s FROM %s WHERE %s = :key'; var ss: TStringStream; q: TQuery; begin q := TQuery.Create(nil); with q do begin DatabaseName := 'TEST'; SQL.Text := Format(SELECT, [fldName, tblName, keyName]); Params.ParamValues['key'] := keyValue; Open; ss := TStringStream.Create(''); TBlobField(Fields[0]).SaveToStream(ss); Result := ss.DataString; ss.Free; Close; end; end; |
Re: Blob mit SQL nach Teilstring durchsuchen?
@marabu
pkName := NameOfCandidateKeyOfDataSet; Das heisst doch ich brauch in meiner Tabelle ine Feld wo ich den reinen Text des Memos reinschreibe. und den Name dieses Feldes muss ich hier rein schreiben oder? |
Re: Blob mit SQL nach Teilstring durchsuchen?
Ich bin ein schlechter Lehrer, scheint mir. keyName ist der Name des Feldes in deiner Tabelle INT, den du dort als Primary Key festgelegt hast. Solltest du keinen PK haben, dann musst du statt dessen einen Candidate Key verwenden. Beide Keys haben die Eigenschaft, dass sie den Datensatz eindeutig identifizieren können.
Hoffentlich habe ich es jetzt verständlicher ausgedrückt. marabu (auf dem Weg zum Mittagstisch) |
Re: Blob mit SQL nach Teilstring durchsuchen?
Das funzt jetzt genauso gut wie:
Delphi-Quellcode:
Gleiche Fehlermeldung: TSearch : Auf Feld 'Erstnotiz' kann in einem Filter nicht zugegriffen werden.
Accept := false;
with dataset do for i:= 0 to Pred(FieldCount) do if Pos(SearchString,Fields[i].AsString)> 0 then begin Accept := true; break; end; Info : erstnotiz ist ein memoBlob, TSearch mein Table |
Re: Blob mit SQL nach Teilstring durchsuchen?
Wie heißt denn das Feld in der Tabelle INT, welches als Primärschlüssel festgelegt ist und welchen Typ hat dieses Feld? In der Datenbankoberfläche erkennst du es am Stern in der letzten Spalte, wenn du die Strukturinformationen zur Tabelle anschaust.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
Feld heisst 'Nummer' und ist AutoInc
Frage : Muss ich vielleicht irgendwas bei der TTable komponente einstellen? Sagt das jemandem was: #. Programmer's name for it: SNoFieldAccess #: Vcl/bdeconst.pas:68 msgid "Cannot access field '%s' in a filter" msgstr "Auf Feld '%s' kann in einem Filter nicht zugegriffen werden" |
Re: Blob mit SQL nach Teilstring durchsuchen?
Ich habe dir jetzt Nummer als pkName in meinem Beispiel für die Filter-Routine eingetragen. Wenn es jetzt immer noch nicht funktioniert, dann musst du mal deine Filter-Routine hier zeigen.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
Delphi-Quellcode:
so siehts bei mir aus
function GetMemo(tblName, fldName, keyName: string; keyValue: variant): string;
const SELECT = 'SELECT %s FROM %s WHERE %s = :key'; var ss: TStringStream; q: TQuery; begin q := TQuery.Create(nil); with q do begin DatabaseName := 'Mailingliste'; SQL.Text := Format(SELECT, [fldName, tblName, keyName]); Params.ParamValues['key'] := keyValue; Open; ss := TStringStream.Create(''); TBlobField(Fields[0]).SaveToStream(ss); Result := ss.DataString; ss.Free; Close; end; end; procedure TdmMain.TSearchFilterRecord(DataSet: TDataSet; var Accept: Boolean); var i: integer; f: TField; s, pkName: string; pkValue: variant; begin Accept:=false; with DataSet do begin pkName := 'Nummer'; pkValue := FieldValues[pkName]; for i := 0 to Pred(FieldCount) do begin f := Fields[i]; ShowMessage(f.AsString); case f.DataType of ftMemo: s := GetMemo('"int.db"', f.FieldName, pkName, pkValue); ftGraphic: s := ''; else s := f.AsString; end; if Pos(s, tfSearch.SearchString)>0 then begin Accept := true; Break; end; end; end; end; Edit Ob 'int' oder '"int.db"' macht keinen Unterschied |
Re: Blob mit SQL nach Teilstring durchsuchen?
Der Code ist jetzt prinzipiell in Ordnung. Du hast AnsiContainsText() durch Pos() ersetzt, dadurch wird die Schreibweise eventuell zum Stolperstein. Der Fehler ensteht dadurch, dass du einfach über alle Felder iterierst, wobei es Felder gibt, auf die du im OnFilterRecord-Event nicht zugreifen darfst. Zu diesen Feldern gehören alle Blob-Felder. Untersuche mal die Struktur der Tabelle int, ob da noch andere kritische Feldtypen vorkommen.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
ne es sind nur ftMemo und ftBlob, wenn ich diese ausklammer dann funktioniert es ohne Probs.
Das deprimierende ist, ich "erneuere" gerade ein altes Programm das mit der selben Tabelle läuft. Und das alte Programm kann auf diese Felder zugreifen(ausserhalb des OnFilterRecords). d.h. ich muss diese Suchfunktion irgendwie ausserhalb des Filters realisieren oder? Edit: Wie kann ich dieses ANsiContainsText nutzen? mein Delphi kennt das nicht Edit2 : Ah habs, StrUtils einbinden dann..gehts aber immernochnicht. Ich probier das mal anders. Ich werd das ganze extern machen und in en StringGrid reinschreiben.. dann müssts eigentlich gehen |
Re: Blob mit SQL nach Teilstring durchsuchen?
So.. Ich hab jetzt folgenden Code.. es funktioniert auch fast.. aber eben nur fast. Irgendwann, nachdem es 15 sekunden oder so das System blockiert kommt die Meldung falscher Parameter. Aber ich weis nicht warum, zumal es ja ne Weile perfekt läuft.
Delphi-Quellcode:
Weis jemand wo ich diesmal den Fehler hab?
procedure TtfSearch.InitGrid;
var i : integer; begin tfSearchResults.searchgrid.ColCount:=dmMain.TSearch.FieldCount; for i:= 0 to dmMain.TSearch.FieldCount -1 do tfSearchResults.searchgrid.Cells[i,0]:=dmMain.TSearch.Fields.Fields[i].FieldName; tfSearchResults.searchgrid.RowCount:=2; end; {------------------------------------------------------------------------------} procedure TtfSearch.AddFound(f : TFields); var i : integer; begin with tfSearchResults.searchgrid do begin for i:= 0 to dmMain.TSearch.FieldCount -1 do Cells[i,RowCount-1]:=dmMain.TSearch.Fields.Fields[i].AsString; RowCount:=RowCount+1; end; end; {------------------------------------------------------------------------------} function GetMemo(tblName, fldName, keyName: string; keyValue: variant): string; const SELECT = 'SELECT %s FROM %s WHERE %s = :key'; var ss: TStringStream; q: TQuery; begin q := TQuery.Create(nil); with q do begin DatabaseName := 'Mailingliste'; SQL.Text := Format(SELECT, [fldName, tblName, keyName]); Params.ParamValues['key'] := keyValue; Open; ss := TStringStream.Create(''); TBlobField(Fields[0]).SaveToStream(ss); Result := ss.DataString; ss.Free; Close; end; end; {------------------------------------------------------------------------------} procedure TtfSearch.Suche(SearchPart : string; Feld : string; GrossKlein : boolean;Komplett : boolean); var temp : string; RecAll,i : integer; f: TField; s, pkName: string; pkValue: variant; begin with dmMain.TSearch do begin Open; pkName := 'Nummer'; InitGrid; First; while not eof do begin pkValue := FieldValues[pkName]; for i := 0 to Pred(FieldCount) do begin f := Fields.Fields[i]; case f.DataType of ftMemo: s := GetMemo('"'+TableName+'"', f.FieldName, pkName, pkValue); else s := f.AsString; end; if AnsiContainsText(s, tfSearch.SearchString) then begin AddFound(Fields); ShowMessage(Fields.Fields[0].asstring); Break; end; end; Next; end; if RecordCount > 0 then tfSearchResults.tsbStatus.Panels.Items[1].Text:=Format(' %7d/%-7d Treffer gesamt',[RecordCount,RecAll]) else MessageDlg('Es wurden keine Übereinstimmungen gefunden',mtConfirmation,[mbOK],0); end; end; |
[GELÖST] Blob mit SQL nach Teilstring durchsuchen?
SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY SORRY
hab mich SOOOOOOOOOOOOOOOOOOOOOO DUMM angestellt, dabei gehts ganz einfach: Ich habe folgendes gemacht :
SQL-Code:
ging mit Blobs nicht :
WHERE CAST('+Feld+' AS CHARACTER(255)) LIKE "%'+SearchPart+'%"
jetzt hab ich gerade irgendwo DAS gesehen:
SQL-Code:
und was soll ich sagen: ES FUNKTIONIERT!!!!
WHERE '+Feld+' LIKE "%'+SearchPart+'%"
:wall: :wall: :wall: :wall: :wall: :wall: :wall: Edit : ein kleines Problem hab ich aber trotzdem noch: die Funktion UPPER() funktioniert nicht auf dem Memo... Soll ich en Neuen Thread eröffnen oder machen wir das gleich hier?(kurz und schmerzlos) Übrigens hier die Seite auf der ich das gefunden hab. Ist hoffentlich kein Problem wenn ich da mal hier rein mache : ![]() da unter 5. e) (Resttext ist ein Blob) |
Re: Blob mit SQL nach Teilstring durchsuchen?
Martin, geht es noch um Paradox? In MySQL gibt es reichlich Unterstützung für den BLOB resp. TEXT Datentyp, in Paradox gar keine - insbesondere keine Operatoren. Wie kann das also bei dir funktionieren? Indem du nur die ersten 255 Stellen für deine Suche heranziehst? Klar es gibt keinen compile-time oder run-time Fehler, aber das nenne ich nicht funktionieren.
marabu |
Re: Blob mit SQL nach Teilstring durchsuchen?
marabu, ja es geht noch um Paradox. Ich weis nicht WARUM es funktioniert. ich weis nur DAS es funktioniert. Und ich nimm sicher nicht nur 255 Zeichen sondern es sucht in dem ganzen Memo. Ich habe es getestet indem ich extra mal 500 Zeichen reingeschrieben habe und habe nach dem ersten Wort gesucht, und einmal nach dem letzten Wort gesucht. Und es funktioniert. Warum das so ist ist mir eigentlich egal ich bin nur saumäßig Happy DAS es funtioniert. Aber ich hindere niemanden daran herauszufinden WARUM es funktioniert.
Edit: LOCALSQL.HLP ist das Stichwort : Suche nach WHERE, geh nach ganz unten in dem Artikel: dort steht: Tip: Bei der Filterung der meisten Spaltentypen genügen die einfachen Vergleichsprädikate. Erfolgt die Filterung jedoch auf der Basis der Inhalte einer MEMO-Spalte, müssen Sie mit dem Prädikat LIKE arbeiten. |
Re: Blob mit SQL nach Teilstring durchsuchen?
JaEin,
also, die Tücke liegt im Detail. Paradox speichert einen Teil des Blobfeldes in der Datenbanktabelle und einen Teil im externen Blobbfeld. Der Textteil in der Datenbanktabelle kann bei der Definition mit 1 bis 255 Zeichen angegeben werden. Eigentlich habe ich angenommen, dass das Like-Statement nur auf die Zeichen in der Tabelle angesetzt wird. /EDIT/ Bei dem Blobb war ich der Meinung, dass es nicht richtig durchsucht wird. /EDIT/ Grüße // Martin |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 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 by Thomas Breitkreuz