quinta-feira, 20 de agosto de 2009
Calendário em SQLServer
Alem de ser um excelente exemplo de CTE com recursividade.
declare @start datetime,
@end datetime
set @start = '2009-01-01'
set @end = '2010-01-01'
;with calendar(date,isweekday, y, q,m,d,dw,monthname,dayname,w) as
(
select @start ,
case when datepart(dw,@start) in (1,7) then 0 else 1 end,
year(@start),
datepart(qq,@start),
datepart(mm,@start),
datepart(dd,@start),
datepart(dw,@start),
datename(month, @start),
datename(dw, @start),
datepart(wk, @start)
union all
select date + 1,
case when datepart(dw,date + 1) in (1,7) then 0 else 1 end,
year(date + 1),
datepart(qq,date + 1),
datepart(mm,date + 1),
datepart(dd,date + 1),
datepart(dw,date + 1),
datename(month, date + 1),
datename(dw, date + 1),
datepart(wk, date + 1) from calendar where date + 1< @end
)
select * from calendar option(maxrecursion 10000)
Campos Identity
Primeiro, estra query mostra como estão os Identitys de todas as tabelas do seu banco de dados, a tabela, coluna, o tipo, o valor atual e o % de uso:
SELECT QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) AS TableName,
c.name AS ColumnName,
CASE c.system_type_id
WHEN 127 THEN 'bigint'
WHEN 56 THEN 'int'
WHEN 52 THEN 'smallint'
WHEN 48 THEN 'tinyint'
END AS 'DataType',
IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) AS CurrentIdentityValue,
CASE c.system_type_id
WHEN 127 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 9223372036854775807
WHEN 56 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 2147483647
WHEN 52 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 32767
WHEN 48 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 255
END AS 'PercentageUsed'
FROM sys.columns AS c
INNER JOIN
sys.tables AS t
ON t.[object_id] = c.[object_id]
WHERE c.is_identity = 1
ORDER BY PercentageUsed DESC
Para incrementar passo (seed) a um identity e retornar o valor:
SELECT IDENT_INCR('sua_tabela') AS 'IDENT_INCR';
Para mostra o valor atual do identity:
SELECT IDENT_CURRENT('sua_tabela') AS Current_Identity;
Mostra o "valor de passo" (seed) da identity
SELECT IDENT_SEED('sua_tabela') AS 'IDENT_SEED';
Reset na Identity para o próximo valor valido na tabela.
DBCC CHECKIDENT('sua_tabela')
Reset na Identity para o valor informado no último parâmetro.
DBCC CHECKIDENT('sua_tabela', RESEED, 0)
Para desligar o Identity de uma tabela MOMENTANEAMENTE, para um insert:
SET IDENTITY_INSERT sua_tabela On --Desliga o Identity
Faça os Inserts necessários para sua manutenção/carga.
SET IDENTITY_INSERT sua_tabela Off --Religa o IdentityVocê sabe a diferença entre Some, Any e All??
Com este exemplo bem simples, fica facil de entender.
CREATE TABLE #T1 (ID int)
GO
INSERT Into #T1 VALUES (1)
INSERT Into #T1 VALUES (2)
INSERT Into #T1 VALUES (3)
INSERT Into #T1 VALUES (4)
Print 'The following query returns TRUE because 3 is less than some of the values in the table.'
IF 3 < SOME (SELECT ID FROM #T1)
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
Print 'The following query returns FALSE because 3 is not less than all of the values in the table.'
IF 3 < ALL (SELECT ID FROM #T1)
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
Print 'The following query returns TRUE because 3 is less than anyone of the values in the table.'
Print 'SOME is an ISO standard equivalent for ANY.'
IF 3 < Any (SELECT ID FROM #T1)
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
Verificar e Trocar o owner do Banco
Para listar os Bancos e seus owners:
SELECT databases.NAME as Banco,
server_Principals.NAME as Owner
FROM sys.[databases]
INNER JOIN sys.[server_principals] ON [databases].owner_sid = [server_principals].sid
Esta opção deve ser utilizada somente se o banco perdeu o owner, ou é claro, se você tem certeza do que está fazendo.
Para fazer isso você precisa ser SysAdmin ou estar no grupo DB_Owner.
Este exemplo irá trocar o owner do banco de dados atual para SA.
USE Seu_Banco_De_Dados
GO
EXEC sp_changedbowner 'sa'
GO
Detalhes da Execução de um Job.
Com essa Query dá para saber se o Job ainda está executando, ou se já finalizou, com sucesso ou erro, quanto tempo demorou, etc.
/***************************************/
/* Detalhes da Execução do JOB */
/***************************************/
Use msdb
GO
SELECT sjb.Job_id,
stsv.server_id,
stsv.server_name,
stsv.enlist_date,
stsv.last_poll_date,
cast(dateadd(ss, cast(substring(cast(last_run_time + 1000000 as char(7)),6,2) as int),
dateadd(mi, cast(substring(cast(last_run_time + 1000000 as char(7)),4,2) as int),
dateadd(hh, cast(substring(cast(last_run_time + 1000000 as char(7)),2,2) as int),
convert(datetime,cast (last_run_date as char(8)))))) as DateTime) as LastRunDate,
sjs.last_run_duration,
sjs.last_run_outcome,
sjs.last_outcome_message
FROM msdb.dbo.sysjobs sjb
Inner Join msdb.dbo.sysjobservers sjs On sjb.Job_Id = sjs.job_id
Left Join msdb.dbo.systargetservers_view stsv ON (sjs.server_id = stsv.server_id)
WHERE sjb.name = 'BKPIncremental-1.BKPIncremental-1'
Select Top 2 A.*
from msdb..sysjobhistory A
Inner Join msdb.dbo.sysjobs B On A.Job_Id = B.job_id
Where B.name = 'Nome do Seu Job'
Caso tenha dado erro na execução do Job, esta Query, mostra o log do erro do Job:
Select Top 2 A.*
from msdb..sysjobhistory A
Inner Join msdb.dbo.sysjobs B On A.Job_Id = B.job_id
Where B.name = 'Nome do Seu Job'
Os registros sempre vem uma linha para o Job Outcome e uma linha para cada Step do Job, como o exemplo é um Job de um único Step coloquei o Top 2.
Tamanho da tabela no Banco
Essa SP de sistema, mostra o tamanho em KB das seguintes informações da tabela:
1) Quantida de registros da tabela
2) Espaço reservado para a tabela
3) Espaço utilizado pelos dados
4) Espaço utilizado pelos Indices
5) Espaço ainda livre
sp_spaceused 'sua_tabela'
Estas informações são importantes para por exemplo rever um planejamento de capacidade do servidor.
Como está a utilização dos seus Indices?
A grosso modo, não adianta você criar um indice em tabelas que são mais utilizadas para inserts/updates do que para consultas.
E isso "talvez" você só saiba algum tempo depois, após algumas estatisticas.
Esta primeira query mostra a quantidade de Inserts, Updates e Deletes por indices.
/*leaf_insert_count - total count of leaf level inserts leaf_delete_count - total count of leaf level inserts leaf_update_count - total count of leaf level updates
*/
SELECT OBJECT_NAME(A.[OBJECT_ID]) AS [OBJECT NAME], I.[NAME] AS [INDEX NAME], A.LEAF_INSERT_COUNT, A.LEAF_UPDATE_COUNT, A.LEAF_DELETE_COUNT FROM SYS.DM_DB_INDEX_OPERATIONAL_STATS (NULL,NULL,NULL,NULL ) A INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = A.[OBJECT_ID] AND I.INDEX_ID = A.INDEX_ID WHERE OBJECTPROPERTY(A.[OBJECT_ID],'IsUserTable') = 1 And (A.LEAF_INSERT_COUNT > 0 Or A.LEAF_UPDATE_COUNT > 0 Or A.LEAF_DELETE_COUNT > 0)Order by LEAF_INSERT_COUNT DESC
Esta mostra a quantidade de Index Seeks, Index Scans, Index Lookups e operações de Insert, Update e Delete por indices.
/*user_seeks - number of index seeks
user_scans- number of index scans
user_lookups - number of index lookups
user_updates - number of insert, update or delete operations
*/
SELECT OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], I.[NAME] AS [INDEX NAME], USER_SEEKS, USER_SCANS, USER_LOOKUPS, USER_UPDATES FROM SYS.DM_DB_INDEX_USAGE_STATS AS S INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = S.[OBJECT_ID] AND I.INDEX_ID = S.INDEX_ID WHERE OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1 Order by User_Updates DESC, User_Seeks ASC
