Transact-SQL: processi bloccanti e relative query

Utilizzando SQL Server Enterprise Manager è possibile visualizzare l’attività corrente del server,  sotto forma di elenco di processi e loro situazione:

Attività Corrente
Immagine

Può capitare che processi siano bloccati da altri processi. Ed è possibile visualizzare l’ultimo comando TSQL eseguito dai processi:

Proprietà

Unendo le informazioni trovate in questi due siti

http://www.sqlservercentral.com/Forums/Topic365627-146-1.aspx

http://www.kodyaz.com/articles/identify-kill-blocking-sql-server-processes.aspx

ho realizzato uno script che mostra i processi bloccanti, ed il relativo comando TSQL:

use master
GO
declare @spid smallint

select * from sysprocesses (nolock) where blocked = 0 and spid in (
select blocked from sysprocesses (nolock) where blocked <> 0 )

DECLARE c_curs CURSOR FOR
select spid from sysprocesses (nolock) where blocked = 0 and spid in (
select blocked from sysprocesses (nolock) where blocked <> 0
)

OPEN c_curs
FETCH NEXT FROM c_curs
INTO @spid

WHILE @@FETCH_STATUS = 0
BEGIN

dbcc inputbuffer(@spid)

FETCH NEXT FROM c_curs
INTO @spid

END --while

CLOSE c_curs
DEALLOCATE c_curs

Breve spiegazione: prima viene eseguita la query:

select * from sysprocesses (nolock) where blocked = 0 and spid in (
select blocked from sysprocesses (nolock) where blocked <> 0 )

che restituisce l’elenco dei processi bloccanti, poi sulla stessa query viene definito un cursore, e di ogni processo vado a prendere il comando TSQL che sta eseguendo:

dbcc inputbuffer(@spid)

Qualche nota:

Transact-SQL: utilizzo del CURSOR

Una cosa molto banale, dichiarare ed usare un cursore in una store procedure in Transact-SQL:

Supponiamo di avere una tabella con tre campi: (ID, CAMPO1, CAMPO2)

DECLARE @ID INTEGER
DECLARE @CAMPO1 VARCHAR(10)
DECLARE @CAMPO2 VARCHAR(10)

DECLARE c_curs CURSOR FOR

select * from tabella

OPEN c_curs

FETCH NEXT FROM c_curs
INTO @ID, @CAMPO1, @CAMPO2

WHILE @@FETCH_STATUS = 0

BEGIN

-- Faccio qualche cosa con i record della tabella

-- Passo al record successivo
FETCH NEXT FROM c_curs
INTO @ID, @CAMPO1, @CAMPO2

END

CLOSE c_curs
DEALLOCATE c_curs

La documentazione di mamma Microsoft: http://msdn.microsoft.com/it-it/library/ms180169(SQL.90).aspx

C# e Sql Server: sp_help_job, monitorare i job.

In questo link mamma microsoft ci parla della store procedure sp_hel_job, utile per monitorare i job di sql server:

http://technet.microsoft.com/it-it/library/ms186722(SQL.90).aspx

Il metodo di esempio DammiElencoJob riportato sotto non fa altro che eseguire la query:

"exec [msdb].dbo.sp_help_job @enabled = 1"

per avere l’elenco di tutti i job attivi.


private String DammiElencoJob()
{

StringBuilder _sb = new StringBuilder();
DataTable _ds;

_ds = QueryDB.getRecordSQL(, ,, , "exec [msdb].dbo.sp_help_job @enabled = 1");

if (_ds.Rows.Count == 0)

{
_sb.Append("Errore: nessun job trovato.").Append(Environment.NewLine);
}
else
{
_sb.Append("NOME                                                               + "
" |ULTIMA    |ESITO").Append(Environment.NewLine);
foreach (DataRow r in _ds.Rows)
{
string _name =  ((string)r["name"]).PadRight(90);
_sb.Append(_name).Append("|");
DateTime dt = new DateTime((int)r["last_run_date"]);
string _last_run_date = ("" + dt.ToString("dd/MM/yyyy")).PadRight(10);
_sb.Append(_last_run_date).Append("|");
int _last_run_outcome = (int)r["last_run_outcome"];
switch (_last_run_outcome)
{
case 0:
_sb.Append("Non completato");
break;
case 1:
_sb.Append("Completato");
break;
case 3:
_sb.Append("Annullato");
break;
case 5:
_sb.Append("Stato sconosciuto");
break;
default:
_sb.Append("Stato sconosciuto");
break;
}
_sb.Append(Environment.NewLine);
}
}
_sb.Append(Environment.NewLine);
return _sb.ToString();

}


