LIKE is how DB2 SQL tests whether a string matches a pattern. It is not a regular expression engine: you get two wildcards, an optional ESCAPE character, and a lot of rules about nulls, blanks, mixed data, and indexes. This page covers LIKE, NOT LIKE, wildcard patterns, ESCAPE, host-variable padding, and the performance notes that keep a name search from scanning the whole tablespace.
The form is match-expression [NOT] LIKE pattern-expression [ESCAPE escape-expression]. The match expression is the string you test (usually a column). The pattern is a constant, host variable, special register, allowed scalar function, CAST, concatenation, or array element, with a documented maximum pattern length (4000 bytes). Match, pattern, and escape must all be character or graphic strings (or a mix of those) or all binary strings. Distinct types must be cast to their source type first.
| Token | Meaning |
|---|---|
| % | Zero or more characters (any length string, including empty) |
| _ | Exactly one character |
| other | That character itself (case-sensitive in Db2; no implicit UPPER) |
| ESCAPE c | c%, c_, or cc are literal %, _, or c |
123SELECT EMPNO, LASTNAME FROM DSN8C10.EMP WHERE LASTNAME LIKE '%SMITH%';
IBM’s example: this predicate is true when NAME is SMITH, NESMITH, SMITHSON, or NESMITHY. It is not true for SMYTHE—the letters must match the non-wildcard parts exactly. Db2 LIKE is not case-insensitive. If data is stored in mixed case, either store a search column in a consistent case or apply a function (knowing that UPPER(LASTNAME) LIKE 'SMITH%' may not match an index on LASTNAME).
Redundant percents do not change the meaning: AB%%%%CD is equivalent to AB%CD.
12345678-- Prefix WHERE LASTNAME LIKE 'JO%' -- One wildcard character WHERE LASTNAME LIKE 'JO_ES' -- Contains (watch the access path) WHERE LASTNAME LIKE '%BERG%';
m NOT LIKE p is equivalent to NOT (m LIKE p). Rows that clearly fail the pattern are kept. Rows where LIKE is UNKNOWN (null column or null pattern) stay UNKNOWN, so WHERE still drops them.
123SELECT EMPNO, LASTNAME FROM DSN8C10.EMP WHERE LASTNAME NOT LIKE 'A%';
That keeps non-null last names that do not start with A. Null last names do not appear. NOT LIKE is typically not a matching index predicate. If you need “not starting with A” and the table is large, compare EXPLAIN with a range (LASTNAME < 'A' OR LASTNAME >= 'B' in the encoding you actually use—EBCDIC letter order is tricky) versus NOT LIKE.
When the data itself contains % or _, those characters in the pattern would be wildcards unless you escape them. ESCAPE escape-expression names a single character (one SBCS or DBCS character, or one byte for binary). In the pattern, that character may appear only as:
Any other use of the escape character in the pattern is an error. IBM’s table with escape +:
| Pattern string | Actual pattern |
|---|---|
| +% | A percent sign |
| ++% | A plus sign followed by zero or more arbitrary characters |
| +++% | A plus sign followed by a percent sign |
12345-- Host variable PATTERN contains: AB+_C_% -- Escape is + so +_ is a literal underscore SELECT EMPNO, LASTNAME FROM DSN8C10.EMP WHERE LASTNAME LIKE :PATTERN ESCAPE '+';
IBM’s walkthrough: if PATTERN is AB+_C_%, the predicate is true for AB_CD or AB_CDE, and false for AB, AB_, or AB_C. The first underscore is literal because of +; the second underscore is a wildcard; % eats the rest.
ESCAPE is not allowed when the match expression is mixed ASCII/EBCDIC data. Unicode mixed (UTF-8) may use ESCAPE. If you search mixed EBCDIC columns for a literal %, you may need a different technique (LOCATE, POSSTR, or a generated column) rather than ESCAPE.
If the pattern lives in a fixed-length host variable or parameter marker, trailing blanks are part of the pattern. IBM’s warning: CHAR(10) set to 'WYSE%' becomes 'WYSE% ' (percent plus five blanks). You then search for values that start with WYSE and end with five blanks, unless LIKE blank-insignificant behavior is in effect. That is not a prefix search.
Fixes:
Pattern expressions built with concatenation are allowed. Keep the result within 4000 bytes. Do not concatenate unsanitized user text into dynamic SQL; use a host variable for the pattern and keep the statement text static so the cache can reuse it.
For mixed ASCII/EBCDIC data, an SBCS underscore matches one SBCS character, a DBCS underscore matches one MBCS character, and either percent matches zero or more SBCS or MBCS characters. EBCDIC redundant shift bytes are ignored. For Unicode, underscore matches one character and percent matches a string of characters; full-width and half-width % and _ have documented code points (UTF-8 / UTF-16).
Binary LIKE uses bytes. The special bytes are the binary percent and underscore, not the character glyphs you type in a CHAR pattern. Use BX constants when the column is BINARY / VARBINARY / BLOB.
Subsystem parameter LIKE_BLANK_INSIGNIFICANT changes how trailing blanks in CHAR/GRAPHIC columns are treated before LIKE. When it is enabled, trailing blanks in column data can be stripped before matching, while trailing blanks in the pattern remain significant. If your shop enables it, existing CHECK constraints that use LIKE may need CHECK DATA. Ask before you assume CHAR comparison matches VARCHAR the way a PC database would.
Predicate-processing tables in the performance manuals classify LIKE roughly like this (details depend on release and pattern):
Practical habits:
LIKE is matching stickers to a template. A blank square with a percent sign means “any bunch of letters, even none.” A single underscore square means “exactly one mystery letter.” If you need to find a sticker that actually has a percent sign drawn on it, you whisper a secret escape letter first so the percent is just ink, not a magic square. Searching for “starts with SAM” is like looking in the S drawer. Searching for “ends with SON” means opening every drawer. NOT LIKE is “does not match this template,” and a sticker with the name torn off (NULL) is not a yes.
For a pattern with no wildcards, LIKE still follows LIKE matching and CHAR padding rules, which can differ from equality on trailing blanks. Prefer = when you mean exact equality. Use LIKE only when you need wildcards.
The pattern is an expression, not a fullselect. If the pattern comes from a table, join to that table or assign the pattern to a host variable. A scalar subquery that returns one string can be an expression in some contexts; keep it to one row or you will get a scalar subquery error.
Character large objects can participate in string predicates with restrictions and often without useful indexes. For large text search, LIKE '%term%' on a CLOB is a last resort. Prefer designed search tables or functions documented for LOBs.
1. What does the percent sign mean in a LIKE pattern?
2. How do you match a literal percent sign in the data?
3. NAME LIKE '%SMITH%' is true for which of these?
4. Why can LIKE :HV fail when HV is CHAR(10) and you assigned 'WYSE%'?
5. Which LIKE pattern is typically index-friendly on LASTNAME?