Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Използвайки T-SQL, върнете n-ти разделен елемент от низ

Това е най-лесният отговор за възстановяване на 67 (тип-безопасен!! ):

SELECT CAST('<x>' + REPLACE('1,222,2,67,888,1111',',','</x><x>') + '</x>' AS XML).value('/x[4]','int')

По-долу ще намерите примери как да използвате това с променливи за низа, разделителя и позицията (дори за крайни случаи със забранени от XML знаци)

Лесният

Този въпросне е за подход за разделяне на низ , но закак да получите n-тия елемент . Най-лесният, напълно интегриран начин би бил този IMO:

Това е единистинско едноредово за да получите част 2, разделена с интервал:

DECLARE @input NVARCHAR(100)=N'part1 part2 part3';
SELECT CAST(N'<x>' + REPLACE(@input,N' ',N'</x><x>') + N'</x>' AS XML).value('/x[2]','nvarchar(max)')

Променливите могат да се използват с sql:variable() или sql:column()

Разбира се можете да използвате променливи за разделител и позиция (използвайте sql:column за да извлечете позицията директно от стойността на заявка):

DECLARE @dlmt NVARCHAR(10)=N' ';
DECLARE @pos INT = 2;
SELECT CAST(N'<x>' + REPLACE(@input,@dlmt,N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)')

Edge-Case с XML-забранени знаци

Ако низът ви може да включва забранени знаци , все още можете да го направите по този начин. Просто използвайте FOR XML PATH първо в низа си, за да замените имплицитно всички забранени знаци с подходящата escape последователност.

Това е много специален случай, ако - освен това - вашият разделител е точка и запетая . В този случай първо замествам разделителя на „#DLMT#“ и накрая заменям това с XML таговете:

SET @input=N'Some <, > and &;Other äöü@€;One more';
SET @dlmt=N';';
SELECT CAST(N'<x>' + REPLACE((SELECT REPLACE(@input,@dlmt,'#DLMT#') AS [*] FOR XML PATH('')),N'#DLMT#',N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)');

АКТУАЛИЗИРАНЕ за SQL-Server 2016+

За съжаление разработчиците забравиха да върнат индекса на частта с STRING_SPLIT . Но при използване на SQL-Server 2016+ има JSON_VALUE и OPENJSON .

С JSON_VALUE можем да предадем позиция като индексен масив.

За OPENJSON в документацията е посочено ясно:

Когато OPENJSON анализира JSON масив, функцията връща индексите на елементите в JSON текста като ключове.

Низ като 1,2,3 не се нуждае от нищо повече от скоби:[1,2,3] .
Низ от думи като this is an example трябва да бъде ["this","is","an"," example"] .
Това са много лесни операции с низове. Просто го изпробвайте:

DECLARE @str VARCHAR(100)='Hello John Smith';
DECLARE @position INT = 2;

--We can build the json-path '$[1]' using CONCAT
SELECT JSON_VALUE('["' + REPLACE(@str,' ','","') + '"]',CONCAT('$[',@position-1,']'));

--Вижте това за безопасен за позиция разделител на низове (на база нула ):

SELECT  JsonArray.[key] AS [Position]
       ,JsonArray.[value] AS [Part]
FROM OPENJSON('["' + REPLACE(@str,' ','","') + '"]') JsonArray

В тази публикация тествах различни подходи и открих, че OPENJSON е наистина бързо. Дори много по-бързо от известния метод "delimitedSplit8k()"...

АКТУАЛИЗАЦИЯ 2 – Вземете стойностите, безопасни за типа

Можем да използваме масив в масив просто като използвате удвоен [[]] . Това позволява въведено WITH -клауза:

DECLARE  @SomeDelimitedString VARCHAR(100)='part1|1|20190920';

DECLARE @JsonArray NVARCHAR(MAX)=CONCAT('[["',REPLACE(@SomeDelimitedString,'|','","'),'"]]');

SELECT @SomeDelimitedString          AS TheOriginal
      ,@JsonArray                    AS TransformedToJSON
      ,ValuesFromTheArray.*
FROM OPENJSON(@JsonArray)
WITH(TheFirstFragment VARCHAR(100) '$[0]'
    ,TheSecondFragment INT '$[1]'
    ,TheThirdFragment DATE '$[2]') ValuesFromTheArray


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server - Как да заключите таблица, докато съхранената процедура приключи

  2. Работа с данни на Salesforce.com в SQL Server Reporting Services

  3. Създайте задание за агент на SQL Server в Azure Data Studio

  4. Как да разделя низ, за ​​да мога да получа достъп до елемент x?

  5. Изберете стойности от полето XML в SQL Server 2008