STRING_SPLIT#
Splits a string into rows of substrings at a single-character separator. Use it in the FROM clause
to turn a delimited list into a table, or with CROSS APPLY to split a column of each row.
Syntax#
STRING_SPLIT ( string , separator [ , enable_ordinal ] )
Arguments#
string
The string to split: an expression of type char, nchar, varchar, nvarchar or sysname - a literal, a variable, a column, or any expression over them.
separator
A single character that separates the substrings, typed char(1), nchar(1), varchar(1) or nvarchar(1). A separator whose type is longer than one character is refused, even when its value is one character long.
enable_ordinal
Optional. A constant 1 adds an ordinal column that numbers the substrings; 0 or an omitted
argument returns the value column only. The argument must be a constant: a variable or an
expression is refused.
Return value#
Column name |
Data type |
Description |
|---|---|---|
|
the type of string |
One substring per row: nvarchar when string or separator is Unicode, otherwise
varchar, of the same length as string; sysname gives a length of 128 and an untyped
|
|
bigint NOT NULL |
The one-based position of the substring in the input. Present only when enable_ordinal is
|
The rows come back in no particular order. Use ORDER BY ordinal when the input order matters.
Remarks#
A NULL string yields no rows. Under CROSS APPLY the driving row disappears; under OUTER APPLY
it is kept, with NULL in the function’s columns. A NULL separator is an error (214), whether it is
written as NULL or arrives through a variable or a column.
An empty string yields one empty substring, and adjacent separators, or a separator at either end,
yield empty substrings: STRING_SPLIT(',a,,b,', ',') returns five rows. Trailing blanks of a
char input are part of the last substring.
A column argument requires APPLY. CROSS APPLY STRING_SPLIT(t.tags, ',') splits each row’s
value. Referencing another table’s column from a plain join, or from a comma-separated FROM list,
is refused with error 4104, as SQL Server refuses it.
Where the split is evaluated#
In a database backed by SQL Server, the source runs the function when the dialect version of its connection has it, and otherwise Querona splits the strings itself. When the source cannot run it under
APPLYwith an argument from another table, the default federator renders theAPPLYwhen its dialect version has the function; when it does not, or external federation is off, Querona splits the strings once per driving row. It does so only when the call is the whole right side ofAPPLY: a query on the right side that reads the other table and callsSTRING_SPLIT- a derived table such asCROSS APPLY (SELECT TOP (1) value FROM STRING_SPLIT(c.ContactName, ' ') ORDER BY value), or an inline function whose body calls it - is refused with a message that names the function. Set the dialect version of the connection to the version of the server to have the server run it.Anywhere else, the rows come from wherever the query runs: a SQL Server source or the default federator renders
STRING_SPLITwhen the query reaches one whose dialect version has it, and otherwise Querona splits the strings itself - once per driving row when the argument comes from another table underAPPLY.
Which dialect version of a SQL Server connection has the function:
Dialect version |
Without enable_ordinal |
With enable_ordinal |
|---|---|---|
SQL Server (no version), SQL Server 2014 |
No |
No |
SQL Server 2016, 2017, 2019 |
Yes |
No |
SQL Server 2022, 2025 |
Yes |
Yes |
Azure SQL Data Warehouse |
Yes |
No |
The dialect version is part of the connection settings. Set it to the version of the server so that the
server runs every call it can. The generic SQL Server version does not assume the server has
STRING_SPLIT, because a SQL Server 2014 or older server does not.
Note
SQL Server finds STRING_SPLIT only in a database whose compatibility level is 130 or higher; at a
lower level it answers error 208 “Invalid object name ‘STRING_SPLIT’”, whatever its version. Querona
does not read the compatibility level of the source database, so a source database below level 130
needs a dialect version that does not have the function, such as SQL Server 2014.
Note
When Querona splits the string itself, it matches the separator character by character, exactly.
SQL Server matches it under the collation of the string, so under a case-insensitive collation
STRING_SPLIT('aXb', 'x') returns a and b on SQL Server and the whole string here.
See Feature support for other differences.
Examples#
A delimited list as a table:
SELECT value FROM STRING_SPLIT('red,green,blue', ',') ORDER BY value;
Keeping the input order:
SELECT value, ordinal FROM STRING_SPLIT('x,y,z', ',', 1) ORDER BY ordinal;
Splitting a column of every row, keeping rows whose column is NULL:
SELECT c.CustomerID, s.value AS word
FROM dbo.Customers c
OUTER APPLY STRING_SPLIT(c.Region, ' ') s
ORDER BY c.CustomerID, s.value;