TSQL, как вы перебираете строки во время их анализа? - PullRequest
3 голосов
/ 01 августа 2010

Извините за плохую формулировку вопроса, я не знал, как это описать.Я хочу перебрать каждую строку в таблице и при этом извлечь столбец, проанализировать находящийся в нем varchar и в зависимости от того, что он найдет, вставить строки в другую таблицу.Что-то вроде этого:

DECLARE @string varchar(max);
foreach row in (select * from Table) {
    set @string = row[column];
    while (len(@string) > 0) {
        -- Do all the parsing in here

        if (found what was looking for)
            insert into Table2 values(row[column2], row[column3]);
    }
}

Было бы очень хорошо, если бы это было хранимой процедурой, так чтобы это делалось в SQL.Я просто не очень уверен, как подойти к нему.Спасибо.

Редактировать:

В основном это функциональность, на которую я надеялся:

Table 1   |
id_number | text    |
1           Hello, test 532. Yay oh and test 111   
2           test 932.
3           This is a test 315 of stuff test 555.
4           haflksdhfal test 311 sadjhfalsd
5           Yay.

Я хочу просмотреть эту таблицу и проанализировать все текстовые столбцы, чтобыищите экземпляры 'test #', где # это число.Когда он находит что-то внутри текста в этом формате, он вставляет это значение в другую таблицу, например:

Table 2   |
id_number | number
1           532
1           111
2           932
3           315
3           555
4           311

Ответы [ 6 ]

5 голосов
/ 01 августа 2010

Вы думаете, процедурно, а не на основе набора.Вы, вероятно, можете написать все это как один запрос:

INSERT INTO target_table (column list)
SELECT (column list)
FROM source_table
WHERE (parse your column) = (some criterion)

Это гораздо проще написать, и, вероятно, намного быстрее.

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

3 голосов
/ 01 августа 2010

В SQL Server 2008 вы можете сделать это

WITH testTable AS
(
SELECT 1 AS id_number, N'Hello, test 532. Yay oh and test 111' AS txt UNION ALL
SELECT 2, N'test 932.' UNION ALL
SELECT 3, N'This is a test 315 of stuff test 555.' UNION ALL
SELECT 4, N'haflksdhfal test 311 sadjhfalsd' UNION ALL
SELECT 5, N'Yay.'
)

SELECT id_number,display_term
FROM testTable
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(txt,'"','""') + '"', 1033, 0,0)
WHERE TXT IS NOT NULL and 
  display_term NOT LIKE '%[^0-9]%' /*Or use LIKE '[0-9][0-9][0-9]' to only get 3 
                                     digit numbers*/

Возвращает

id_number   display_term
----------- ------------------------------
1           532
1           111
2           932
3           315
3           555
4           311
2 голосов
/ 01 августа 2010

Примерно так: у вас всегда есть «Тест (число)». Работает на SQL Server 2005 +

DECLARE @Table1 TABLE (id_number int, textcol nvarchar(MAX))

INSERT @Table1 VALUES (1, 'Hello, test 532. Yay oh and test 111')
INSERT @Table1 VALUES (2, 'test 932.')
INSERT @Table1 VALUES (3, 'This is a test 315 of stuff test 555.')
INSERT @Table1 VALUES (4, 'haflksdhfal test 311 sadjhfalsd')
INSERT @Table1 VALUES (5, 'Yay.')


;WITH cte AS
(
    SELECT TOP 9999 CAST(ROW_NUMBER() OVER (ORDER BY c1.OBJECT_ID) AS varchar(6)) AS TestNum
    FROM sys.columns c1 CROSS JOIN sys.columns c2
)
SELECT id_number, TestNum FROM
    cte
    JOIN
    @Table1 ON PATINDEX('%Test ' + TestNum + '[^0-9]%', textcol) > 0
                    OR textcol LIKE '%Test ' + TestNum
ORDER BY
    id_number
1 голос
/ 01 августа 2010

Функция, которую вы ищете, называется CURSOR - здесь - статья о том, как их использовать.

Они считаются плохими по производительности и их трудно правильно использовать.

Переосмыслите свою проблему и переформулируйте ее, чтобы ее можно было решить с помощью операции на основе множеств.

Посмотрите на использование табличных переменных или подзапросов для вашего сложного условия.

0 голосов
/ 01 августа 2010

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

DECLARE @CurrentRecord VARCHAR(MAX)

DECLARE db_cursor CURSOR FOR  
SELECT Column
FROM Table 

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @CurrentRecord

WHILE @@FETCH_STATUS = 0   
BEGIN   
       --Your stuff here

       FETCH NEXT FROM db_cursor INTO @name   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Однако, в зависимости от того, что вы делаете, и если это то, что вы делаете на регулярной основе.Я бы порекомендовал посмотреть, если вы можете извлечь разбор в пользовательскую функцию, то вы можете сделать его основанным, а не использовать курсор.В качестве курсора следует приложить «последний рывок».

0 голосов
/ 01 августа 2010

Вы находитесь за курсором - см. Документы MSDN здесь .Обратите внимание, что по возможности следует избегать курсоров - очень мало мест, в которых они подходят и могут привести к медленному неэффективному коду - обычно лучше попробовать решение на основе множеств.

...