Wednesday, August 31, 2016

Sql Server - Find and Replace a value across all tables in database

Find and Replace a value across all tables in database



In my project I faced this problem due to typing mistakes.
End user has entered ‘goodmorning’ and ‘good morning’ interchangeably and it was causing logic failure at application level. So task was to replace ‘goodmorning’ with ‘good morning’ in database wherever it is there. So I came up with this simple script. It worked for me but still there is room for improvement. Please feel free to suggest improvements, use it and share it.

Begin

Set NOCount on
SET ANSI_WARNINGS  OFF


Declare @TotalRec int
Declare @Count int
Declare @TableName varchar(256)
Declare @ColumnName varchar(256)
Declare @RowNum int
Declare @SqlScript varchar(999)
Declare @SearchThis nvarchar(256)
Declare @ReplaceWith nvarchar(256)

Set @SearchThis='AAron'
Set @ReplaceWith='aaRon'

Declare  @TableColumn Table
(
RowNum int Identity(1,1),
TableName varchar(256),
ColumnName varchar(256)
)

Create Table #TableColumn1
(
RowNum int Identity(1,1),
TableName varchar(256),
ColumnName varchar(256)
)

Insert into @TableColumn


select distinct T.TABLE_NAME --as 'TableName'
,Col.COLUMN_NAME --as 'ColumnName'
from
INFORMATION_SCHEMA.COLUMNS Col with (nolock)
inner join INFORMATION_SCHEMA.TABLESwith (nolock) on T.TABLE_NAME=Col.TABLE_NAME and T.TABLE_TYPE='BASE TABLE'
where  DATA_TYPE IN ('char', 'varchar', 'nchar', 'nVarChar','text')  and T.TABLE_SCHEMA='dbo' and T.TABLE_TYPE='BASE TABLE'

Set @TotalRec=(select count(*) from @TableColumn)
Set @Count=0

while @TotalRec>@Count
Begin

