STRING_SPLIT Is Not A Recognized Built-In Function Name | Fix Steps

The error means your SQL engine can’t see STRING_SPLIT, most often due to SQL Server version, database compatibility level, or calling it like a scalar.

You run a query, hit execute, and SQL Server fires back: string_split is not a recognized built-in function name. Annoying, yep. This message is SQL Server telling you it can’t bind the name STRING_SPLIT to a built-in function in the place your query is running.

Most fixes land in three buckets. You’re on an older SQL Server release. Your database is running in an older compatibility level. Or your query is calling STRING_SPLIT in the wrong shape (it returns a table, not a single value).

What This Error Means In Plain Terms

SQL Server reads your statement, resolves names, then compiles a plan. When it sees STRING_SPLIT, it checks the built-in function list that applies to the database context you’re connected to. If it can’t find it, you get the message.

This can happen on a new server if the database you’re using was restored from an older instance and kept an older compatibility level. Compatibility level is set per database, not per server. So two databases on the same server can behave differently.

This can also happen when you call STRING_SPLIT like a scalar function. It’s a table-valued function. So SELECT STRING_SPLIT('a,b', ',') is the wrong shape. You must select from it, or apply it to a rowset.

STRING_SPLIT Is Not A Recognized Built-In Function Name In SQL Server

If you want the fastest path, match your setup to the minimum requirements, then check your database settings. The table below is a quick map you can keep open in another tab while you work.

Where You Run It Minimum Level What To Verify
SQL Server 2016 (13.x) and later Database compatibility 130+ DB compatibility, correct call shape
Azure SQL Database / Managed Instance Database compatibility 130+ DB compatibility, correct call shape
SQL Server 2014 and earlier Not available Use an alternate split method

Start by checking what you are connected to and what it is running. Don’t trust the server name in Object Explorer alone.

  1. Check the current database — Run SELECT DB_NAME(); so you know the exact database your window is using.
  2. Check the server version — Run SELECT @@VERSION; and confirm you’re on SQL Server 2016 or later.
  3. Check compatibility level — Query sys.databases for the current database and confirm 130 or higher.

Use this query to check compatibility level for the database your session is using:

SELECT name, compatibility_level
FROM sys.databases
WHERE name = DB_NAME();

If the level is below 130, raise it:

ALTER DATABASE CURRENT
SET COMPATIBILITY_LEVEL = 130;

If your team keeps compatibility lower to match older query behavior, do this change through your normal release flow. Test in a non-prod database first, then roll it out in the same way you roll out other database changes.

Fixing STRING_SPLIT Not A Recognized Built-In Function Name Fast

Once version and compatibility look right, the next step is to confirm you’re using STRING_SPLIT in a way SQL Server accepts. A lot of people hit this error because they paste a snippet that calls it like a scalar.

Run this tiny demo first. It helps you separate server capability from query design.

SELECT s.value
FROM STRING_SPLIT('a,b,c', ',') AS s;

If the demo runs, the engine recognizes the function, and your original problem is in query shape or context. If the demo fails, stick with version and compatibility checks until it runs.

  • Switch to the right database — If you raised compatibility in one database but your query window is pointed at another, the error won’t change.
  • Use the table form — Always select from STRING_SPLIT or apply it with CROSS APPLY.
  • Keep the separator to one character — The separator parameter is a single character, not a multi-character token.

Correct Ways To Call STRING_SPLIT In Real Queries

STRING_SPLIT returns a rowset. That makes it great for joins, filtering, and transforming comma-separated values into rows you can work with in normal SQL.

Using it with a constant string

SELECT s.value
FROM STRING_SPLIT('red|blue|green', '|') AS s;

The output column is named value. You can alias it in the select list if you want clearer downstream code.

Splitting a column with CROSS APPLY

This is the common pattern when each row has its own delimited list.

SELECT o.OrderId, s.value AS Tag
FROM dbo.Orders AS o
CROSS APPLY STRING_SPLIT(o.TagList, ',') AS s;

Cleaning spaces and converting types

Split values often carry spaces. Clean them before converting or joining.

SELECT TRY_CONVERT(int, LTRIM(RTRIM(s.value))) AS ItemId
FROM STRING_SPLIT('10, 20, 30', ',') AS s;

If a value can’t be converted, TRY_CONVERT returns NULL. That keeps your batch running and gives you a clean way to filter bad input.

Handling order when order matters

On older releases, the output order is not guaranteed. If you need stable ordering by position, use the optional ordinal output on SQL Server 2022 (16.x) and later, or on Azure SQL Database and Managed Instance.

SELECT s.value, s.ordinal
FROM STRING_SPLIT('a,b,c', ',', 1) AS s
ORDER BY s.ordinal;

Use a literal 1 or 0 for the third argument. In SQL Server 2022, treat that flag as a constant.

When The Server Can’t Run STRING_SPLIT At All

If you’re on SQL Server 2014 or earlier, you won’t get STRING_SPLIT no matter what you do with compatibility level. In that case, you need a different method. The right choice depends on your input and how much control you have over it.

XML split that works on older SQL Server

This method converts a delimited string into a tiny XML document, then reads nodes. It’s a solid fallback when you can’t move off older versions.

DECLARE @s varchar(max) = '10,20,30';

SELECT x.n.value('.', 'int') AS ItemId
FROM (SELECT CAST('' + REPLACE(@s, ',', '') + '' AS xml) AS xm) AS d
CROSS APPLY d.xm.nodes('/i') AS x(n);

If your input can contain characters like & or <, escape them before casting to XML, or the cast can fail.

JSON array split when you have OPENJSON

OPENJSON can split a JSON array into rows and also returns an index you can use as an ordinal. This is handy when you need ordering and you can safely build the array.

DECLARE @s nvarchar(max) = N'10, 20, 30';

SELECT TRY_CONVERT(int, LTRIM(RTRIM([value]))) AS ItemId,
       CAST([index] AS int) + 1 AS Ordinal
FROM OPENJSON(N'["' + REPLACE(@s, ',', '","') + '"]')
WITH ([value] nvarchar(4000) '$') AS j
CROSS APPLY (SELECT j.[value], j.[index]) AS d;

If your SQL Server build doesn’t have OPENJSON, you’ll get a different error. Stick with the XML method in that case.

Final Checks Before You Rerun The Query

Once STRING_SPLIT works in a demo, make sure the full change is safe in your real workload. This is the part that saves you from “it worked in SSMS” surprises.

  1. Retest the failing statement — Run the exact query that failed, not only the demo snippet.
  2. Test under the same login — If a job or app user runs the code, test under that login, not only under sysadmin.
  3. Validate trimming and typing — Use LTRIM/RTRIM and TRY_CONVERT so messy input doesn’t break the batch.
  4. Set an ordering plan — Use ordinal output on SQL Server 2022+ when position matters, or pick a split method that yields an index.
  5. Guard NULL input — Decide what a NULL string should do, and handle it before calling the function.

If you still see string_split is not a recognized built-in function name after raising compatibility and checking version, confirm you altered the same database your session is using. A quick SELECT DB_NAME(); often catches the mismatch.