Close

LTRIM, RTRIM, and TRIM

The trimming functions in Oracle frequently are used by many developers; but not all know the full set of options available and how they compare to each other. Sometimes I need to remind myself so this post is as much for me as for others. I hope you find it helpful.

The LTRIM and RTRIM functions both default to removing a blanks from the left (LTRIM) or right (RTRIM) ends of the input string if that is the only parameter used. If the a second parameter is passed, then all characters within that set, regardless of order will be trimmed from their corresponding sides. Frequently, I see code with a single character for the trim option, but rarely the second and it is both a convenient and efficient means of doing so. The following examples demonstrate the various syntax and functional variations.

SELECT '>' || result || '<' result
  FROM (SELECT LTRIM('    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT LTRIM('abc.......cba', 'a') result FROM DUAL
        UNION ALL
        SELECT LTRIM('abc.......cba', 'bac') result FROM DUAL
        UNION ALL
        SELECT RTRIM('    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT RTRIM('abc.......cba', 'a') result FROM DUAL
        UNION ALL
        SELECT RTRIM('abc.......cba', 'bac') result FROM DUAL);

RESULT
-------------------
>abc.......cba    <
>bc.......cba<
>.......cba<
>    abc.......cba<
>abc.......cb<
>abc.......<

A relatively common use I find for the multi-character functionality is cleaning up DOS end-of-line sequences of carriage-return and line-feed characters. For example:

RTRIM(some_variable,chr(13)||chr(10))

TRIM, in contrast to the LTRIM and RTRIM functions, only works with a single character; but still defaults to blanks if no character is specified.
Also, rather than using a simple positional parameter, the non-default functionality is specified with a descriptive clause preceding the input string.
A LEADING clause will produce results similar to LTRIM, a TRAILING clause similar to RTRIM – but specifying only a single character to be trimmed.

Using BOTH allows for trimming a non-default character from both sides. The keyword BOTH is optional though as seen in the last two subqueries in the examples below.

SELECT '>' || result || '<' result
  FROM (SELECT TRIM('    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT TRIM(LEADING ' ' FROM '    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT TRIM(TRAILING ' ' FROM '    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT TRIM(BOTH ' ' FROM '    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT TRIM(' ' FROM '    abc.......cba    ') result FROM DUAL
        UNION ALL
        SELECT TRIM('a' FROM 'abc.......cba') result FROM DUAL);

RESULT
-------------------
>abc.......cba<
>abc.......cba    <
>    abc.......cba<
>abc.......cba<
>abc.......cba<
>bc.......cb<

Finally, if you forget the single-character limit of TRIM, Oracle will remind you explicitly of the error.

SQL> SELECT TRIM('abc' FROM 'abc.......cba') result FROM DUAL;
SELECT TRIM('abc' FROM 'abc.......cba') result FROM DUAL
       *
ERROR at line 1:
ORA-30001: trim set should have only one character

2 thoughts on “LTRIM, RTRIM, and TRIM

    1. Yes that will do the same thing as TRIM() but regexp functions are significantly slower than just using TRIM as well as consuming more cpu.

      Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
      Version 18.3.0.0.0
      
      SQL> set serveroutput on
      SQL> DECLARE
        2      v_start   TIMESTAMP WITH TIME ZONE;
        3  BEGIN
        4      v_start := SYSTIMESTAMP;
        5      FOR x IN (SELECT TRIM(word) FROM wordlist)
        6      LOOP
        7          NULL;
        8      END LOOP;
        9      DBMS_OUTPUT.put_line('trim trimmed:   ' || (SYSTIMESTAMP - v_start));
       10
       11      v_start := SYSTIMESTAMP;
       12      FOR x IN (SELECT REGEXP_REPLACE(word, '^\s*|\s*$') FROM wordlist)
       13      LOOP
       14          NULL;
       15      END LOOP;
       16      DBMS_OUTPUT.put_line('regexp trimmed: ' || (SYSTIMESTAMP - v_start));
       17
       18      v_start := SYSTIMESTAMP;
       19      FOR x IN (SELECT TRIM('    ' || word || '    ') FROM wordlist)
       20      LOOP
       21          NULL;
       22      END LOOP;
       23      DBMS_OUTPUT.put_line('trim padded:    ' || (SYSTIMESTAMP - v_start));
       24
       25      v_start := SYSTIMESTAMP;
       26      FOR x IN (SELECT REGEXP_REPLACE('    ' || word || '    ', '^\s*|\s*$') FROM wordlist)
       27      LOOP
       28          NULL;
       29      END LOOP;
       30      DBMS_OUTPUT.put_line('regexp padded:  ' || (SYSTIMESTAMP - v_start));
       31  END;
       32  /
      trim trimmed:   +000000000 00:00:00.103423000
      regexp trimmed: +000000000 00:00:00.578619000
      trim padded:    +000000000 00:00:00.115871000
      regexp padded:  +000000000 00:00:00.806902000
      
      PL/SQL procedure successfully completed.
      

Leave a Reply