2017-01-18 2 views
0

У меня есть следующий запрос, я хочу использовать вложенный курсор в моем запросе. Как это сделать, потому что оно не работает, и я новичок в SQL Server. Пожалуйста, помогите мнеКак использовать курсор внутри курсора в SQL Server?

CHECK TABLE SUGGEST LAT 31.8181 LONG 71.4146 

Msg 16915, уровень 16, состояние 1, процедура Sp_CheckCarStatusMeter, Линия курсор с именем 'ShapeCursor' уже существует. ELSE ОТКРЫТЫЙ CURSOR

Msg 16905, уровень 16, состояние 1, процедура Sp_CheckCarStatusMeter, линии 296
Курсор уже открыт.

Код:

DECLARE SuggestCursor CURSOR FOR 
    SELECT TOP 100 
     rtha.car_id, rtha.latitude, rtha.longitude 
    FROM 
     Carhistory rtha 
    WHERE 
     rtha.car_id = 6142 ; 

OPEN SuggestCursor; 

FETCH NEXT FROM SuggestCursor INTO @CarSuggested, @carlatprevious, @carlongprevious; 

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    PRINT 'CHECK TABLE SUGGEST LAT '[email protected] +' LONG '+ @carlongprevious; 

    DECLARE ShapeCursor CURSOR FOR 
     SELECT 
      g.ID, @carID, g.ShapeType 
     FROM 
      tblgeo AS g 
     WHERE 
      car_id @ID; 

    IF (SELECT CURSOR_STATUS('local','ShapeCursor')) >= -1 
    BEGIN 
     Print 'DEALLOCATE CURSOR' 
     --DEALLOCATE ShapeCursor 
    END 
    ELSE  
     Print 'ELSE OPEN CURSOR' 

    OPEN ShapeCursor; 

    FETCH NEXT FROM ShapeCursor INTO @ID, @CarIdx, @ShapeType; 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 
+2

Нам нужно будет увидеть больше кода, чтобы убедиться, поскольку вы показываете только верхнюю часть. Поскольку вы объявляете курсор в цикле, очевидная проблема заключается в том, что вы также не освобождаете его в каждом цикле цикла. При этом, и особенно, поскольку вы говорите, что вы новичок в SQL, курсоры, как правило, лучше избегать, если все другие возможности не были исследованы, а * вложенные * курсоры редко, если вообще когда-либо, являются правильным решением проблемы. Если бы вы могли описать свою * цель *, а также некоторые примеры данных и ожидаемые результаты, мы можем предложить решение, которое вообще не использует курсоры. –

+2

Курсоры злы. Вложенные курсоры даже хуже. Если у вас действительно нет другого выбора, не используйте их вообще. Сказав это, если вы действительно должны использовать вложенные курсоры, внутренний курсор должен быть объявлен (и освобожден) за пределами цикла внешнего курсора. –

+0

[xy problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Bridge

ответ

0

Пример с вложенными курсоров:

DECLARE 
     @crTables CURSOR, 
     @crColumns CURSOR, 
     @table_id INT, 
     @table_name VARCHAR(100), 
     @column_id INT, 
     @column_name VARCHAR(100) 

SET @crTables = CURSOR FAST_FORWARD FOR 
SELECT TOP 10 [object_id], NAME 
FROM sys.tables t 
ORDER BY t.[object_id] DESC 

OPEN @crTables 

FETCH NEXT FROM @crTables 
INTO @table_id, @table_name 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    PRINT @table_name + ': ' 

    SET @crColumns = CURSOR FAST_FORWARD FOR 
    SELECT TOP 10 c.column_id, c.name 
    FROM sys.[columns] c 
    WHERE c.[object_id] = @table_id 
    ORDER BY c.column_id 

    OPEN @crColumns 

    FETCH NEXT FROM @crColumns 
    INTO @column_id, @column_name 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     PRINT @column_name 

     FETCH NEXT FROM @crColumns 
     INTO @column_id, @column_name 
    END 

    CLOSE @crColumns 
    DEALLOCATE @crColumns 

    PRINT '' 

    FETCH NEXT FROM @crTables 
    INTO @table_id, @table_name 
END 

CLOSE @crTables 
DEALLOCATE @crTables 

GO 

Который даст тот же результат, как:

GO 

DECLARE @txt VARCHAR(MAX) 

SET @txt = 
STUFF(
    (
    SELECT TOP 10 
     CHAR(13) + CHAR(10) + NAME 
     + (
       SELECT TOP 10 CHAR(13) + CHAR(10) + c.name 
       FROM sys.[columns] c 
       WHERE c.[object_id] = t.[object_id] 
       ORDER BY c.column_id 
       FOR XML PATH(''), TYPE 
      ).value('.', 'VARCHAR(MAX)') 
     + CHAR(13) + CHAR(10) 
    FROM sys.tables t 
    ORDER BY t.[object_id] DESC 
    FOR XML PATH(''), TYPE 
).value('.', 'VARCHAR(MAX)'), 1, 2, '') 

PRINT @txt 

Try, чтобы избежать курсоров.

Смежные вопросы