21. String Functions -- Manipulating Text in SQL Server
Level: Beginner
- LEN -- string length
- SUBSTRING, LEFT, RIGHT -- extract parts
- UPPER, LOWER -- case conversion
- REPLACE -- find and replace text
- TRIM, LTRIM, RTRIM -- remove spaces
- CONCAT -- join strings
- CHARINDEX, PATINDEX -- find position
- Common string mistakes
- Best practices
Query data as-is. APIs transform text. String functions manipulate in database. This article teaches text operations for reporting and display.
Why String Functions Matter for Backend Developers
APIs need formatted data:
Frontend asks: "Display student initials and class level"
v
Backend needs:
- Extract initials from Name (Ravi Kumar -> R.K.)
- Extract class number from ClassName (10-A -> 10)
v
String functions transform in SQL
v
Return formatted data to frontend
Transform text in database, not backend code.
String Function Reference
LEN(string) -> Length
SUBSTRING(string, start, len) -> Extract part
LEFT(string, n) -> First n chars
RIGHT(string, n) -> Last n chars
UPPER(string) -> Uppercase
LOWER(string) -> Lowercase
REPLACE(string, old, new) -> Find/replace
LTRIM(string) -> Remove left spaces
RTRIM(string) -> Remove right spaces
TRIM(string) -> Remove both sides
CONCAT(str1, str2, ...) -> Join strings
CHARINDEX(find, string) -> Position
Example 1: Extract Student Initials
Get student initials:
SELECT
Name AS FullName,
LEFT(Name, 1) + '.' +
SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 1) + '.' AS Initials
FROM Student;
Result (initials):
FullName | Initials
Ravi Kumar | R.K.
Priya Sharma | P.S.
Arjun Reddy | A.R.
LEFT: First char. CHARINDEX: Find space position. SUBSTRING: First char after space.
Example 2: Extract Class Number
Get class level from class name:
SELECT
ClassName,
LEFT(ClassName, CHARINDEX('-', ClassName) - 1) AS ClassLevel,
RIGHT(ClassName, 1) AS Section
FROM Class;
Result (class parts):
ClassName | ClassLevel | Section
10-A | 10 | A
10-B | 10 | B
11-A | 11 | A
CHARINDEX finds hyphen. LEFT extracts before it. RIGHT gets last char.
Example 3: Search Names (LIKE vs CHARINDEX)
Find all students with "Kumar" in name:
SELECT
StudentId,
Name
FROM Student
WHERE CHARINDEX('Kumar', Name) > 0;
Result (Kumar students):
StudentId | Name
1 | Ravi Kumar
5 | Ashok Kumar
CHARINDEX > 0: Found. = 0: Not found.
Alternative with LIKE:
WHERE Name LIKE '%Kumar%';
Both work. CHARINDEX more explicit.
Example 4: Format Names (Case conversion)
Display formatted names:
SELECT
StudentId,
UPPER(Name) AS NameUpper,
LOWER(Name) AS NameLower,
UPPER(LEFT(Name, 1)) + LOWER(SUBSTRING(Name, 2, LEN(Name))) AS ProperCase
FROM Student;
Result (formatted):
StudentId | NameUpper | NameLower | ProperCase
1 | RAVI KUMAR | ravi kumar | Ravi kumar
2 | PRIYA SHARMA| priya sharma| Priya sharma
UPPER/LOWER transform. Combine to create proper case formatting.
Example 5: REPLACE -- Fix Data
Replace typo in subject names:
UPDATE Subject
SET Name = REPLACE(Name, 'Phisics', 'Physics');
SELECT Name FROM Subject;
Result (corrected):
Name
Physics
Chemistry
English
REPLACE finds "Phisics", replaces with "Physics".
Example 6: CONCAT -- Build Strings
Create full address:
SELECT
Name,
CONCAT(Address, ', ', City, ', ', State, ' - ', PinCode) AS FullAddress
FROM School;
Result (concatenated):
Name | FullAddress
NexCoding Academy | 123 Main St, Bangalore, Karnataka - 560001
CONCAT joins strings with delimiters.
Alternative (+ operator):
SELECT
Name,
Address + ', ' + City + ', ' + State + ' - ' + PinCode AS FullAddress
FROM School;
Same result. CONCAT safer with NULL (treats as empty).
Example 7: TRIM -- Clean Data
Remove extra spaces:
SELECT
Name,
TRIM(Name) AS NameTrimmed,
LEN(Name) AS OriginalLen,
LEN(TRIM(Name)) AS TrimmedLen
FROM Student;
Result (spaces removed):
Name | NameTrimmed | OriginalLen | TrimmedLen
" Ravi " | Ravi | 9 | 4
"Priya " | Priya | 6 | 5
TRIM removes leading/trailing spaces. LTRIM: left only. RTRIM: right only.
Example 8: String Validation
Check email format:
SELECT
Email,
CASE
WHEN CHARINDEX('@', Email) > 0
AND CHARINDEX('.', Email, CHARINDEX('@', Email)) > 0
THEN 'Valid'
ELSE 'Invalid'
END AS EmailStatus
FROM User;
Result (validation):
Email | EmailStatus
nagarjuna.thota@outlook.com | Valid
invalid.email.com | Invalid
Check @ exists and . after @. Basic validation.
Common String Function Mistakes
Mistake 1: Ignoring NULL in string functions
Wrong:
SELECT CONCAT(FirstName, ' ', LastName) FROM User;
-- If LastName is NULL: result is NULL (CONCAT ignores NULLs)
Result: NULL instead of partial name.
Fix: Handle NULL:
SELECT
CONCAT(FirstName, ' ', ISNULL(LastName, '')) AS FullName
FROM User;
Or use + (must ISNULL both):
SELECT
ISNULL(FirstName, '') + ' ' + ISNULL(LastName, '') AS FullName
FROM User;
Mistake 2: SUBSTRING with wrong position (1-based, not 0)
Wrong:
SELECT SUBSTRING('Ravi Kumar', 0, 4);
-- Expected: 'Ravi'
-- Actual: 'Rav' (position 0 treated as 1)
Result: Off-by-one error.
Fix: Use 1-based indexing:
SELECT SUBSTRING('Ravi Kumar', 1, 4); -- Correct: 'Ravi'
SQL uses 1-based indexing, not 0-based like programming languages.
Mistake 3: CHARINDEX returns 0 if not found
Wrong:
SELECT CHARINDEX('X', 'Ravi Kumar');
-- Returns 0 (not found)
WHERE CHARINDEX('Kumar', Name) = 1;
-- Always false: first char never contains 'Kumar'
Result: Logic error.
Fix: Compare > 0:
WHERE CHARINDEX('Kumar', Name) > 0; -- Correct: found
Mistake 4: LEN doesn't count trailing spaces
Wrong:
SELECT LEN('Ravi ');
-- Returns 4 (trailing spaces ignored)
-- Need to RTRIM to see actual string
Result: Hidden trailing spaces.
Fix: Use DATALENGTH if spaces matter:
SELECT DATALENGTH('Ravi '); -- Returns 6 (with spaces)
Or TRIM first:
SELECT LEN(TRIM('Ravi ')); -- Returns 4 (clean)
Mistake 5: Performance -- string functions on large datasets
Wrong:
SELECT * FROM Student
WHERE SUBSTRING(ClassName, 1, 2) = '10';
-- Function on every row, can't use index
Result: Table scan, slow on 1M rows.
Fix: Avoid functions in WHERE if possible:
WHERE ClassName LIKE '10%';
-- Can use index on ClassName
Best Practices for String Functions
- Use CONCAT for multiple strings -- Handles NULL better
- TRIM incoming data -- Clean on insert, not query
- Use LIKE for pattern matching -- Easier to read than CHARINDEX
- 1-based indexing in SUBSTRING -- Start at 1, not 0
- Handle NULL explicitly -- Don't assume CONCAT does
- Avoid functions in WHERE on indexed columns -- Use LIKE instead
- Test with sample data -- String functions error-prone
SUBSTRING: Extract from any position.
SUBSTRING('Ravi Kumar', 6, 5) -- Returns 'Kumar'
LEFT: Extract first N chars only.
LEFT('Ravi Kumar', 4) -- Returns 'Ravi'
Use LEFT for prefix. SUBSTRING for specific range.
+ operator: NULL breaks chain.
'Ravi' + ' ' + NULL + ' Kumar' -- Returns NULL (entire result)
CONCAT: NULL ignored.
CONCAT('Ravi', ' ', NULL, ' Kumar') -- Returns 'Ravi Kumar'
CONCAT safer with possible NULL values.
Find @ position, extract after:
SELECT
Email,
SUBSTRING(Email, CHARINDEX('@', Email) + 1, LEN(Email)) AS Domain
FROM User;
Result:
Email | Domain
nagarjuna@outlook.com | outlook.com
ravi@gmail.com | gmail.com
CHARINDEX finds @. SUBSTRING extracts after (+1).
LIKE: Pattern matching (wildcards).
WHERE Name LIKE '%Kumar%' -- Contains Kumar
WHERE ClassName LIKE '10%' -- Starts with 10
CHARINDEX: Find exact substring position.
WHERE CHARINDEX('Kumar', Name) > 0 -- Contains Kumar
LIKE more readable. CHARINDEX returns position (useful for extraction).
Capitalize first letter, lowercase rest:
SELECT
UPPER(LEFT(Name, 1)) + LOWER(SUBSTRING(Name, 2, LEN(Name))) AS ProperCase
FROM Student;
Result:
ProperCase
Ravi
Priya
Arjun
Combine UPPER, LEFT, LOWER, SUBSTRING.
Note: SQL Server has no built-in proper case function.
Functions prevent index use:
WHERE LEFT(ClassName, 2) = '10' -- Table scan
SQL can't use ClassName index (function applied to each row).
Better:
WHERE ClassName LIKE '10%' -- Can use index
LIKE pattern: SQL optimizer uses index effectively.
Use ChatGPT, Claude, or Copilot to go deeper on String functions for text manipulation in SQL Server. Try these prompts:
"Show how to extract student initials using SUBSTRING and CHARINDEX""What's the difference between SUBSTRING, LEFT, and RIGHT?""How do I use REPLACE to fix data in a column?""How do I validate email format using string functions?""Quiz me: ask 5 questions about string functions, CONCAT, CHARINDEX"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.