It's been a long while since this question was asked, and although the OP wanted a non-function solution, this is the only post where the answer pointed me in the right direction for me to write my code, so I thought I'd share my solution here.
What it does
This code, checks the master db compatibility mode and creates an appropriate _my_string_split function. If string_split exists, this is just a wrapper.
If not it will use the method Stan proposed in the accepted answer
So now, regardless of where I'm running my code, after creating the function, all I need to do is use master.dbo._my_string_split, for example:
SELECT * FROM master.dbo._my_string_split('Hello|World!','|')
The Code
USE master
IF OBJECT_ID('dbo._my_string_split') IS NOT NULL DROP FUNCTION [dbo].[_my_string_split]
GO
DECLARE @sqlCode NVARCHAR(MAX);
IF 130 <= (SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME())
SET @sqlCode = '
--- 130+ string_split exists
CREATE FUNCTION [dbo].[_my_string_split]
(
@string nvarchar(max),
@separator nvarchar(1)
)
RETURNS
@result TABLE ([Value] nvarchar(max) )
BEGIN
INSERT INTO @result
SELECT [Value] FROM string_split(@string,@separator)
RETURN
END
'
ELSE
SET @sqlCode = '
--- before 130: string_split does not exists
CREATE FUNCTION [dbo].[_my_string_split]
(
@string nvarchar(max),
@separator nvarchar(1)
)
RETURNS
@result TABLE ([Value] nvarchar(max) )
BEGIN
INSERT INTO @result
SELECT [Value]=t.value(''.'', ''varchar(max)'')
FROM (SELECT x=(CAST((''<A>'' + REPLACE(@string, @separator, ''</A><A>'') + ''</A>'') AS XML))) a
CROSS APPLY a.x.nodes(''/A'') AS x(t)
RETURN
END
'
PRINT @sqlCode
EXEC sp_sqlexec @sqlCode
Hope others will find this useful.