1

I was trying to create a function in pl/sql that will accept a String and to split the String into an array then compare the array of the split string into the invalid characters stored in the database.

I am still experimenting, haven't tested the apex_string.split since I encountered these errors: Error(7,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior The symbol "begin" was substituted for "DECLARE" to continue.

Error(38): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge

I'm kinda new to PL/SQL and I am open to any comments

thanks

create or replace FUNCTION invalid_checker(inword IN varchar2)
RETURN boolean
IS 
    hasInvalid boolean;


declare
    CURSOR invalids IS select invalidChar from InvalidCharacter;  --table that contains the invalid characters
    Type wordsplit IS VARRAY(100) OF VARCHAR2(2);
    splitcount INTEGER;
    invalidscount INTEGER ;
    ctr INTEGER := 0;
    invalidctr INTEGER :=0;
    wordarray wordsplit;    
    
begin

open invalids;

wordarray := wordsplit(apex_string.split(inword, null));--split inserted word into array
--splitcount := wordsplit.count
--invalidsctr := invalids.count

FOR splitcount IN wordarray LOOP
    ctr := ctr + 1;
    FOR invalidscount IN invalids LOOP
        invalidctr := invalidctr + 1;
        IF (wordarray(ctr) = invalids(invalidctr)) THEN
            hasInvalid := true;
        END IF;
    END LOOP;
END LOOP;

close invalids;

RETURN hasInvalid;
end;
/
1
  • Simply delete declare, it's not needed. Commented Apr 27, 2021 at 8:37

2 Answers 2

2
  • Delete the DECLARE keyword as it is not needed.

  • You want to iterate the array using:

    FOR splitcount IN 1 .. wordarray.COUNT LOOP
    

    and you do not need to declare the splitcount varaible.

  • You cannot read a CURSOR multiple times. Instead of a CURSOR use SELECT ... BULK COLLECT INTO ... and collect the invalid values into a collection (and that you can read multiple times).

However, it looks like you could simplify it a lot:

CREATE FUNCTION invalid_checker(inword IN varchar2)
RETURN boolean
IS 
  hasinvalid INTEGER ;    
BEGIN
  SELECT 1
  INTO   hasInvalid
  FROM   (
           SELECT SUBSTR(inword, LEVEL, 1) AS ch
           FROM   DUAL
           CONNECT BY LEVEL <= LENGTH(inword)
         ) c
         INNER JOIN InvalidCharacter i
         ON ( c.ch = i.invalidchar )
  FETCH FIRST ROW ONLY;

  RETURN TRUE;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RETURN FALSE;
END;
/

Then, if you have:

CREATE TABLE InvalidCharacter ( invalidchar ) AS
SELECT 'A' FROM DUAL UNION ALL
SELECT 'C' FROM DUAL UNION ALL
SELECT 'E' FROM DUAL;

And run:

DECLARE
  words SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST(
    'BDF',
    'ACE',
    'BDE',
    'ace'
  );
BEGIN
  FOR i IN 1 .. words.COUNT LOOP
    IF invalid_checker( words(i) ) THEN
      DBMS_OUTPUT.PUT_LINE( words(i) || ' invalid' );
    ELSE
      DBMS_OUTPUT.PUT_LINE( words(i) || ' valid' );
    END IF;
  END LOOP;
END;
/

The output is:

BDF valid
ACE invalid
BDE invalid
ace valid

db<>fiddle here

Sign up to request clarification or add additional context in comments.

Comments

1

I saw this question and thought, why invoke PL/SQL at all? This can be answered with just SQL.

CREATE TABLE InvalidCharacter ( invalidchar ) AS
SELECT 'A' FROM DUAL UNION ALL
SELECT 'C' FROM DUAL UNION ALL
SELECT 'E' FROM DUAL;

select * from apex_string.split('ORACLE','')
where column_value not in (select invalidchar from invalidcharacter);

Result Sequence
---------------
O
R
L

1 Comment

The exact deployment of this SQL would depend on the specific needs/inputs you have, but it demonstrates that it can be bundled without PL/SQL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.