Subject | Re: Memory issue with text blob (blob sub_type 1) query |
---|---|
Author | dkeith2 |
Post date | 2009-08-06T19:51:31Z |
Thanks Dmitry. By changing the :COMBINED variable to a VARCHAR(32000) that cleared up the problem. The new procedure looks like this and works well:
CREATE PROCEDURE PARSE_HTML_TAGS
RETURNS (
ATAG VARCHAR(255))
AS
DECLARE VARIABLE COMBINED VARCHAR(32000);
DECLARE VARIABLE CNT INTEGER;
DECLARE VARIABLE POS INTEGER;
DECLARE VARIABLE LOC1 INTEGER;
DECLARE VARIABLE LOC2 INTEGER;
DECLARE VARIABLE TAG VARCHAR(255);
BEGIN
FOR SELECT DISHEET
FROM CP_MONO_MAIN_PATI_
INTO :COMBINED
DO
BEGIN
POS = 1;
LOC1 = 1;
LOC2 = 3;
WHILE ((:LOC2 > 2) AND (:LOC1 > 0)) DO
BEGIN
LOC1 = POSITION('<',:COMBINED,:POS);
LOC2 = POSITION('>',:COMBINED,:POS);
IF ((:LOC1 > 0) AND (:LOC2 > 0) AND ((:LOC2 - :LOC1 + 1) > 0)) THEN
TAG = UPPER(SUBSTRING(:COMBINED FROM :LOC1 FOR ((:LOC2 - :LOC1) + 1)));
POS = :LOC2 + 1;
ATAG = :TAG;
IF (POSITION('/' IN :ATAG) <> 2) THEN
SUSPEND;
END
POS = 1;
LOC1 = 1;
LOC2 = 3;
WHILE ((:LOC2 > 2) AND (:LOC1 > 0)) DO
BEGIN
LOC1 = POSITION('&',:COMBINED,:POS);
LOC2 = POSITION(';',:COMBINED,:POS);
IF ((:LOC1 > 0) AND (:LOC2 > 0) AND ((:LOC2 - :LOC1 + 1) > 0)) THEN
TAG = UPPER(SUBSTRING(:COMBINED FROM :LOC1 FOR ((:LOC2 - :LOC1) + 1)));
POS = :LOC2 + 1;
END
COMBINED = '';
ATAG = :TAG;
SUSPEND;
END
END
David Keith
CREATE PROCEDURE PARSE_HTML_TAGS
RETURNS (
ATAG VARCHAR(255))
AS
DECLARE VARIABLE COMBINED VARCHAR(32000);
DECLARE VARIABLE CNT INTEGER;
DECLARE VARIABLE POS INTEGER;
DECLARE VARIABLE LOC1 INTEGER;
DECLARE VARIABLE LOC2 INTEGER;
DECLARE VARIABLE TAG VARCHAR(255);
BEGIN
FOR SELECT DISHEET
FROM CP_MONO_MAIN_PATI_
INTO :COMBINED
DO
BEGIN
POS = 1;
LOC1 = 1;
LOC2 = 3;
WHILE ((:LOC2 > 2) AND (:LOC1 > 0)) DO
BEGIN
LOC1 = POSITION('<',:COMBINED,:POS);
LOC2 = POSITION('>',:COMBINED,:POS);
IF ((:LOC1 > 0) AND (:LOC2 > 0) AND ((:LOC2 - :LOC1 + 1) > 0)) THEN
TAG = UPPER(SUBSTRING(:COMBINED FROM :LOC1 FOR ((:LOC2 - :LOC1) + 1)));
POS = :LOC2 + 1;
ATAG = :TAG;
IF (POSITION('/' IN :ATAG) <> 2) THEN
SUSPEND;
END
POS = 1;
LOC1 = 1;
LOC2 = 3;
WHILE ((:LOC2 > 2) AND (:LOC1 > 0)) DO
BEGIN
LOC1 = POSITION('&',:COMBINED,:POS);
LOC2 = POSITION(';',:COMBINED,:POS);
IF ((:LOC1 > 0) AND (:LOC2 > 0) AND ((:LOC2 - :LOC1 + 1) > 0)) THEN
TAG = UPPER(SUBSTRING(:COMBINED FROM :LOC1 FOR ((:LOC2 - :LOC1) + 1)));
POS = :LOC2 + 1;
END
COMBINED = '';
ATAG = :TAG;
SUSPEND;
END
END
David Keith
--- In firebird-support@yahoogroups.com, Dmitry Yemanov <dimitr@...> wrote:
>
> dkeith2 wrote:
>
> > Is there a setting in firebird.conf that would allow me to allocate more memory to the instance so that this query could run?
>
> No. This error means that the operating system simply doesn't have any
> available memory (or you get out of the process address space).
>
> > I've tried many permutations of this, but all eventually run out of resources.
>
> Don't use blobs instead of varchars unless strictly required. Your
> procedure creates a lot of temporary blobs (intermediate operation
> results). Every such blob occupies around <page size> bytes of memory
> for the whole transaction lifetime.
>
> FB 2.5 works better in this regard, but this practice is still not
> friendly to the engine.
>
>
> Dmitry
>