Sei sulla pagina 1di 4

create procedure sys.

sp_updatestats
@resample char(8)='NO'
as
declare @dbsid varbinary(85)
select @dbsid = owner_sid
from sys.databases
where name = db_name()
-- Check the user sysadmin
if not is_srvrolemember('sysadmin') = 1 and suser_sid() <> @dbsid
begin
raiserror(15247,-1,-1)
return (1)
end
-- cannot execute against R/O databases
if DATABASEPROPERTYEX(db_name(), 'Updateability')=N'READ_ONLY'
begin
raiserror(15635,-1,-1,N'sp_updatestats')
return (1)
end

if upper(@resample)<>'RESAMPLE' and upper(@resample)<>'NO'


begin
raiserror(14138, -1, -1, @resample)
return (1)
end
-- required so it can update stats on ICC/IVs
set ansi_warnings on
set ansi_padding on
set arithabort on
set concat_null_yields_null on
set numeric_roundabort off
declare @exec_stmt nvarchar(4000) -- "UPDATE STATISTICS [sysname].[sysname] [s
ysname] WITH RESAMPLE NORECOMPUTE"
declare @exec_stmt_head nvarchar(4000) -- "UPDATE STATISTICS [sysname].[sysname
] "
declare @options nvarchar(100) -- "RESAMPLE NORECOMPUTE"
declare @index_names cursor

declare @ind_name sysname


declare @ind_id int
declare @ind_rowmodctr int
declare @updated_count int
declare @skipped_count int
declare @sch_id int
declare @schema_name sysname
declare @table_name sysname
declare @table_id int
declare @schema_table_name nvarchar(640) -- assuming sysname is 128 chars, 5x t
hat, so it's > 128*4+4
declare @compatlvl tinyint
declare ms_crs_tnames cursor local fast_forward read_only for
select name, object_id, schema_id from sys.objects o
where o.type = 'U' or o.type = 'IT'
open ms_crs_tnames
fetch next from ms_crs_tnames into @table_name, @table_id, @sch_id
-- determine compatibility level
select @compatlvl = cmptlevel from sys.sysdatabases where name = db_name()
while (@@fetch_status <> -1) -- fetch successful
begin
-- generate fully qualified quoted name
select @schema_name = schema_name(@sch_id)
select @schema_table_name = quotename(@schema_name, '[') +'.'+ quotename(rtrim
(@table_name), '[')
-- check for table with disabled clustered index
if (1 = isnull((select is_disabled from sys.indexes where object_id = @table_i
d and index_id = 1), 0))
begin
-- raiserror('Table ''%s'': cannot perform the operation on the table because
its clustered index is disabled', -1, -1, @tablename)
raiserror(15654, -1, -1, @schema_table_name)
end
else
begin
-- filter out local temp tables.
if ((@@fetch_status <> -2) and (substring(@table_name, 1, 1) <> '#'))
begin
-- reset counters for this table
select @updated_count = 0
select @skipped_count = 0
-- print status message
--raiserror('Updating %s', -1, -1, @schema_table_name)
raiserror(15650, -1, -1, @schema_table_name)
-- initial statement preparation: UPDATE STATISTICS [schema].[name]
select @exec_stmt_head = 'UPDATE STATISTICS ' + @schema_table_name + ' '
-- using another cursor to iterate through
-- indices and stats (user and auto-created)
set @index_names = cursor local fast_forward read_only for
select name, indid, rowmodctr from sys.sysindexes
where id = @table_id and indid > 0 and indexproperty(id, name, 'ishypotheti
cal') = 0
order by indid
open @index_names
fetch @index_names into @ind_name, @ind_id, @ind_rowmodctr
-- if there are no stats, skip update
if @@fetch_status < 0
--raiserror(' %d indexes/statistics have been updated, %d did not requir
e update.', -1, -1, @updated_count, @skipped_count)
raiserror(15651, -1, -1, @updated_count, @skipped_count)
else
begin
while @@fetch_status >= 0
begin
-- create quoted index name
declare @ind_name_quoted nvarchar(258)
select @ind_name_quoted = quotename(@ind_name, '[')
-- reset options
select @options = ''
declare @is_ver_current bit
select @is_ver_current = stats_ver_current(@table_id, @ind_id)
-- note that <> 0 should work against old and new rowmodctr logic (when it
is always > 0)
-- also, force a refresh if the stats blob version is not current
if ((@ind_rowmodctr <> 0) or ((@is_ver_current is not null) and (@is_ver_c
urrent = 0)))
begin
select @exec_stmt = @exec_stmt_head + @ind_name_quoted
-- add resample if needed
if (upper(@resample)='RESAMPLE') select @options = 'RESAMPLE '
if (@compatlvl >= 90)
-- put norecompute if local properties are set to AUTOSTATS = OFF
-- note that ind name is unique within the object
if ((select no_recompute from sys.stats where object_id = @table_id and
name = @ind_name) = 1)
begin
if (len(@options) > 0) select @options = @options + ', NORECOMPUTE'
else select @options = 'NORECOMPUTE'
end
if (len(@options) > 0)
select @exec_stmt = @exec_stmt + ' WITH ' + @options
--print @exec_stmt
exec (@exec_stmt)
--raiserror(' %s has been updated...', -1, -1, @ind_name_quoted)
raiserror(15652, -1, -1, @ind_name_quoted)
select @updated_count = @updated_count + 1
end
else
begin
--raiserror(' %s, update is not necessary...', -1, -1, @ind_name_quote
d)
raiserror(15653, -1, -1, @ind_name_quoted)
select @skipped_count = @skipped_count + 1
end
fetch @index_names into @ind_name, @ind_id, @ind_rowmodctr
end
--raiserror(' %d index(es)/statistic(s) have been updated, %d did not re
quire update/disabled.', -1, -1, @updated_count, @skipped_count)
raiserror(15651, -1, -1, @updated_count, @skipped_count)
end
deallocate @index_names
end
end
print ' '
fetch next from ms_crs_tnames into @table_name, @table_id, @sch_id
end
raiserror(15005,-1,-1)
deallocate ms_crs_tnames
return(0) -- sp_updatestats

Potrebbero piacerti anche