Domanda

Ho una procedura memorizzata che crea e apre alcuni cursori. Li chiude alla fine, ma se colpisce un errore quei cursori rimangono aperti! Quindi le esecuzioni successive falliscono quando tenta di creare cursori poiché esiste già un cursore con il nome.

Esiste un modo in cui posso interrogare quali cursori esistono e se sono aperti o no in modo da poterli chiudere e deallocare? Sento che è meglio che cercare ciecamente di chiudere e ingoiare errori.

È stato utile?

Soluzione 3

Questo sembra funzionare per me:

CREATE PROCEDURE dbo.p_cleanUpCursor @cursorName varchar(255) AS
BEGIN

    DECLARE @cursorStatus int
    SET @cursorStatus =  (SELECT cursor_status('global',@cursorName))

    DECLARE @sql varchar(255)
    SET @sql = ''

    IF @cursorStatus > 0
        SET @sql = 'CLOSE '+@cursorName

    IF @cursorStatus > -3
        SET @sql = @sql+' DEALLOCATE '+@cursorName

    IF @sql <> ''
        exec(@sql)

END

Altri suggerimenti

Guarda qui per informazioni su come per trovare i cursori. Non ho mai usato nessuno di loro perché sono riuscito a trovare un modo per farlo senza andare a Rowon Agonizing Row.

Dovresti ricostruire lo sp in

  • non usare i cursori (possiamo aiutarti - c'è quasi sempre un modo per evitare RBAR)

  • compilalo in una transazione e ripristinalo in caso di errore o se rilevi un errore. Ecco alcuni articoli eccellenti su questo. part 1 e parte 2

Se hai SQL2005, puoi anche usare provare a catturare

EDIT (in risposta al tuo post): idealmente, la generazione dei dati è gestita al meglio a livello di applicazione in quanto sono più adatti per operazioni non basate su set.

Red Gate ha un Generatore di dati SQL che ho usato prima (è ottimo per le singole tabelle, ma richiede alcune configurazioni se si dispone di un sacco di FK o di un ampio database [normalizzato]).

Funziona su 2008R2, non ho testato nulla prima:

USE MASTER
GO
select s.session_id, s.host_name, s.program_name, s.client_interface_name, s.login_name
, c.cursor_id, c.properties, c.creation_time, c.is_open, con.text,
l.resource_type, d.name, l.request_type, l.request_Status, l.request_reference_count, l.request_lifetime, l.request_owner_type
from sys.dm_exec_cursors(0) c
left outer join (select * from sys.dm_exec_connections c cross apply sys.dm_exec_sql_text(c.most_recent_sql_handle) mr) con on c.session_id = con.session_id
left outer join sys.dm_exec_sessions s on s.session_id = c.session_id
left outer join sys.dm_tran_locks l on l.request_session_id = c.session_id
left outer join sys.databases d on d.database_id = l.resource_database_id
  

Puoi usare la sp_cursor_list stored procedure di sistema per ottenere un elenco   di cursori visibili alla connessione corrente e    sp_describe_cursor , sp_describe_cursor_columns e    sp_describe_cursor_tables per determinare le caratteristiche di a   cursore.

(da http://msdn.microsoft .com / it-it / library / aa172595 (v = sql.80) .aspx )

Puoi usare

  

sys.dm_exec_cursors

come descritto qui

Fondamentalmente è possibile eseguire questa query di esempio e ottenere informazioni sui cursori aperti in vari database

  

sys.dm_exec_cursors (0)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top