2016-11-04 2 views
0

Привет, я новичок в переполнении стека, хотя я использовал этот сайт для поиска ответов в течение многих лет. Поэтому у меня есть эта проблема, чтобы извлечь различные и конкретные детали из очень длинной строки. Проблема в том, что строки не статичны и не имеют фиксированного индекса, поэтому я не могу использовать функцию подстроки. Пример вывода строки такой.Извлечение Конкретные слова из динамического источника строки

Sample 1: 
1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400 

Sample 2: 
1 AJ 2552 O 10/8/2016 0:0:0 6 PSI KTL 0 GK 2 10/28/2016 7:0:0 9/28/2016 8:5:0 O20YEARS 32.2400 

Как вы можете видеть, индексы строк соответственно корректируются таким образом, я не могу полагаться на фиксированной функции подстроки.

Я довольно новичок в SQL и хотел бы получить ваш совет относительно того, как я должен подходить к этому.

До сих пор методы, которые я пытался, были подстроками.

UPDATE:

К сожалению, я забыл упомянуть, что я не извлекая базы данных на любых символов или строки. Я извлекаю точную часть из этой строки. Например,

Sample 1: 
1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400 

Мне нужно извлечь первое свидание, которое «9/28/2016» и «PSI KTL»

Технически, мне нужно извлечь определенное ное слово из строки ,

Прямо сейчас, я пытаюсь использовать пространство в качестве разделителя и назначать каждое слово в таблицу темп, но кажется, что он не работает на данный момент.

Спасибо!

+0

'извлекать различные и конкретные details' ... что вы пытаетесь извлечь? –

+0

Что такое целая маркерная строка? –

+0

Обновлено. Извините за путаницу. :) – Calvs

ответ

0

Попробуйте это:

CREATE FUNCTION GetWordBasedOnIndex(@text varchar(max),@index int) 
RETURNS varchar(50) 
AS 
BEGIN 
    DECLARE @RET VARCHAR(50),@counter int 
    SET @text = LTRIM(RTRIM(@text)) 
    SET @counter = 1 
    IF @counter < @index 
    BEGIN 
      SET @text = LTRIM(RTRIM(SUBSTRING(@text, CHARINDEX(' ',@text,1), LEN(@text) - CHARINDEX(' ',@text,1)+1))) 
      SET @text = dbo.GetWordBasedOnIndex(@text,@index-1) 
    END 
    IF CHARINDEX(' ',@text,1)=0 SET @RET = @text 
    ELSE SET @RET = SUBSTRING(@text,@counter,CHARINDEX(' ',@text,1)) 
    RETURN @RET 
END 

declare @string nvarchar(max) 
set @string = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400'; 
SELECT DBO.GetWordBasedOnIndex(@string, 5) 

В случае перехода от таблицы и взять слово на основе индекса:

declare @string nvarchar(max) 
set @string = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400'; 
SELECT [dbo].[GetWordBasedOnIndex](@string, 5) 


CREATE table #temp (msg nvarchar(max)) 
INSERT INTO #temp VALUES(@string) 
SELECT [dbo].[GetWordBasedOnIndex](msg, 5) as test from #temp 

drop table #temp 
+0

Спасибо Джеймс, это решает мою проблему. :) – Calvs

+0

Привет @James. Ваш ответ очень полезен, однако, используя его таким образом. ВЫБОР \t bh.Detail, \t (SELECT [REZ5JWB01]. [DBO]. [GetWordBasedOnIndex] (bh.Details, 13)) в качестве тест- дает мне другой выход. Вместо того, чтобы указать значение параметра string, я напрямую передаю его из таблицы. Любые мысли об этом? – Calvs

+0

u означал следующее: SELECT a.test от (SELECT [dbo]. [GetWordBasedOnIndex] (PermanentAdress, 2) в качестве теста из вашей таблицы) a – James

0

пожалуйста, попробуйте следующее:

DECLARE @s varchar(8000) 
DECLARE @s2 varchar(8000) 


set @s = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400'; 

SET @s2 =SUBSTRING(@s, CHARINDEX('PSI KTL', @s), 8000) 

select SUBSTRing(@s2, PATINDEX('%__/__/____%', @s2), 10) 

UPDATE:

, если вы хотите, чтобы разобрать строку, используя пространство в качестве разделителя, вы можете использовать String_Split из SQL 2016 или аналогичной UDF функции для других версий:

DECLARE @s varchar(max) 

set @s = '1 AJ 2552 O 10/8/2016 0:0:0 6 PSI KTL 0 GK 2 10/28/2016 7:0:0 9/28/2016 8:5:0 O20YEARS 32.2400'; 
SET @s = replace(@s, ' ', ' '); -- Here, you can replace other white spaces by single space. 

WITH cte 
AS (
     SELECT *, 
       ROW_NUMBER() Over(ORDER BY (SELECT null)) as RN 
     from string_split(@s, ' ') 
    ) 
     SELECT * FROM cte 
     WHERE RN = 15 
+1

Попытайтесь просто обновить длину до 8000 вместо 9999 для предотвращения следующей ошибки: размер (9999), присвоенный типу «varchar», превышает максимально допустимый для любого типа данных (8000). –

+0

@ahmedabdelqader, Спасибо Ахмед, код обновлен. –

0

Другой простое решение, если вы используете SQL Server 2016

1) Используйте функцию STRING_SPLIT, которая разделяет выражение символа с помощью указанного разделителя.

3) Обнаружение значений даты с помощью функции, используя ISDATE

2) Наконец использовать Top 1 для retriving первой строки.

Как видно из следующего: -

SELECT TOP 1 * 
FROM STRING_SPLIT ('1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400 
', ' ') 
WHERE ISDATE(value) = 1 

Результат:

value 
9/28/2016