Set @Count=@Count+1
Set @TableName=(Select top 1 TableName From @TableColumn T where T.RowNum=@Count)
Set @ColumnName=(Select top 1 ColumnName From @TableColumn T where T.RowNum=@Count)
 Begin Try
 EXEC ( 'Update '+@TableName+ ' Set '+ @ColumnName+'='+''''+@ReplaceWith+''''+ ' Where '+@ColumnName+' = '+''''+@SearchThis+'''')
         End Try
         Begin catch

         End catch
End

Drop table #TableColumn1
SET ANSI_WARNINGS ON;


End

Sql Server - Monitoring the Performance of All Stored Procedures

Monitoring the Performance of All Stored Procedures 



Every Project suffer from this problem, over the time they have developed many stored procedure and their versions. No one is actually sure about their utilization and performance. Use this very simple SQL Script and generate a report with all the information you required. You can modify the script as per your need like order by execution_count so you can identify most used ones or use a date range in filter criteria to narrow down your search.  




SELECT
O.Name As 'StoredProcName',
O.object_id,
ps.execution_count,
CAST(ROUND((ps.lASt_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Last_elapsed_time_In_Sec',
ps.lASt_execution_time as 'Last_execution_time',
ps.lASt_logical_reads as 'Last_logical_reads',
ps.lASt_logical_writes as 'Last_logical_writes',
ps.lASt_physical_reads as 'Last_physical_reads',
CAST(ROUND((ps.lASt_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Last_worker_time_In_Sec' ,
CAST(ROUND((ps.max_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Max_elapsed_time_In_Sec',
ps.max_logical_reads,
ps.max_logical_writes,
ps.max_physical_reads,
CAST(ROUND((ps.max_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Max_worker_time_In_Sec',
CAST(ROUND((ps.min_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Min_elapsed_time_In_Sec' ,
ps.min_logical_reads,
ps.min_logical_writes,
ps.min_physical_reads,
CAST(ROUND((ps.min_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Min_worker_time_In_Sec',
CAST(ROUND((ps.total_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Total_elapsed_time_In_Sec' ,
ps.total_logical_reads,
ps.total_logical_writes,
ps.total_physical_reads,
CAST(ROUND((ps.total_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Total_worker_time_In_Sec'
FROM Sys.objects O left join sys.dm_exec_procedure_stats ps on O.name=OBJECT_NAME(ps.object_id, ps.databASe_id)
WHERE O.TYPE='P'
ORDER BY O.Name







Feel free to use it or share it.
Please provide your feedback or suggestion to improve our work.


Thanks & Happy Scripting 

Sql Server - Monitoring the Performance of All Stored Procedures

Monitoring the Performance of All Stored Procedures 



Every Project suffer from this problem, over the time they have developed many stored procedure and their versions. No one is actually sure about their utilization and performance. Use this very simple SQL Script and generate a report with all the information you required. You can modify the script as per your need like order by execution_count so you can identify most used ones or use a date range in filter criteria to narrow down your search.  




SELECT 
O.Name,
O.object_id,
ps.execution_count,
CAST(ROUND((ps.lASt_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'LASt_elapsed_time_In_Sec',
ps.lASt_execution_time,
ps.lASt_logical_reads,
ps.lASt_logical_writes,
ps.lASt_physical_reads,
CAST(ROUND((ps.lASt_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'LASt_worker_time_In_Sec' ,
CAST(ROUND((ps.max_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Max_elapsed_time_In_Sec',
ps.max_logical_reads,
ps.max_logical_writes,
ps.max_physical_reads,
CAST(ROUND((ps.max_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'max_worker_time_In_Sec',
CAST(ROUND((ps.min_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Min_elapsed_time_In_Sec' ,
ps.min_logical_reads,
ps.min_logical_writes,
ps.min_physical_reads,
CAST(ROUND((ps.min_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Min_worker_time_In_Sec',
CAST(ROUND((ps.total_elapsed_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Total_elapsed_time_In_Sec' ,
ps.total_logical_reads,
ps.total_logical_writes,
ps.total_physical_reads,
CAST(ROUND((ps.total_worker_time/1000000.00),4)AS NUMERIC(8,4)) AS 'Total_worker_time_In_Sec'
FROM Sys.objects O left join sys.dm_exec_procedure_stats ps on O.name=OBJECT_NAME(ps.object_id, ps.databASe_id)
WHERE O.TYPE='P'
ORDER BY O.Name

Feel free to use it or share it.
Please provide your feedback or suggestion to improve our work.


Thanks & Happy Scripting 

Monday, August 29, 2016

Sql Server - Index Utilization Report

Index Utilization Report


One day my manager came and told me that he need Index Utilization Report.
He felt that during development of the project we have created so many indexes but he is not sure about how useful those are. So he wants a report which shows all the Indexes on user defined table or view and how effectively they are being used in our project.  So guys here is the code and screen shot of the report.  You can run this code on any database and get the report.


select
Obj.name as 'Table/View Name',
Obj.type,
Indx.name as 'IndexName',
Indx.index_id,
Indx.type_desc,
Indx.type,
 IUS.*,
 IOS.*
from
sys.INDEXES Indx inner join sys.objects Obj on Obj.object_id=Indx.object_id
left join SYS.DM_DB_INDEX_USAGE_STATS IUS on Indx.index_id=IUS.index_id and IUS.object_id=Obj.object_id
left join
SYS.DM_DB_INDEX_OPERATIONAL_STATS (NULL,NULL,NULL,NULL ) IOS       
         ON Indx.[OBJECT_ID] = IOS.[OBJECT_ID] 
            AND Indx.INDEX_ID = IOS.INDEX_ID 
where (Obj.type_desc='USER_TABLE' or Obj.type_desc='VIEW')
order by Obj.name,Indx.Name,
IUS.user_updates,IUS.user_lookups,IUS.user_seeks,IUS.user_scans  DESC


Feel free to share or modify it.
Let me know if you have any idea to improve this report.

I am adding few more useful columns , here is the updated Sql Script -



select
Obj.name as 'Table/View Name',
Obj.type_desc As 'TableType',
Indx.name as 'IndexName',
Indx.index_id,
Indx.type_desc,
Indx.is_primary_key,
Indx.is_unique,
Indx.is_unique_constraint,
Indx.has_filter,
 IUS.*,
 IOS.*
from
sys.INDEXES Indx inner join sys.objects Obj on Obj.object_id=Indx.object_id
left join SYS.DM_DB_INDEX_USAGE_STATS IUS on Indx.index_id=IUS.index_id and IUS.object_id=Obj.object_id
left join
SYS.DM_DB_INDEX_OPERATIONAL_STATS (NULL,NULL,NULL,NULL ) IOS      
         ON Indx.[OBJECT_ID] = IOS.[OBJECT_ID]
            AND Indx.INDEX_ID = IOS.INDEX_ID
where (Obj.type_desc='USER_TABLE' or Obj.type_desc='VIEW')
order by Obj.name,Indx.Name,
IUS.user_updates,IUS.user_lookups,IUS.user_seeks,IUS.user_scans  DESC

Thanks