У меня есть некоторые данные в столбце FileFullPath
Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\Oracle\2022-05-04\MSudaitemlov_20220503
Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OracleABC\2022-05-04\FDERDMSudaitemlov_20220503
Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OCSBAGF\2022-05-04\AASSSMSudaitemlov_20220503
Часть, которую я хотел, это:
Oracle
OracleABC
OCSBAGF
Буквы dynamic
, поэтому я не смог применить функцию Left,Right
, так как длина другая. Я попытался разделить его с помощью '\'
с помощью STRING_SPLIT()
, но он говорит:
Msg 195, Level 15, State 10, Line 18
'string_split' is not a recognized built-in function name.
Отвечает ли это на ваш вопрос? Используя T-SQL, верните n-й элемент с разделителями из строки
это версия 18.9.1
SQL Server 18.9.1 не существует; последняя версия SQL Server — 15.0.4223.1, то есть SQL Server 2019 CU 16.
это Microsoft SQL Server 2016
STRING_SPLIT
был добавлен в SQL Server 2016, поэтому вы сможете его использовать. Хотя, по правде говоря, вам это не поможет, поскольку он не обеспечивает порядкового номера. Хотя я связал вас с вопросом о том, как вы можете получить n-е значение.
Я не могу визуализировать ссылку, которую вы разместили @Larnu
Он разбивается на разные строки, но мне нужна только извлеченная часть для каждой из строк.
Так как же узнать, какая часть вам нужна? И, что более важно, откуда SQL Server знает?
Если мы ищем закономерность, есть ли она? Глядя с конца обратного слова, всегда ли строка имеет имя, дату, а затем строковое значение, которое вы хотите? Если вы перевернете строку, вы можете разделить ее с помощью функции, которая предоставляет позицию, а затем просто взять третью часть. А разбиение строк - САМЫЙ РАСПРОСТРАНЕННЫЙ вопрос - было опубликовано множество функций, которые работают во всех версиях сервера sql.
Вы должны иметь возможность использовать STRING_SPLIT()
в SQL Server 2016, за исключением двух сценариев:
SELECT STRING_SPLIT(...
), а не как функцию с табличным значением (SELECT * FROM STRING_SPLIT(...
). Он возвращает таблицу, поэтому вы должны обращаться с ней как с таблицей.STRING_SPLIT()
все равно не решит эту проблему...... потому что порядок вывода не гарантируется, поэтому вы никогда не сможете надежно определить, какой элемент является третьим от последнего.
Беззастенчиво позаимствовав мою работу в Эта статья, вы можете создать следующую простую функцию:
CREATE FUNCTION dbo.SplitOrdered_JSON
(
@List nvarchar(4000),
@Delimiter nvarchar(255)
)
RETURNS table WITH SCHEMABINDING
AS
RETURN
(
SELECT [key], value FROM OPENJSON
(
CONCAT
(
N'["',
REPLACE(STRING_ESCAPE(@List, 'JSON'),
@Delimiter, N'","'),
N'"]')
) AS x
);
Затем, если вам нужен 3-й последний элемент в строке, вы можете просто изменить его перед синтаксическим анализом, а затем снова изменить после синтаксического анализа. например
CREATE TABLE #f(ID int, FullFilePath nvarchar(4000));
INSERT #f VALUES
(1,N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\Oracle\2022-05-04\MSudaitemlov_20220503'),
(2,N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OracleABC\2022-05-04\FDERDMSudaitemlov_20220503'),
(3,N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OCSBAGF\2022-05-04\AASSSMSudaitemlov_20220503');
DECLARE @ElementOfInterest int = 3;
SELECT REVERSE(value)
FROM #f CROSS APPLY dbo.SplitOrdered_JSON(REVERSE(FullFilePath), N'\')
WHERE [key] = @ElementOfInterest - 1;
Вот еще одно решение для полного покрытия.
Он будет работать, начиная с SQL Server 2012 и далее.
Он использует XML и XQuery для токенизации. Нет необходимости в каких-либо определяемых пользователем функциях (UDF).
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, FullFilePath nvarchar(4000));
INSERT INTO @tbl (FullFilePath) VALUES
(N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\Oracle\2022-05-04\MSudaitemlov_20220503'),
(N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OracleABC\2022-05-04\FDERDMSudaitemlov_20220503'),
(N'Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OCSBAGF\2022-05-04\AASSSMSudaitemlov_20220503');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = '\'
, @token int = 8;
SELECT t.*
, c.value('(/root/r[sql:variable("@token")]/text())[1]', 'NVARCHAR(20)')
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' +
REPLACE(FullFilePath, @separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c);
Выход
+----+--------------------------------------------------------------------------------------------------------+------------------+
| ID | FullFilePath | (No column name) |
+----+--------------------------------------------------------------------------------------------------------+------------------+
| 1 | Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\Oracle\2022-05-04\MSudaitemlov_20220503 | Oracle |
| 2 | Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OracleABC\2022-05-04\FDERDMSudaitemlov_20220503 | OracleABC |
| 3 | Y:\dfs-dc-01\Split\Retail\Kroger\Kroger\FTP-FromClient\OCSBAGF\2022-05-04\AASSSMSudaitemlov_20220503 | OCSBAGF |
+----+--------------------------------------------------------------------------------------------------------+------------------+
Что ж, вам также не «нужен» UDF для решения JSON, но он, безусловно, делает запрос более аккуратным (без снижения производительности), поэтому не уверен, зачем его устранять.
Я согласен. Модель данных XML основана на упорядоченных последовательностях. Модель данных JSON основана на массивах. Так что они оба идеально подходят для таких задач. Хотя у JSON нет реальных API, таких как XPath. XQuery и проверка XSD.
Какую версию SQL Server вы используете? Если
STRING_SPLIT
не распознается, вы используете SQL Server 2014 или более раннюю версию.