TSQL перевод поля ChangeData в CRM 2011

У меня есть строка с разделителями, которая действует как ключ для целевой строки с разделителями. Мне нужно знать, где находятся 2 значения в последовательности клавиш, а затем извлекать только эти позиции из моей целевой строки.

Пример 1
Ключ: ,15,90,104,73,95,13,14,
Цель: Средний~Мужчина~28~Зеленый~Право~Нет~10/04/2013

Пример 2
Ключ: ,14,73,104,95,15,13,90,
Цель: 03.12.2013~Зеленый~28~Правый~Средний~Нет~Мужской~

Меня интересуют только значения пола и даты в цели, а соответствующие записи в ключе всегда будут 14 и 90.

Как только я узнаю, где эти значения находятся последовательно (позиции 2 и 7 в примере 1), мне нужно вытащить те же разделы моей целевой строки, чтобы я получил значения пола и даты в своих собственных переменных.

Я изменил тип данных, которые я ищу, чтобы упростить понимание вопроса.

Я надеюсь, что это имело смысл

Спасибо

Мэтт


person Powell21    schedule 10.04.2013    source источник


Ответы (3)


Попробуйте это решение -

DECLARE @temp TABLE
(
      id INT IDENTITY(1,1)
    , k NVARCHAR(100)
    , t NVARCHAR(500)
)

INSERT INTO @temp (k, t)
VALUES 
    (',15,90,104,73,95,13,14,', 'Medium~Male~28~Green~Right~No~10/04/2013'),
    (',14,73,104,95,15,13,90,', '12/03/2013~Green~28~Right~Medium~No~Male~')

SELECT 
      data.id
    , data.p
    , data.r 
FROM (
    SELECT 
          p = p.value('(.)[1]', 'NVARCHAR(50)')
        , po = p.value('for $i in . return count(../*[. << $i])', 'int')
        , r = r.value('(.)[1]', 'NVARCHAR(50)')
        , ro = r.value('for $i in . return count(../*[. << $i])', 'int')
        , d.id
    FROM (
        SELECT 
              t.id
            , txml = CAST('<r><s>' + REPLACE(t.k + ',', ',', '</s>' + '<s>') + '</s></r>' AS XML)
            , kxml = CAST('<r><s>' + REPLACE(t.t + '~', '~', '</s>' + '<s>') + '</s></r>' AS XML)  
        FROM @temp t
    ) d
    CROSS APPLY kxml.nodes('/r/s') t(p)
    CROSS APPLY txml.nodes('/r/s') k(r)
) data
WHERE data.po = data.ro - 1
    AND data.r IN ('14', '90')
    --AND r + data.p != ''
ORDER BY data.id
person Devart    schedule 10.04.2013
comment
Фантастический!! Большое спасибо вам обоим за вашу помощь в этом. - person Powell21; 10.04.2013
comment
Я не хотел отказываться от этого решения. Я думал, что смогу принять 2 одновременно - person Powell21; 16.04.2013

Вы можете разделить две строки (см. здесь: Эквивалент функции разделения в T-SQL? ).

Затем, когда вы разделили строки на два табличных объекта, обратитесь к N-й записи (например, используя ключевое слово TOP) в обоих, и вы сможете получить результат.

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

person Andrea Colleoni    schedule 10.04.2013
comment
Единственная проблема с этим решением заключается в том, что каждый раз, когда цель и ключ генерируются, длина может сильно различаться, поэтому нет никакого способа узнать количество столбцов, которые мне нужны. Я надеялся, что можно будет сохранить последовательное значение в переменной, а затем использовать эту переменную для извлечения соответствующего раздела из цели. - person Powell21; 10.04.2013
comment
Если я хорошо понимаю ваш комментарий и снова читаю ваш вопрос, я думаю, что после того, как вы разделили свои значения в таблице (переменная, временная или физическая, это не имеет значения), как это делает функция, вы можете получить n-я запись этой таблицы . См. здесь: stackoverflow.com/ вопросы/1022514/ - person Andrea Colleoni; 10.04.2013
comment
Но независимо от типа таблицы, которую я использую, не придется ли мне определять количество столбцов? Я не буду знать, сколько столбцов мне нужно, потому что количество значений в моей строке изменится - person Powell21; 10.04.2013
comment
Извините, я не обратил достаточного внимания на использование вами слова «столбцы». С такой функцией ваши строки разбиваются на строки, а не столбцы, поэтому у вас не должно возникнуть этой проблемы. - person Andrea Colleoni; 10.04.2013
comment
Большое спасибо за вашу помощь в этом - person Powell21; 10.04.2013

В качестве быстрого продолжения у меня возникли проблемы с применением вышеуказанного решения (вероятно, из-за отсутствия знаний с моей стороны), поэтому я создал следующие функции, и они выполняют свою работу.

ПОЛУЧИТЬ ПОСЛЕДОВАТЕЛЬНОЕ ЗНАЧЕНИЕ -------------------------------------------------------------- -----------------------

DECLARE @Attributemask varchar(max) = '[PASS IN KEY STRING]' 
DECLARE @Required varchar(10) = '[PASS IN VALUE TO LOOK FOR FOLLOWED BY A COMMA]'
DECLARE @AttPosition int
DECLARE @TempString varchar(max)
DECLARE @Result as int

SET @AttPosition = CHARINDEX(@Required, @Attributemask)
SET @TempString = LEFT(@Attributemask, @AttPosition)
SET @Result = len(@TempString)-len(replace(@TempString,',',''))
SELECT @Result

ПОЛУЧИТЬ ДАННЫЕ ------------------------------------------------ ----------------------------------

DECLARE @ChangeData varchar(max) = '[PASS IN TARGET STRING]'
DECLARE @AttPos int = [PASS IN RESULT FROM PREVIOUS FUNCTION] 
DECLARE @Count int = 1
DECLARE @NotNeeded varchar(100)
Declare @Result varchar(max)

SET @ChangeData = '~'+@ChangeData

WHILE @Count < (@AttPos +1)
BEGIN
    SET @NotNeeded = CHARINDEX('~', @ChangeData)
    SET @ChangeData = right(@ChangeData,len(@ChangeData) - @NotNeeded)
    IF len(@ChangeData) = 0 BREAK
    SET @Count = @Count +1
END

SET @Result = LEFT(@ChangeData, (CHARINDEX('~', @ChangeData)))
SET @Result = LEFT(@Result, (LEN(@Result)-1))
Select @Result
person Powell21    schedule 11.04.2013