28. marts 2000 - 17:08Der er
26 kommentarer og 1 løsning
MS SQL Server - Delphi og lange strenge...
Jeg har et problem med lange strenge i delphi, jeg vil godt vide om der er nogle der ved hvordan man kan gemme strenge over 8192 tegn op til en MS SQL Server (7) hvor datafeltet er en "TEXT" -
AsString - gemmer som sagt kun med 8192 tegn, ...
jeg tror at der skal ud i noget AsBlob men kan ikke få det til at fungere, anyone please help me....
Den moderne arbejdsplads er i stigende grad afhængig af mødelokaler til at fremme samarbejde, men dette skift medfører også stigende sikkerhedsudfordringer.
Hvad med at benytte en stream til at putte din streng ind i feltet. Fx. noget i stil med nedenstående:
procedure TextToField(field : TBlobField; Text : String); var ms : TMemoryStream; s : String; begin S := 'hakon var her!'; ms := TMemoryStream.Create; try ms.SetSize(Length(s)); StrPCopy(ms.Memory, S); ms.position := 0; field.LoadFromStream(ms); finally ms.Free; end; end;
og læse det igen således:
procedure FieldToText(field : TBlobField; var Text : String); var ms : TMemoryStream; s : String; begin S := ''; ms := TMemoryStream.Create; try field.SaveToStream(ms); ms.position := 0; SetString(Text, PChar(ms.memory), ms.Size); finally ms.Free; end; end;
Der var desværre lidt teststuff tilbage i koden, men her er en renset :-)
procedure FieldToText(field : TBlobField; var Text : String); var ms : TMemoryStream; begin ms := TMemoryStream.Create; try field.SaveToStream(ms); ms.position := 0; SetString(Text, PChar(ms.memory), ms.Size); finally ms.Free; end; end;
procedure TextToField(field : TBlobField; Text : String); var ms : TMemoryStream; begin ms := TMemoryStream.Create; try ms.SetSize(Length(Text)); StrPCopy(ms.Memory, Text); ms.position := 0; field.LoadFromStream(ms); finally ms.Free; end; end;
Alternativt kunne du oprette en tabel der indeholde de linier du skal have gemt, hver post i tabellen kunne så være en varchar (256). DU SKAL SÅ BARE HAVE EN LINK ATTRIBUT FRA DIN TABEL TIL TABELLEN MED TEKSTLINIERNE.
OBS: Det er ikke nogen "pæn" løsning men den virker !!!!!!!!!!!!!
Der må være en bedre måde, det kan ikke passe man skal ud i den slags underlig kodning, fandme nej, det er en meget almindelig problemstilling, hvis ikke den kan det pænere, så kan man ikke sælge delphi, så keep answering, det der kan jeg ikke bruge...
picard, ellers tak for det, men nej det er ikke en pæn løsning, faktisk er det en ubrugelig løsning - hvorfor gider jeg ikke komme ind på, men omstrukturering af databasen er absolut ikke en option....
Efter at have debugget en del ind i VCL sourcen har jeg fundet en nem løsning!!!
Før du får den vil jeg dog lige sige at ovenstående er ganske fin og almindelig Delphi, som virker på TFields og med meget små ændringer også på TParams...
Den er uhyggelig enkel og virker på min maskine med 100K strenge (og sikkert meget længere). Benyt
Query1.Params[0].AsMemo := 'Some text in a long Pascal String';
Når du skal hente strengen ud kan du nemt benytte AsString...
Baunsgaard, der er et problem med AsMemo, nemlig at den er limited af hvad du har skrevet i din bde config, som BLOB SIZE, og min og standard er 32K og derfor ikke umildbart lang nok til at efterkomme mit formål... :/
det er ihvertfald den konklusion jeg har er kommet frem til, jeg har testet den tidligere, og den cutter stadig, dog ikke så meget som asstring, hvis jeg sætter blob size op til 1000 kan den tage noget mere, men 1000 er i sig selv heller ikke fleksibel nok, og det er ikke sat som standart, der må da være en måde hvor man ikke er limited på den måde, ellers må blob size kunne sættes at runtime, - men stadig 1000K er jo kun en mega, det kan da ikke være maks...
men jeg har også det problem at jeg ikke kan create blob/memo fields at runtime, så jeg kan ikke rigtig smide en tfield med i parameter på dit ovenstående... hvis du så har en løsning på det og eksempel hvor man kan bruge sammen med params... så kan det være mit problem er løst... MEN helst en måde man kan bruge as blob/memo uden begrænsning
Jeg må tilstå at jeg ikke er løbet i problemer med AsMemo. I min BDE Config står der ganske rigtigt 32(K), men det har ikke haft betydning.
Jeg har netop prøvet at lave nogle tests med nogle større strenge med følgende kode
S := ''; for i := 1 to 100000 do S := S + '1234567890ABCDEF'; // Giver en ~1.6 MB streng
og ParamByName('tekst').AsMemo := S;
samt
TextToParam(ParamByName('tekst'), S);
Der benytter en modificeret udgave af koden jeg først postede som er nedenfor
procedure TextToParam(field : TParam; Text : String); var ms : TMemoryStream; begin ms := TMemoryStream.Create; try ms.SetSize(Length(Text)); StrPCopy(ms.Memory, Text); ms.position := 0; field.LoadFromStream(ms, ftMemo); finally ms.Free; end; end;
Der er ingen problemer med strenge af den størrelse i mit setup med en meget simpel TQuery som nedenfor:
object Query2: TQuery DatabaseName = 'baser' SQL.Strings = ( 'INSERT INTO dbo.Test VALUES (:tekst)') Left = 344 Top = 8 ParamData = < item DataType = ftUnknown Name = 'tekst' ParamType = ptUnknown end> end
Hvis du ser i hjælpen til BLOB SIZE står der 'This parameter does not apply to live table opens.' Jeg ved ikke om det ville have en betydning, hvis du benyttede RequestLive på din TQuery...
Det er vist ikke opløftende nyheder, men jeg prøver alligevel :-)
Med Delphi 4 C/S uden sp. virker det ikke over ~8 KB på Win98. Med service pack 2 virker det perfekt - den længste streng jeg prøvede var på ~3 MB og det virkede fint.
Jeg føler mig næsten overbevist om at du allerede har installeret service packs til din Delphi - hvis ikke, så gør det straks...
service packs til delphi, det har du nok ikke ret i at jeg har, :) kan du give mig en url til sådan en...
anyway så må jeg lede efter den, men det lyder da opløftende, i og med at jeg ikke har installeret den... så jeg siger mange tak for tålmodigheden og hjælpen, du har sgu fortjent pointene, så here ya go :)
baunsgaard, jeg har dog stadig problemer blob size sætter stadig størrelsen for min upload, hvis du har et test projekt med en simpel upload kunne jeg ikke få lov at kigge i det? evt du kunne maile mig sourcen til et simpelt proj. der virker på din delphi 4, / jeg tror ikke det skulle være pga C/S versus Pro.
Benyt ado istedet for bde, fordi med ado er der ingen problemer i delphi at gemme string over 255 character. BDE'en benytter DBlib til SQL7, men DBLIB er udviklet til SQL65 og kan ikke udnytte de nye datatyper under SQL7, som NCHAR og VARCHAR > 255 m.m. Microsoft har skottet DBLIB og anbefaler ADO
ADO kan også benyttes til Delphi 4 eller tidligere. Enten ved selv benytte ADO, vhj com, eller købe TADOExpress kombonenter.
Ja TEXT er et blob felt og fandes også i MSSQL 6.5, men i MSSQL 7, kan varchar nu være til at kunne indeholde 8096 bytes. Da Varchar er nemmere end blob, kunne det løse dit problem.
Blackthorne, jeg tror simpelthen at du har mistforstået noget, jeg har INTET problem med at gemme 8192 Kilo som er limit på asstring, men det er IKKE NOK
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.