BuildRowSetFromString
Splits a delimited string into a single-column rowset. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including the unnamed column and the empty separator that splits nothing.
Syntax
BuildRowSetFromString(sourceData, delimiter) → rowset
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sourceData |
string | Yes | The delimited string to split into rows |
delimiter |
string | Yes | The separator to split on, one or more characters long |
Example
%%[
VAR @rows
SET @rows = BuildRowSetFromString("North**South**East**West", "**")
]%%
Rows: %%=v(RowCount(@rows))=%% first: %%=v(Field(Row(@rows, 1), 1))=%%
Renders Rows: 4 first: North.
Because an empty or unset input produces a rowset with no rows rather than a value you can test, guard the read with RowCount before touching a row:
%%[
VAR @rows, @i
SET @rows = BuildRowSetFromString(@csv, ",")
FOR @i = 1 TO RowCount(@rows) DO
]%%
<li>%%=v(Field(Row(@rows, @i), 1))=%%</li>
%%[ NEXT @i ]%%
Return value
rowset — one row per segment of the input string, in source order.
There is no closed set of sentinel values: an empty source string and an unset variable both produce a rowset of zero rows, so RowCount is the only value worth branching on.
Behaviour
Each segment becomes one row, in source order. Splitting a four-region string on a two-character separator produced four rows whose first and fourth rows read North and West. A different two-character separator behaves the same way: a::b::c split on :: gave three rows whose second row read b.
The single column has no name, but answers to Value. Read it by ordinal 1; reading the first row of a,b,c as Value with the three-argument Field form also returned a.
A trailing separator adds a final empty row. The input a,b, gave three rows, the last of which read empty — it is not trimmed away.
Input without the separator yields exactly one row. NoDelimiterHere split on a comma gave one row holding the whole input.
An empty separator splits nothing. a,b,c with an empty separator gave a single row rather than one row per character. Both edge cases are catalogued on Differs from official docs.
Rowsets are read 1-based. Row(rowset, 0) and Field(row, 0) both abort the page. RowCount never aborts and returns 0 for an empty rowset.
Either capitalisation resolves to the same function. BuildRowsetFromString with a lowercase s produced identical results.
Show test script
%%[
VAR @b, @unset, @rows
SET @b = RequestParameter("b")
/* control branch: proves the page itself renders */
IF @b == "zzz" THEN
OutputLine(Concat("CTRL=[alive]"))
ENDIF
/* multi-character separator, source order, ordinal 1 */
IF @b == "safe" THEN
SET @rows = BuildRowSetFromString("North**South**East**West", "**")
OutputLine(Concat("s1 rc=[", RowCount(@rows), "]"))
OutputLine(Concat("s1 r1 ord1=[", Field(Row(@rows, 1), 1), "] r4 ord1=[", Field(Row(@rows, 4), 1), "]"))
OutputLine(Concat("s12 multichar rc=[", RowCount(BuildRowSetFromString("a::b::c", "::")), "] r2=[", Field(Row(BuildRowSetFromString("a::b::c", "::"), 2), 1), "]"))
ENDIF
/* separator edge cases and empty inputs */
IF @b == "edges" THEN
SET @rows = BuildRowSetFromString("a,b,", ",")
OutputLine(Concat("s2 trailingdelim rc=[", RowCount(@rows), "] r3=[", Field(Row(@rows, 3), 1), "]"))
SET @rows = BuildRowSetFromString("NoDelimiterHere", ",")
OutputLine(Concat("s3 nodelim rc=[", RowCount(@rows), "] r1=[", Field(Row(@rows, 1), 1), "]"))
OutputLine(Concat("s4 emptysource rc=[", RowCount(BuildRowSetFromString("", ",")), "]"))
OutputLine(Concat("s13 unsetvar rc=[", RowCount(BuildRowSetFromString(@unset, ",")), "]"))
OutputLine(Concat("s5 emptydelim rc=[", RowCount(BuildRowSetFromString("a,b,c", "")), "]"))
ENDIF
/* the unnamed column also answers to the name Value */
IF @b == "byname" THEN
SET @rows = BuildRowSetFromString("a,b,c", ",")
OutputLine(Concat("s6 byname-Value=[", Field(Row(@rows, 1), "Value", 0), "]"))
ENDIF
/* the alternate capitalisation resolves to the same function */
IF @b == "casing" THEN
OutputLine(Concat("s11 lowercase-s-casing rc=[", RowCount(BuildRowsetFromString("a,b,c", ",")), "]"))
ENDIF
/* fetch ?b=abortord0 - HTTP 422, ordinals are 1-based */
IF @b == "abortord0" THEN
OutputLine(Concat("--- s7 start ---"))
SET @rows = BuildRowSetFromString("a,b,c", ",")
OutputLine(Concat("s7 ord0=[", Field(Row(@rows, 1), 0), "]"))
ENDIF
/* fetch ?b=abortrow0 - HTTP 422, row indexing is 1-based */
IF @b == "abortrow0" THEN
OutputLine(Concat("--- s8 start ---"))
SET @rows = BuildRowSetFromString("a,b,c", ",")
OutputLine(Concat("s8 row0=[", Field(Row(@rows, 0), 1), "]"))
ENDIF
]%%
OutputLine given a bare string literal renders an empty line. Wrap the argument in Concat() or your start and done markers vanish silently — which looks exactly like the function failing.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | No |
See also
- Differs from official docs — the separator edge cases in full
BuildRowsetFromJSON·BuildRowSetFromXML— the same rowset shape for structured payloads- Official reference · ampscript.guide