public static DataTable getRecordSQL(String datasource,String user, String password, String database, String sql)

{

String connStr;
OleDbConnection conn;
OleDbDataAdapter adattatore;
DataTable ds = new DataTable();

connStr = @"Provider = SQLOLEDB.1;Password=" + password + ";User ID=" + user + ";Initial Catalog=" + database + ";Data Source=" + datasource;

conn = new OleDbConnection(connStr);
adattatore = new OleDbDataAdapter();
adattatore.SelectCommand = new OleDbCommand(sql, conn);

try

{
adattatore.Fill(ds);
adattatore.Dispose();
conn.Dispose();
return ds;
}
catch (SqlException se)
{
return null;
}
catch (Exception ex)
{
return null;
}

}

Dot Net: Naming Conventions

Direttamente da mamma Microsoft: http://msdn.microsoft.com/en-us/library/ms229045.aspx, di cui questa pagina è una maccheronica traduzione:

I Nomi

  • Scegliete nomi di facile lettura. No, gli acronimi non sono di facile lettura.
  • Date preferenza alla leggibilità sulla brevità. Dalla versione 3.5 di .net mamma Microsoft non fa più pagare un tot a carattere.
  • Non usate “_”, “-” o altri caratteri non alfanumerici. Non andate sempre a complicare le cose, su.
  • Non usare la notazione Ungherese (es. txtApri, lblTitolo, ecc…). Non state mica programmando in Visual Basic 6, diamine.
  • Evitate di usare nomi che vanno in conflitto con le parole chiave del linguaggio che state usando. Tanto non ve lo fa fare.

Abbreviazioni e Acronimi

  • Non usare abbreviazioni o contrazioni delle parole. Non state scrivendo un sms.
  • Non usare acronimi a meno che questi non siano largamente riconosciuti (es. Xml, Http ecc…). Si, lo so che non volete che nessuno capisca il vostro codice come lo capite voi… vi capisco…

Nomi specifici di linguaggio

  • Se dovete riferirvi ad un tipo, utilizzate il suo common language runtime (CLR), e non la denominazione in un determinato linguaggio. Ad esempio, Int16 è int in c#, Integer in VB ecc… ma se un metodo si riferisce un Int16, metteteci Int16 nel nome, e non int o Integer.
  • Utilizzate nomi comuni (come “value” o “item”) dove non ci sia la necessità di dare un significato all’identificatore o il tipo nel parametro non sia importante (es. Il “value” utilizzato nei metodi Get e Set). Non so se Pippo o Pluto possano considerarsi nomi comuni però…

A dire la verità, cercavo un’altra cosa stasera, ma sono incappato in questa pagina…

Transact-SQL: errore 8153 – è stato eliminato un valore Null …

Ebbene si, ogni tanto si torna da mamma microsoft. Oggi una store procedure mi ha dato il seguente errore:

Avviso: è stato eliminato un valore Null tramite un'aggregazione o un'altra operazione SET.

Ho trovato il codice dell’errore qua: http://msdn.microsoft.com/it-it/library/cc645597.aspx ed in questo forum anche la spiegazione:

http://www.btre.it/forum/select_sum-t53361.html

In sostanza, significa che in una select contenente una formula di aggregazione (es SUM) è stato scartato un record che nel campo su cui si effettua l’aggregazione ha valore NULL.

←Older