create table #db_list
(
	dbname sysname not null,
	user_name sysname null,
	map_type varchar (5) null
)

/*
**  Check to see if any databases are owned by the login.
*/

insert into #db_list (dbname)
	select name from sysdatabases where suid = @login_suid

if @@rowcount <> 0
	begin
		raiserror(15174,-1,-1,@loginame)
		select 'Databases owned by login:' = dbname from #db_list
		return(1)
	end

/*
**  Check to see if the login is mapped to a user in any database.
*/

declare db_name_cursor cursor for select name from sysdatabases
open db_name_cursor

fetch db_name_cursor into @dbname

while @@fetch_status >= 0
	begin
		exec ('use ' + @dbname + ' ' +
		      'insert into #db_list (dbname,user_name,map_type)
			select '''+@dbname+''', name, ''user''
			from sysusers
			where suid = ' + @char_login_suid + '
			union
			select '''+@dbname+''',u.name,''alias''	
			from sysusers u, sysalternates a
			where ' + @char_login_suid + ' = a.suid
				and a.altsuid = u.suid
			')

		--In 6.5 DB context auto reverts back, immediately after dynam exec().

		fetch db_name_cursor into @dbname
	end

if (select count(*) from #db_list) <> 0
	begin
		raiserror(15175,-1,-1,@loginame)

		select
			'Database name:' = dbname,
			'User name:' = user_name,
			'Mapping type:' = map_type
		from #db_list

		deallocate db_name_cursor

		return (1)
	end


deallocate db_name_cursor

/*
** Finally, check if the login owns tasks in msdb since we don't want the tasks to
** get inadvertently re-assigned when a new login is created with the same suid.
*/
if exists (select * from master.dbo.sysdatabases where name = 'msdb')
begin
	create table #retval (taskcount int not null)
	exec ('exec msdb.dbo.sp_MScheckforownedtasks ''#retval'', ''' + @loginame + '''')
	if exists (select taskcount from #retval where taskcount > 0)
	begin	
		declare @task_count int
		select @task_count = taskcount from #retval
		raiserror(14248, -1, -1, @task_count)
		return (1)
	end
end

/*
**  Delete the login, cascading to certain children first.
*/
delete from sysremotelogins where suid = @login_suid
delete from syslogins       where suid = @login_suid

/*
** Check @@rowcount when it works
*/
if @@rowcount > 0
	begin
		raiserror('Login dropped.',0,1)
		return (0)
	end
else
	begin
		raiserror(15007,10,-1,@loginame)
		return (1)
	end
go



raiserror(15339,-1,-1,'sp_dropmessage')
go
create procedure sp_dropmessage
@msgnum int = null,		-- Number of message to drop.
@lang varchar(30) = null	-- Language of message to drop (or 'ALL')
as
declare @retcode int
declare @langid smallint

/*
** If no message id, show usage
*/
if @msgnum is null
	begin
		raiserror(15177,-1,-1)
		return (1)
	end

/*
** Message id must be > 50000
*/
if @msgnum < 50001
	begin
		raiserror(15178,-1,-1)
		return(1)
	end

if (select count(*) from sysmessages where error=@msgnum) = 0
	begin
		raiserror(15179,-1,-1,@msgnum)
		return(1)
	end

/*
** Verify the language
*/
if @lang is null
	select @lang = @@language
if upper(@lang) <> 'ALL'
begin
	begin
		exec @retcode = sp_validlang @lang
		if @retcode <>  0
			return(1)
	end
	/*
	** Get langid from syslanguages; us_english won't exist, so use 0.
	*/
	select @langid = isnull((select langid from syslanguages where name = @lang),0)
end

/*
** The us_english version must be the last one to be dropped
*/
if (@langid = 0) and (select count(*) from sysmessages where error = @msgnum) > 1
begin
	raiserror(15280,-1,-1)
	return(1)
end

/*
**  Drop the message.
*/
if upper(@lang) = 'ALL'
	delete from sysmessages where error = @msgnum
else
	delete from sysmessages where error = @msgnum and langid = @langid

print 'Message dropped.'
return (0)
go


raiserror(15339,-1,-1,'sp_droptype')
go
create procedure sp_droptype
@typename varchar(30)			/* the user type to drop */
as

declare @typeid smallint		/* the typeid of the usertype to drop */

/*
**  Initialize @typeid so we can tell if we can't find it.
*/
select @typeid = 0

/*
**  Find the user type with @typename.  It must be a user type (usertype > 99)
**  and it must be owned by the person (or dbo) running the procedure.
*/
select @typeid = usertype
	from systypes
		where (uid = user_id() or user_id() = 1)
			and name = @typename
			and usertype > 99

if @typeid = 0
	begin
		raiserror(15105,-1,-1)
		return (1)
	end

/*
**  Check to see if the type is being used.  If it is, it can't be dropped.
*/
if exists (select * from syscolumns where usertype = @typeid)
	begin
		raiserror(15180,-1,-1)

		/*
		**  Show where it's being used.
		*/
		select object = o.name, type = o.type, owner = u.name,
			column = c.name, datatype = t.name
		from syscolumns c, systypes t, sysusers u, sysobjects o
		where c.usertype = @typeid
			and t.usertype = @typeid
			and o.uid = u.uid
			and c.id = o.id
		order by object, column

		return (1)
	end

/*
**  Everything is consistent so drop the type.
*/
delete from systypes where usertype = @typeid

print 'Type has been dropped.'

return (0)
go


raiserror(15339,-1,-1,'sp_dropuser')
go
create procedure sp_dropuser
@name_in_db varchar(30)			/* user name to drop */
as

declare @suid int				/* suid of the user */
declare @uid int				/* uid of the user */
declare @objectcount int		/* count of objects user owns */
declare @typecount int			/* count of types user owns */
declare	@userdropped int		/* flag to indicate user was dropped */
declare @privcount int                  /* count of occurrences as Grantor */

/*
**  You must be SA or the dbo to execute this sproc.
*/
if suser_id() <> 1 and user_id() <> 1
	begin
		raiserror(15000,-1,-1)
		return (1)
	end

/*
**  See if the user exists in the database.
**  User ids are <= 16383 and group ids are > 16383.
*/
select @uid = uid, @suid = suid
	from sysusers
		where name = @name_in_db
			and uid <= 16383 and uid > 0

/*
**  No such user so return.
*/
if @uid is null
	begin
		raiserror(15008,-1,-1,@name_in_db)
		return (1)
	end

/*
**  Can't drop database owner.
*/
if @uid = 1
	begin
		raiserror(15181,-1,-1)
		return (1)
	end

/*
**  Trouble if guest gets dropped from master or tempdb, so check.
*/
if (@name_in_db = 'guest' and (db_id() = 1 or db_id() = 2))
	begin
		raiserror(15182,-1,-1)
		return(1)
	end

/*
**  If the user owns any objects or datatypes or is a grantor,
**  and we're not forcing the drop, return without doing anything.
*/
select @objectcount = count(*)
	   from sysobjects
		   where uid = @uid
select @typecount = count(*)
	from systypes
		where uid = @uid
select @privcount = count(*)
	from sysprotects
	where grantor = @uid


if @objectcount > 0 or @typecount > 0 or @privcount > 0
begin
	if @objectcount > 0
		begin
			raiserror(15183,-1,-1)
			select name, type
				from sysobjects
					where uid = @uid
		end

	if @typecount > 0
		begin
			raiserror(15184,-1,-1)
			select user_type = a.name, physical_type = b.name
				from systypes a, systypes b
					where a.uid = @uid
						and a.type = b.type
						and b.usertype < 100
		end

	if @privcount > 0
		begin
			raiserror(15284,-1,-1)
			select 'Grantee'=user_name(uid) ,'Object'=object_name(id)
				from sysprotects
				where grantor = @uid
		end

	return (1)
end


/*
**  Drop the user.
**  Also drop any references to the user in the sysprotects table.
**  If anyone is aliased to the user, drop them also.
*/
begin transaction

	delete from sysusers
		where suid = @suid
	select @userdropped = @@rowcount

	delete from sysprotects
		where uid = @uid

	/*
	**  Drop any dependent aliases.
	*/
	if exists (select *
			from sysalternates
				where altsuid = @suid)
	begin
		delete from sysalternates
			where altsuid = @suid

		print 'The dependent aliases were also dropped.'
	end

if @userdropped = 1
	commit transaction
else rollback transaction

print 'User has been dropped from current database.'

return (0)
go

dump transaction master with no_log
go

raiserror(15339,-1,-1,'sp_dropremotelogin')
go
create procedure sp_dropremotelogin
@remoteserver	varchar(30),		/* name of remote server */
@loginame varchar(30) = NULL,		/* user's remote name */
@remotename varchar(30) = NULL		/* user's local user name */
as

declare @suid	smallint

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_dropremotelogin')
		return (1)
	end

/*
**  If @loginame is NULL then we want to set @suid = -1. Otherwise get
**  it real value.
*/
if @loginame is null
	select @suid = -1
else
	select @suid = suser_id(@loginame)

/*
**  Delete the remote login.
*/
delete sysremotelogins
	from sysremotelogins l, sysservers s
	where l.remoteserverid = s.srvid
		and s.srvname = @remoteserver
		and l.remoteusername = @remotename
		and l.suid = @suid

/*
** Check @@rowcount when it works
*/
if @@rowcount > 0
	begin
		print 'Remote login dropped.'
		return (0)
	end
else
	begin
		raiserror(15185,-1,-1,@remotename,@loginame,@remoteserver)
		return (1)
	end
go


raiserror(15339,-1,-1,'sp_dropsegment')
go
create procedure sp_dropsegment
@segname	varchar(30),		/* segment name */
@device		varchar(30) = null	/* device name */
as

declare @dbuid	smallint	/* id of the owner of the database */
declare @segbit	int		/* this is the bit to turn on in sysusages */
declare	@msg	varchar(200)
declare @dbname varchar(30)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_dropsegment')
		return (1)
	end

/*
**  You must be SA or the dbo to execute this sproc.
*/
if suser_id() <> 1 and user_id() <> 1
	begin
		raiserror(15000,-1,-1)
		return (1)
	end

/*
**  There are two drop cases:
**	1) dropping the segment
**	2) dropping a segment reference to a device
**  The sproc does things differently depending on which we're doing.
*/

/*
**  Check to see if the segment exists.
*/
if not exists (select * from syssegments where name = @segname)
	begin
		raiserror(15018,-1,-1,@segname)
		return (1)
	end

/*
**  Get the segment number of @segname.
*/
select @segbit = segment
	from syssegments
		where name = @segname

/*
**  Now convert the segment number to the right bit for segmap.
*/
if (@segbit < 31)
	select @segbit = power(2, @segbit)
else
	/*
	**  Since this is segment 31, power(2, 31) will overflow
	**  since segmap is an int.  We'll grab the machine-dependent
	**  bit mask from spt_values to clear the right bit.
	*/
	select @segbit = low
		from master.dbo.spt_values
		where type = 'E'
			and number = 2

/*
**  Don't allow the segments 'default', 'system', or 'logsegment' to
**  be dropped completely.
*/
if @segname in ('system', 'default', 'logsegment')
	begin
		if @device is null
			begin
				raiserror(15186,-1,-1,@segname)
				return (1)
			end

		/*
		**  For the case where we are dropping the logsegment from a
		**  device, the logic below works OK.  If this is the last
		**  device for the the segment, it won't let the segment be
		**  dropped.
		*/
	end


/*
**  If we are dropping the segment, check to see that the segment isn't
**  being used by anyone.
*/
if @device is null
	begin
		/*
		**  Check to see if the segment is being used.
		*/
		if exists (select *
			from sysindexes i, syssegments s
				where s.name = @segname
					and i.segment = s.segment)
			begin
				raiserror(15187,-1,-1,@segname)
				return (1)
			end
	end

/*
**  If we are dropping the segment reference, check to see that arguments are
**  reasonable.
*/
if @device IS NOT NULL
begin
	/*
	**  Now see if the database even uses the @device
	*/
	if not exists (select *
			from sysusages u, sysdevices d
			where d.name = @device
				and u.vstart between d.low and d.high
				and u.dbid = db_id())
		begin
			select @dbname=db_name()
			raiserror(15073,-1,-1,@device,@dbname)
			return (1)
		end

	/*
	**  Now check that the segment references the device.
	*/
	if not exists (select *
			from sysusages u, sysdevices d
			where u.segmap & @segbit = @segbit
				and d.name = @device
				and d.low <= u.size + u.vstart
				and d.high >= u.size + u.vstart - 1
				and u.dbid = db_id()
				and d.status & 2 = 2)
		begin
			raiserror(15188,-1,-1,@segname,@device)
			return (1)
		end

	/*
	**  Now check to see if this is the last unique device reference for the
	**  segment.  If it is then we don't want to drop the reference.
	*/
	select distinct d.name into #temptable
		from sysusages u, sysdevices d
		where u.segmap & @segbit = @segbit
			and d.low <= u.size + u.vstart
			and d.high >= u.size + u.vstart - 1
			and u.dbid = db_id()
			and d.status & 2 = 2

	if (select count(*) from #temptable) <= 1
		begin
			raiserror(15189,-1,-1,@segname)
			return (1)
		end

	drop table #temptable
end

/*
**  If we're dropping the segment, go ahead drop the segment and
**  clear its bit in sysusages.
*/
if @device is null
begin
	/*
	**  NOTE: Don't update master..sysusages and syssegments as a xact since
	**  	it could cause problems for recovery.
	*/

	delete syssegments where name = @segname

	/*
	**  Now clear the segment from device in sysusages.
	*/
	update sysusages set segmap = segmap & (~@segbit)
		from sysusages u, sysdevices d
		where d.low <= u.size + u.vstart
			and d.high >= u.size + u.vstart - 1
			and u.dbid = db_id()
			and d.status & 2 = 2
end

/*
**  We want to just clear the segment reference from the device.
*/
else
begin
	update sysusages set segmap = segmap & (~@segbit)
		from sysusages u, sysdevices d
		where d.low <= u.size + u.vstart
			and d.high >= u.size + u.vstart - 1
			and u.dbid = db_id()
			and d.status & 2 = 2
			and d.name = @device

end

/*
**  Now we need to activate the new segment map.
*/
select @dbname = db_name()
dbcc dbrepair (@dbname, remap)

if @device is null
	print 'Segment dropped.'
else print 'Segment reference to device dropped.'

/*
**  If there are no more segment references to the device,
**  print a warning.
*/
if exists (select *
		from sysusages
			where segmap = 0
				and dbid = db_id())
begin
	declare @nosegs	varchar(255),	/* list of unreferenced devices */
		@curdevice varchar(30),
		@i int

	select @curdevice = min(d.name)
		from sysusages u, sysdevices d
		where d.low <= u.size + u.vstart
			and d.high >= u.size + u.vstart - 1
			and u.dbid = db_id()
			and d.status & 2 = 2
			and segmap = 0
	select @nosegs = @curdevice, @i = 1
	while (@curdevice IS NOT NULL)
	begin
		select @curdevice = min(d.name)
			from sysusages u, sysdevices d
			where d.low <= u.size + u.vstart
				and d.high >= u.size + u.vstart - 1
				and u.dbid = db_id()
				and d.status & 2 = 2
				and segmap = 0
				and d.name > @curdevice
		if @curdevice IS NOT NULL
		begin
			select @nosegs = @nosegs + ', ' + @curdevice
			select @i = @i + 1
		end
	end

	/*
	**  Get the device names.
	*/
	select @msg =  'WARNING: There are no longer any segments referencing '
	if @i > 1
		select @msg = @msg + 'devices '''
	else select @msg = @msg + 'device '''
	select @msg = @msg + @nosegs + '''. '
	if @i > 1
		select @msg = @msg + 'These devices '
	else select @msg = @msg + 'This device '
	select @msg = @msg + 'will no longer be used for space allocation.'
	print @msg
end
return (0)
go


raiserror(15339,-1,-1,'sp_dropserver')
go
create procedure sp_dropserver
@server	varchar(30),			/* server name */
@droplogins	char(10) = NULL		/* drop all related logins? */
as

declare	@msg varchar(200)
declare	@distributor varchar(30)
declare	@distribdb varchar(30)
declare	@distproc varchar(255)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_dropserver')
		return (1)
	end

/*
**  Check to see if the server exists.
*/
if not exists (select * from sysservers where srvname = @server)
	begin
		raiserror(15015,-1,-1,@server)
		return (1)
	end

/*
**  Check to see if there are any related logins in sysremotelogins.
*/
if @droplogins is null
	begin
		if exists (select * from sysremotelogins l,
				sysservers s
			where s.srvid = l.remoteserverid
				and s.srvname = @server)
			begin
				raiserror(15190,-1,-1,@server)
				return (1)
			end
	end

/*
**  If @droplogins is true then drop any associated logins
*/
else if lower(@droplogins) = 'droplogins'
begin
	begin transaction dropserver

		delete sysremotelogins
			from sysremotelogins l,
				sysservers s
			where s.srvid = l.remoteserverid
				and s.srvname = @server
		if @@rowcount > 0
		begin
			select @msg = 'Remote logins for remote server '''
				+ @server + ''' have been dropped.'
			print @msg
		end

		delete sysservers where srvname = @server

		print 'Server dropped.'

	commit transaction dropserver

	return (0)
end

/*
**  Bad argument to @droplogins.
*/
else
	begin
		raiserror(15191,-1,-1)
		return (1)
	end

/*
** Drop server information from distribution database MSsubscriber_info table
*/
exec sp_helpdistributor @distributor = @distributor OUTPUT,
   @distribdb = @distribdb OUTPUT

if @distributor is not null and @distribdb is not null
  begin
     select @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) +
        '..sp_MSdrop_subscriber_info '
     exec @distproc @@SERVERNAME, @server
  end

/*
**  Drop the server.
*/
delete sysservers where srvname = @server

print 'Server dropped.'

return (0)
go


raiserror(15339,-1,-1,'sp_extendsegment')
go
create procedure sp_extendsegment
@segname varchar(30),	/* segment name */
@devname varchar(30)	/* device name to put segment on */
as

declare @dbuid  smallint        /* id of the owner of the database */
declare @segbit	int		/* this is the bit to turn on in sysusages */
declare	@msg	char(100)
declare @dbname varchar(30)
declare @retcode	int

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_extendsegment')
		return (1)
	end

/*
**  You must be SA or the dbo to execute this sproc.
*/
if suser_id() <> 1 and user_id() <> 1
	begin
		raiserror(15000,-1,-1)
		return (1)
	end

/*
**  Check to see if the segment exists.
*/
if not exists (select * from syssegments where name = @segname)
	begin
		raiserror(15018,-1,-1,@segname)
		return (1)
	end

/*
**  See if the device exists.
*/
if not exists (select * from sysdevices where name like @devname)
	begin
		raiserror(15012,-1,-1,@devname)
		return (1)
	end

/*
**  Now see if the @dbname uses the @devname
*/

if not exists (select * from sysusages u, sysdevices d
			where d.name = @devname
				and u.vstart between d.low and d.high
				and u.dbid = db_id())
	begin
		select @dbname=db_name()
		raiserror(15073,-1,-1,@devname,@dbname)
		return (1)
	end

/*
**  Check to see if the device is marked as a log device.
**  If so, print error.
*/
if exists (select * from sysusages u, sysdevices d
		where d.name = @devname
			and u.vstart between d.low and d.high
			and u.dbid = db_id()
			and segmap = 4)
	begin
		raiserror(15074,-1,-1,@devname)
		return (1)
	end

/*
** Check for valid identifier.
*/
execute @retcode = sp_validname @segname
if @retcode <> 0
	return (1)

/*
**  Now go ahead and define the new segment and add it to the segmap
**  of sysusages.
**  NOTE: Don't update master..sysusages and syssegments as a xact since
**  	it could cause problems for recovery.
*/

/*
**  Get the segment number for @segname.
*/
select @segbit = segment
	from syssegments
		where name = @segname

/*
**  If @segbit is 2 then it's the logsegment and the logsegment
**  doesn't share devices with other segments.  If this is the original
**  device, we must maintain a data segment since logical page 0
**  resides here, so exit.  If not, go ahead and make the change but
**  don't OR the @segbit in but just set segmap to 4.
*/
if @segbit = 2
begin
	/*
	**  First check to see if this is the original device
	*/
	if exists (select * from sysusages u, sysdevices d
			where d.name = @devname
				and u.vstart between d.low and d.high
				and u.dbid = db_id()
				and lstart = 0)
		begin
			raiserror(15192,-1,-1)
			return (1)
		end

	else
		update sysusages set segmap = 4
			from sysusages u, sysdevices d
			where d.name = @devname
				and u.vstart between d.low and d.high
				and u.dbid = db_id()
end

else
begin
	if (@segbit < 31)
		select @segbit = power(2, @segbit)
	else
		/*
		**  Since this is segment 31, power(2, 31) will
		**  overflow since segmap is an int.  We'll grab the
		**  machine-dependent bit mask from spt_values to set
		**  the right bit.
		*/
		select @segbit = low
			from master.dbo.spt_values
			where type = 'E'
				and number = 2
	/*
	**  Add the segment to @devname in sysusages.
	*/
	update sysusages set segmap = segmap | @segbit
			from sysusages u, sysdevices d
			where d.name = @devname
				and u.vstart between d.low and d.high
				and u.dbid = db_id()
end

/*
**  Now we need to activate the new segment map.
*/
select @dbname = db_name()
dbcc dbrepair (@dbname, remap)
print 'Segment extended.'

/*
**  Get the segment number for @segname.
*/
select @segbit = segment
	from syssegments
		where name = @segname

/*
**  If we are extending the logsegment, print out a message about what it
**  means to do so.
*/
if @segbit = 2
	begin
		select @msg = 'Device ''' + @devname
			+ ''' is now exclusively used by '''
			+ @segname + '''.'
		print @msg
	end

return (0)
go


raiserror(15339,-1,-1,'sp_fixindex')
go
create procedure sp_fixindex
		@dbname		varchar(30),
		@tabname	varchar(30),  		/* system table name */
		@indid		int					/* index id value    */
as
	/*
	**	Description:	allow the SA to force a drop and then a
	**			create index on system catalogs.
	**
	**	Usage:		sp_fixindex  database, systemcatalog, ind_id
	**
	**	Note:		before using this procedure the database has to
	**			be in single user mode. The sp_dboption has to
	**			be used for user databases, and update of
	**			sysdatabases for master.
	**
	*/

	declare	@ramboix smallint			/* mask for rambo indx*/
	declare @badlist  varchar(255)   /* name list of all tables that should
					      not have any indexes on them */
	/*
	**	Initialize name lists. These will be used in catching
	**	any attempts to fix indexes on fake tables or tables
	**	that have no indexes on them.
	*/
	select @badlist = 'syslocks, sysprocesses, syscurconfig,
			   syssegments, syslogckp'

	/*
	**	Make sure we are 'fixing' a system catalog.
	*/
	if @tabname NOT LIKE 'sys%'
		begin
			raiserror(15193,-1,-1)
			return (1)
		end

	/*
	**	Make sure that we are doing this on somenthing that
	**	has indexes (or real tables).
	*/
	if @badlist LIKE  '%' + @tabname + '%'
		begin
			raiserror(15194,-1,-1)
			return (1)
		end

	/*
	**	At this point we are sure that the table has an index
	**	of requested type, so all there is to be done is to
	**	set the ramboix bit for this object unless we try to
	**	fix Sysobjects.
	*/
	if @tabname <> 'sysobjects'
	begin
		/* Use decimal integer equivalent of hex 1000 to avoid
		** byte order issues.
		*/
		select @ramboix = 4096
		update sysobjects set sysstat = sysstat | @ramboix
		where name = @tabname

		checkpoint
	end

	/*
	**	Call dbcc to do the job.
	*/
	dbcc dbrepair(@dbname, REPAIRINDEX, @tabname, @indid)

	/*
	**	Processing successfully done, so turn off the ramboix
	**	bit if not sysobjects, and tell the user that all is fine.
	*/
	if @tabname <> 'sysobjects'
	begin
		update sysobjects set sysstat = sysstat & ~@ramboix
		where name = @tabname

		checkpoint
	end

	return (0)
go


raiserror(15339,-1,-1,'sp_foreignkey')
go
create procedure sp_foreignkey
@tabname  varchar(92),		/* name of table that we are doing */
@pktabname varchar(92),		/* name of table with primary key */
@col1     varchar(30), 		/* column name of table we are doing */
@col2     varchar(30) = NULL,
@col3     varchar(30) = NULL,
@col4     varchar(30) = NULL,
@col5     varchar(30) = NULL,
@col6     varchar(30) = NULL,
@col7     varchar(30) = NULL,
@col8     varchar(30) = NULL
as

declare @objida int	/* id of table we are doing */
declare @objidb int	/* id of table with primary key */
declare @uid smallint	/* id of owner of the table */
declare @cnt    int	/* how many columns are in foreign key */

declare @pkey1 int	/* colids of the foreign key */
declare @pkey2 int
declare @pkey3 int
declare @pkey4 int
declare @pkey5 int
declare @pkey6 int
declare @pkey7 int
declare @pkey8 int

declare @fkey1 int	/* colids of the primary key */
declare @fkey2 int
declare @fkey3 int
declare @fkey4 int
declare @fkey5 int
declare @fkey6 int
declare @fkey7 int
declare @fkey8 int

/*
**  Check to see that the tabname is local.
*/
if @tabname like '%.%.%'
	and substring(@tabname, 1, charindex('.', @tabname) - 1) <> db_name()
	begin
		raiserror(15078,-1,-1)
		return (1)
	end

if @pktabname like '%.%.%'
	and substring(@pktabname, 1, charindex('.', @pktabname) - 1) <> db_name()
	begin
		raiserror(15078,-1,-1)
		return (1)
	end

/*
**  See if we can find the objects.  They must be a system table, user table,
**  or view.  The low 4 bits of sysobjects.sysstat indicate what the
**  object type is -- it's more reliable than using sysobjects.type which
**  could change.
*/
select @objida = id, @uid = uid
	from sysobjects
		where id = object_id(@tabname)
			and (sysstat & 0xf = 1	/* system table */
				or sysstat & 0xf = 2	/* view */
				or sysstat & 0xf = 3)	/* user table */
/*
**  If either of the tables don't exist, quit.
*/
if @objida is NULL
	begin
		raiserror(15151,-1,-1)
		return (1)
	end

select @objidb = id
	from sysobjects
		where id = object_id(@pktabname)
			and (sysstat & 0xf = 1
				or sysstat & 0xf = 2
				or sysstat & 0xf = 3)
if @objidb is NULL
	begin
		raiserror(15152,-1,-1)
		return (1)
	end

/*
**  Only the owner of the table can define its foreign keys.
*/
if @uid <> user_id()
	begin
		raiserror(15153,-1,-1)
		return (1)
	end

/*
**  Now check to see that the foreign key columns exist.
*/
select @cnt = 1, @fkey1 = colid
	from syscolumns
		where name = @col1
			and id = @objida
if @fkey1 is null
	begin
		raiserror(15154,-1,-1)
		return (1)
	end

if @col2 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey2 = colid
			from syscolumns
			where name = @col2
			and id = @objida

		if @fkey2 is NULL
			begin
				raiserror(15155,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col3 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey3 = colid
			from syscolumns
			where name = @col3
			and id = @objida

		if @fkey3 is NULL
			begin
				raiserror(15156,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col4 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey4 = colid
			from syscolumns
			where name = @col4
			and id = @objida

		if @fkey4 is NULL
			begin
				raiserror(15157,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col5 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey5 = colid
			from syscolumns
			where name = @col5
			and id = @objida

		if @fkey5 is NULL
			begin
				raiserror(15158,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col6 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey6 = colid
			from syscolumns
			where name = @col6
			and id = @objida

		if @fkey6 is NULL
			begin
				raiserror(15159,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col7 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey7 = colid
			from syscolumns
			where name = @col7
			and id = @objida

		if @fkey7 is NULL
			begin
				raiserror(15160,-1,-1)
				return (1)
			end
	end
else goto foreign_ok

if @col8 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @fkey8 = colid
			from syscolumns
			where name = @col8
			and id = @objida

		if @fkey8 is NULL
			begin
				raiserror(15161,-1,-1)
				return (1)
			end
	end


/*
**  If we made it this far then all the columns for the foreign key are ok.
*/
foreign_ok:

/*
**  Now let's check out the primary key that the foreign key is on.
**  There must be the same number of columns in the key and the
**  base types of the columns must agree.
*/
select @pkey1 = key1, @pkey2 = key2, @pkey3 = key3, @pkey4 = key4,
	@pkey5 = key5, @pkey6 = key6, @pkey7 = key7, @pkey8 = key8
		from syskeys
	where id = @objidb
		and type = 1
		and keycnt = @cnt

/*
**  If @pkey1 is null then there is no such primary key or the number of
**  columns in the primary key are not the same as the number of columns
**  in the foreign key.
*/
if @pkey1 is null
begin
	if exists (select * from syskeys where id = @objidb and type = 1)
		raiserror(15162,-1,-1)
	else
		raiserror(15163,-1,-1)

	return (1)
end

/*
**  Since we have the right number of columns in the foreign and primary keys,
**  check that their base datatypes agree.
*/
if not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey1
			and a.id = @objida
			and b.colid = @pkey1
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15164,-1,-1)
		return (1)
	end

if @fkey2 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey2
			and a.id = @objida
			and b.colid = @pkey2
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15165,-1,-1)
		return (1)
	end
else goto doinsert

if @fkey3 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey3
			and a.id = @objida
			and b.colid = @pkey3
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15166,-1,-1)
		return (1)
	end
else goto doinsert

if @fkey4 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey4
			and a.id = @objida
			and b.colid = @pkey4
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15167,-1,-1)
		return (1)
	end

if @fkey5 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey5
			and a.id = @objida
			and b.colid = @pkey5
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15168,-1,-1)
		return (1)
	end
else goto doinsert

if @fkey6 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey6
			and a.id = @objida
			and b.colid = @pkey6
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15169,-1,-1)
		return (1)
	end
else goto doinsert

if @fkey7 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey7
			and a.id = @objida
			and b.colid = @pkey7
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15170,-1,-1)
		return (1)
	end
else goto doinsert

if @fkey8 IS NOT NULL and not exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.colid = @fkey8
			and a.id = @objida
			and b.colid = @pkey8
			and b.id = @objidb
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
	begin
		raiserror(15171,-1,-1)
		return (1)
	end

/*
**  Everything is consistent so add the foreign key to syskeys.
*/
doinsert:

insert syskeys (id, type, depid, keycnt, size, key1, key2, key3, key4, key5,
	key6, key7, key8, depkey1, depkey2, depkey3, depkey4, depkey5,
	depkey6, depkey7, depkey8)
values (@objida, 2, @objidb, @cnt, 0, @fkey1, @fkey2, @fkey3, @fkey4, @fkey5,
	@fkey6, @fkey7, @fkey8, @pkey1, @pkey2, @pkey3, @pkey4, @pkey5,
	@pkey6, @pkey7, @pkey8)

print 'New foreign key added.'

return (0)
go



raiserror(15339,-1,-1,'sp_helpconstraint')
go
create procedure sp_helpconstraint --1995/12/05 08:40
    @objname varchar(92)             -- the table to check for constraints
   ,@nomsg   varchar(5) = 'msg'      -- 'nomsg' supresses printing of TBName (sp_help)
as

set nocount on

declare @objid    int           -- the object id of the table
       ,@indid    int           -- the index id of an index
       ,@cnstdes  varchar(255)  -- string to build up index desc
       ,@cnstname varchar(30)   -- name of const. currently under consideration
       ,@tptr     varbinary(16) -- pointer for building text strings.
       ,@i          int
       ,@thiskey    varchar(32)
       ,@cnstid     int
       ,@cnststatus int
       ,@numkeys    int
       ,@rkeyid     int
       ,@fkeyid     int
       ,@dbname     varchar(30)

declare
         @fkey1  int ,@fkey2  int ,@fkey3  int ,@fkey4  int ,@fkey5  int
        ,@fkey6  int ,@fkey7  int ,@fkey8  int ,@fkey9  int ,@fkey10 int
        ,@fkey11 int ,@fkey12 int ,@fkey13 int ,@fkey14 int ,@fkey15 int
        ,@fkey16 int

declare
         @rkey1  int ,@rkey2  int ,@rkey3  int ,@rkey4  int ,@rkey5  int
        ,@rkey6  int ,@rkey7  int ,@rkey8  int ,@rkey9  int ,@rkey10 int
        ,@rkey11 int ,@rkey12 int ,@rkey13 int ,@rkey14 int ,@rkey15 int
        ,@rkey16 int

declare
       @bitDisabled           integer
      ,@bitNotForReplication  integer
--------

select
       @bitDisabled           = 0x4000
      ,@bitNotForReplication  = 0x200000


---- Check to see that the object names are local to the current database.

if      @objname like '%.%.%'
   and  substring(@objname, 1, charindex('.', @objname) - 1) <> db_name()
   begin
   raiserror(15250,-1,-1)
   return (1)
   end


---- Check to see if the table exists and initialize @objid.

select @objid = object_id(@objname)


---- Table does not exist so return.

if @objid is NULL
   begin
   select @dbname=db_name()
   raiserror(15009,-1,-1,@objname,@dbname)
   return (1)
   end


declare cnst_csr cursor for
     select   c.constid, c.status, o.name
        from  sysconstraints c, sysobjects o
        where c.id = @objid and o.id = c.constid
        for read only


---- Now check out each constraint, figure out its type and keys and
---- save the info in a temporary table that we'll print out at the end.

create table #spcnsttab
(
    rowid               int           NOT NULL  identity
   ,cnst_type           varchar(48)   NOT NULL   -- 30 for name + text for DEFAULT
   ,cnst_name           varchar(30)   NOT NULL
   ,cnst_nonblank_name  varchar(30)   NOT NULL
   ,cnst_status         integer           NULL
   ,cnst_keys           text              NULL
)

create table #spcnstkeys
(
    cnst_colid int NOT NULL
)

open cnst_csr

fetch cnst_csr into @cnstid, @cnststatus, @cnstname

while @@fetch_status >= 0
   begin

   if ((@cnststatus & 0xf) in (1,2)) -- primary key, unique
      begin

      if ((@cnststatus & 0xf) = 1)
         select @cnstdes = 'PRIMARY KEY'
      else
         select @cnstdes = 'UNIQUE'

      select   @indid = indid
         from  sysindexes, sysobjects
         where sysobjects.id = @cnstid
         and   sysindexes.name = sysobjects.name

      if (@indid > 1)
         select @cnstdes = @cnstdes + ' (non-clustered)'
      else
         select @cnstdes = @cnstdes + ' (clustered)'

      ---- First we'll figure out what the keys are.

      select @i = 1

      while (@i <= 16)
         begin

         select @thiskey = index_col(@objname, @indid, @i)

         if @thiskey is NULL
            goto keysdone

         if @i=1
            begin
            insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
               values (@cnstdes, @cnstname,@cnstname, @thiskey)

            select @tptr = textptr(cnst_keys) from #spcnsttab
            end
         else
            begin
            select @thiskey = ', ' + @thiskey

            if @tptr is not null
               updatetext #spcnsttab.cnst_keys @tptr null null @thiskey
            end

         select @i = @i + 1
         end --loop 16


         ---- When we get here we now have all the keys.

keysdone:

      end
   else   -- not pkey,ukey

      if ((@cnststatus & 0xf) = 3) /* foreign key */
         begin
         select @cnstdes = 'FOREIGN KEY'

         select
                @fkeyid = fkeyid, @rkeyid = rkeyid,
                @fkey1=fkey1, @fkey2=fkey2, @fkey3=fkey3,
                @fkey4=fkey4, @fkey5=fkey5, @fkey6=fkey6,
                @fkey7=fkey7, @fkey8=fkey8, @fkey9=fkey9,
                @fkey10=fkey10, @fkey11=fkey11,
                @fkey12=fkey12, @fkey13=fkey13,
                @fkey14=fkey14, @fkey15=fkey15,
                @fkey16=fkey16,
                @rkey1=rkey1, @rkey2=rkey2, @rkey3=rkey3,
                @rkey4=rkey4, @rkey5=rkey5, @rkey6=rkey6,
                @rkey7=rkey7, @rkey8=rkey8, @rkey9=rkey9,
                @rkey10=rkey10, @rkey11=rkey11,
                @rkey12=rkey12, @rkey13=rkey13,
                @rkey14=rkey14, @rkey15=rkey15,
                @rkey16=rkey16
            from  sysreferences
            where constid = @cnstid

         insert into #spcnstkeys values(@fkey1)
         insert into #spcnstkeys values(@fkey2)
         insert into #spcnstkeys values(@fkey3)
         insert into #spcnstkeys values(@fkey4)
         insert into #spcnstkeys values(@fkey5)
         insert into #spcnstkeys values(@fkey6)
         insert into #spcnstkeys values(@fkey7)
         insert into #spcnstkeys values(@fkey8)
         insert into #spcnstkeys values(@fkey9)
         insert into #spcnstkeys values(@fkey10)
         insert into #spcnstkeys values(@fkey11)
         insert into #spcnstkeys values(@fkey12)
         insert into #spcnstkeys values(@fkey13)
         insert into #spcnstkeys values(@fkey14)
         insert into #spcnstkeys values(@fkey15)
         insert into #spcnstkeys values(@fkey16)

         delete from #spcnstkeys where cnst_colid = 0

         ---- Need a unique index so we can use a cursor.

         create unique index ind1 on #spcnstkeys(cnst_colid)

         execute('declare fkey_curs cursor for
                     select cnst_colid from #spcnstkeys
                     for read only')

         open fkey_curs

         fetch fkey_curs into @i

         select @numkeys=1

         while @@fetch_status >= 0
            begin
            select @thiskey = col_name(@fkeyid, @i)

            ---- No comma for fist key column.

            if @numkeys = 1
               begin
               insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
                  values (@cnstdes, @cnstname,@cnstname, @thiskey)

               select @tptr = textptr(cnst_keys) from #spcnsttab
               end
            else
               begin
               select @thiskey = ', ' + @thiskey

               if @tptr is not null
                  updatetext #spcnsttab.cnst_keys @tptr null null @thiskey
               end

            select @numkeys=@numkeys+1

            fetch fkey_curs into @i
            end --loop key fetch


         ---- When we get here we now have all the keys.

         truncate table #spcnstkeys

         drop index #spcnstkeys.ind1

         deallocate fkey_curs

         insert into #spcnstkeys values(@rkey1)
         insert into #spcnstkeys values(@rkey2)
         insert into #spcnstkeys values(@rkey3)
         insert into #spcnstkeys values(@rkey4)
         insert into #spcnstkeys values(@rkey5)
         insert into #spcnstkeys values(@rkey6)
         insert into #spcnstkeys values(@rkey7)
         insert into #spcnstkeys values(@rkey8)
         insert into #spcnstkeys values(@rkey9)
         insert into #spcnstkeys values(@rkey10)
         insert into #spcnstkeys values(@rkey11)
         insert into #spcnstkeys values(@rkey12)
         insert into #spcnstkeys values(@rkey13)
         insert into #spcnstkeys values(@rkey14)
         insert into #spcnstkeys values(@rkey15)
         insert into #spcnstkeys values(@rkey16)

         delete from #spcnstkeys where cnst_colid = 0

         ---- Need a unique index so we can use a cursor.

         create unique index ind1 on #spcnstkeys(cnst_colid)

         insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
            select
                      ' ' ,' ' ,@cnstname
                     ,'REFERENCES ' + rtrim(db_name(rkeydbid))
                           + '.' + rtrim(
                  (select user_name(uid) from sysobjects where id = @rkeyid
                  )
                                        )
                           + '.'+object_name(@rkeyid) + ' ('
               from  sysreferences
               where constid = @cnstid

         select @tptr = textptr(cnst_keys) from #spcnsttab

         execute('declare rkey_curs cursor for
                     select cnst_colid from #spcnstkeys
                     for read only')

         open rkey_curs

         fetch rkey_curs into @i

         select @numkeys=1

         while @@fetch_status >= 0
            begin
            select @thiskey = col_name(@rkeyid, @i)

            ---- No comma for first key column.

            if @numkeys <> 1
               select @thiskey = ', ' + @thiskey

            if @tptr is not null
               updatetext #spcnsttab.cnst_keys @tptr null null @thiskey

            select @numkeys=@numkeys+1

            fetch rkey_curs into @i
            end --loop


         ---- When we get here we now have all the keys.

         if @tptr is not null
            updatetext #spcnsttab.cnst_keys @tptr null null ')'

         truncate table #spcnstkeys

         drop index #spcnstkeys.ind1

         deallocate rkey_curs
         end
      else
         if ((@cnststatus & 0xf) = 4)    -- check constraint
            begin
            select @i = 1

            select @cnstdes = text from syscomments
               where id = @cnstid and colid = @i

            while @cnstdes is not null
               begin

               if @i=1
                  begin
                  -- Get Table Check constraint
                  insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
                     select   'CHECK Table Level ',@cnstname,@cnstname,' '
                        from  sysconstraints
                        where colid = 0 and constid = @cnstid

                  -- Column Level Check
                  insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
                     select 'CHECK on column ' + col_name(id, colid)
                           ,@cnstname,@cnstname,' '
                        from  sysconstraints
                        where colid > 0 and constid = @cnstid

                  select @tptr = textptr(cnst_keys) from #spcnsttab

                  if @tptr is not null
                  updatetext #spcnsttab.cnst_keys @tptr 0 null null
                  end
               else
                  begin

                  if @tptr is not null
                     updatetext #spcnsttab.cnst_keys @tptr null null @cnstdes
                  end

               select @cnstdes = null

               select @cnstdes = text from syscomments
                  where id = @cnstid and colid = @i

               select @i = @i + 1
               end
            end
         else
            if ((@cnststatus & 0xf) = 5)    -- default
               begin
               select @i = 1

               select @cnstdes = text from syscomments
                  where id = @cnstid and colid = @i

               while @cnstdes is not null
                  begin

                  if @i=1
                     begin
                     insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
                        select 'DEFAULT on column ' + col_name(id, colid)
                              ,@cnstname,@cnstname,' '
                           from  sysconstraints
                           where colid > 0 and constid = @cnstid

                     select @tptr = textptr(cnst_keys) from #spcnsttab

                     if @tptr is not null
                        updatetext #spcnsttab.cnst_keys @tptr 0 null null
                     end
                  else
                     begin
                     if @tptr is not null
                        updatetext #spcnsttab.cnst_keys @tptr null null @cnstdes
                     end

                  select @cnstdes = null

                  select @cnstdes = text from syscomments
                     where id = @cnstid and colid = @i

                  select @i = @i + 1
                  end
               end
            else
               insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
                  values
                     ('*** INVALID TYPE FOUND IN SYSCONSTRAINTS ***'
                     ,'ERROR','ERROR','ERROR')

            fetch cnst_csr into @cnstid, @cnststatus, @cnstname
        end --of major loop


        ---- Find any rules or defaults bound by the sp_bind... method.

        insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
           select 'RULE (bound with sp_bindrule)'
                 ,object_name(c.domain),object_name(c.domain)
                 ,text
              from  syscolumns c,syscomments m
              where c.id = @objid
                and m.id = c.domain
                and c.domain not in
                        (select constid from sysconstraints)

        insert into #spcnsttab (cnst_type,cnst_name,cnst_nonblank_name,cnst_keys)
           select 'DEFAULT (bound with sp_bindefault)'
                 ,object_name(c.cdefault),object_name(c.cdefault)
                 ,text
              from syscolumns c,syscomments m
              where c.id = @objid
                and m.id = c.cdefault
                and c.cdefault not in
                        (select constid from sysconstraints)


        ---- constraint status (type included)

        update #spcnsttab
                set   cnst_status = cs.status
                from  #spcnsttab tt1 ,sysconstraints cs
                where tt1.cnst_name=object_name(cs.constid)

        update #spcnsttab
                set   cnst_status = 0
                where cnst_status is null


        if @nomsg <> 'nomsg'
           begin
           select 'Object Name' = @objname
           print ''
           end


        ---- Now print out the contents of the temporary index table.

        if (select count(*) from #spcnsttab) <> 0

           select
                   'constraint_type' = cnst_type
                  ,'constraint_name' = cnst_name

                  ,'status_enabled'      = -- 3=fkey ,4=check
                     CASE
                        When cnst_name = ' ' Then ' '
                        When cnst_status & 0xf in (3,4) and
                             cnst_status & @bitDisabled > 0 and
                             cnst_name <> ' '
                           Then    'Disabled'
                        When cnst_status & 0xf in (3,4) and
                             cnst_status & @bitDisabled = 0 and
                             cnst_name <> ' '
                           Then    'Enabled'
                        Else       '(n/a)'
                     END

                  ,'status_for_replication'  =
                     CASE
                        When cnst_name = ' ' Then ' '
                        When cnst_status & 0xf in (3,4) and
                             cnst_status & @bitNotForReplication > 0 and
                             cnst_name <> ' '
                           Then    'Not_For_Replication'
                        When cnst_status & 0xf in (3,4) and
                             cnst_status & @bitNotForReplication = 0 and
                             cnst_name <> ' '
                           Then    'Is_For_Replication'
                        Else       '(n/a)'
                     END

                  ,'constraint_keys' = cnst_keys
                from      #spcnsttab
                order by  cnst_nonblank_name ,cnst_name desc

        else
           print 'No constraints have been defined for this object.'

        print ''

        if (select count(*) from sysreferences where rkeyid = @objid) <> 0

           select
                   'Table is referenced by ' =
                        db_name(r.fkeydbid) + '.'
                     +  rtrim(
               (select user_name(o.uid) from sysobjects o
                  where o.id = r.fkeyid
               )
                             )
                     + '.' + object_name(r.fkeyid)
                     + ': ' + object_name(r.constid)
               from      sysreferences r
               where     r.rkeyid = @objid
               order by  1
        else
           print 'No foreign keys reference this table.'

deallocate cnst_csr
return (0)
go

dump transaction master with no_log
go


raiserror(15339,-1,-1,'sp_helpdb')
go
create procedure sp_helpdb  --1995/12/20 15:34 #12755
@dbname varchar(30) = NULL			/* database name to change */
as

declare @showdev	bit
declare @allopts	int

set nocount on

/*
**  If no database name given, get 'em all.
*/
if @dbname is null
	select @dbname = '%', @showdev = 0
else select @showdev = 1

/*
**  See if the database exists
*/
if not exists (select * from sysdatabases where name like @dbname)
	begin
		raiserror(15010,-1,-1,@dbname)
		return (1)
	end

/*
** Get bitmap of all options that can be set by sp_dboption.
*/
select @allopts=number from master.dbo.spt_values
	where type = 'D' and name = 'ALL SETTABLE OPTIONS'

/*
**  Since we examine the status bits in sysdatabase and turn them
**  into english, we need a temporary table to build the descriptions.
*/
create table #spdbdesc
(
	dbid	smallint	null,
	dbdesc	varchar(175)	null
)

/*
**  Initialize #spdbdesc from sysdatabases
*/
insert into #spdbdesc (dbid)
		select dbid from sysdatabases
			where name like @dbname

/*
**  Now for each dbid in #spdbdesc, build the database status
**  description.
*/
declare @curdbid smallint	/* the one we're currently working on */
declare @dbdesc varchar(175)	/* the total description for the db */
declare @bitdesc varchar(35)	/* the bit description for the db */

/*
**  Set @curdbid to the first dbid.
*/
select @curdbid = min(dbid) from #spdbdesc

while @curdbid IS NOT NULL
begin
	/*
	**  Initialize @dbdesc.
	*/
	select @dbdesc = ''

	/*
	** First check bits in sysdatabases.status.
	*/

	/*
	**  Check select into/bulk copy bit (4)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 4
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check truncate log on checkpoint bit (8)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 8
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check no checkpoint on recovery bit (16)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 16
			and v.number <> @allopts /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check don't recover bit (32)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 32
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check not recovered only bit (256)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 256
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check offline bit (512)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 512
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check read only bit (1024)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 1024
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check dbo only bit (2048)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 2048
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check single user bit (4096)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 4096
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  Check ANSI NULL default bit (16384)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.status & v.number = 16384
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	** Now check bits in sysdatabases.category.
	*/

	/*
	**  Check published bit (65536)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.category & (v.number/0x10000) = 1
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end


	/*
	**  Check subscribed bit (131072)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysdatabases d
		where d.dbid = @curdbid
			and v.type = 'D'
			and d.category & (v.number/0x10000) = 2
			and v.number <> @allopts       /* all options */
	if @bitdesc IS NOT NULL
	begin
		if @dbdesc <> ''
			select @dbdesc = @dbdesc + ', ' +  @bitdesc
		else select @dbdesc = @bitdesc
	end

	/*
	**  If no flags are set, say so.
	*/
	if @dbdesc = ''
		select @dbdesc = 'no options set'

	/*
	**  Save the description.
	*/
	update #spdbdesc set dbdesc = @dbdesc
		from #spdbdesc
			where dbid = @curdbid

	/*
	**  Now get the next, if any dbid.
	*/
	select @curdbid = min(dbid) from #spdbdesc where dbid > @curdbid
end

/*
**  Now #spdbdesc is complete so we can print out the db info
*/
select name = substring(d.name, 1, 24),
	db_size = str(sum(convert(dec(15),u.size))*
		(select low from master.dbo.spt_values
			where type = 'E' and number = 1)
			 / 1048576,10,2)+ ' MB',
	owner = substring(l.name, 1, 24),
	dbid = d.dbid,
	created = convert(char(11), d.crdate),
	status = s.dbdesc
from sysdatabases d, syslogins l, sysusages u, #spdbdesc s
where d.dbid = s.dbid
	and d.suid = l.suid
	and s.dbid = u.dbid
group by d.name,l.name,d.dbid,d.crdate,s.dbdesc
order by d.name

/*
**  If we are looking at one database, show its device allocation.
*/
if @showdev = 1
begin
	print ''
	select device_fragments = v.name, size =
		str((select low from master.dbo.spt_values
			where type = 'E'
				and number = 1)
			* convert(dec(15), u.size)/ 1048576,10,2) +' MB',
		usage = t.name
	from sysdatabases d, sysusages u, sysdevices v,
		master.dbo.spt_values t
	where d.dbid = u.dbid
		and u.vstart between v.low and v.high
		and v.status & 2 = 2
		and d.name = @dbname
		and t.type = 'S'
		and u.segmap & 7 = t.number
	order by u.lstart


	/*
	**  If there is only one database and we are in it, show the
	**  segments.
	*/
	if exists (select * from #spdbdesc where db_id() = dbid)
	begin
		declare @curdevice	varchar(30),
			@curseg		smallint,
			@segbit		int

		delete from #spdbdesc

		select @curdevice = min(d.name)
			from  sysusages u, sysdevices d
			where u.dbid = db_id()
				and u.vstart between d.low and d.high
				and d.status & 2 = 2

		while @curdevice IS NOT NULL
		begin
			/*
			** We need an inner loop here to go through
			**  all the possible segments.
			*/
			select @curseg = min(segment) from syssegments

			while (@curseg IS NOT NULL)
			begin
				if (@curseg < 31)
					select @segbit = power(2, @curseg)
				else select @segbit = low
					from master.dbo.spt_values
					where type = 'E'
						and number = 2
				insert into #spdbdesc
					select @curseg, @curdevice
						from sysusages u,
							sysdevices d
					where u.segmap & @segbit = @segbit
						and u.vstart between d.low and d.high
						and u.dbid = db_id()
						and d.status & 2 = 2
						and d.name = @curdevice
				select @curseg = min(segment)
					from syssegments
					where segment > @curseg
			end

			select @curdevice = min(d.name)
				from  sysusages u, sysdevices d
				where u.dbid = db_id()
					and u.vstart between d.low and d.high
					and d.status & 2 = 2
					and d.name > @curdevice
		end

		/*
		**  One last check for any devices that have no segments.
		*/
		insert into #spdbdesc
			select null, d.name
			from sysusages u, sysdevices d
			where u.segmap = 0
				and u.vstart between d.low and d.high
				and u.dbid = db_id()
				and d.status & 2 = 2

		print ''

		select distinct device = substring(dbdesc, 1, 30),
			segment = isnull(name, ' -- unused by any segments --')
		from #spdbdesc, syssegments
			where dbid *= segment
		order by 1, 2
	end

end
return (0)
go



raiserror(15339,-1,-1,'sp_help_revdatabase')
go
CREATE PROCEDURE sp_help_revdatabase  --1995/12/19 13:54

       @DBNamePattern     varchar (44)   = '%'   -- LIKE pattern
AS

/****************************************************************
      This SP reverse generates CREATE & ALTER DB statements.
The output statements are in the sequence necessary to facilitate
the LOADing of a DUMP DATABASE output file onto a different
DB and possibly a different SV too.
      Perhaps sp_coalesce_fragments could be safely incorporated,
but for now we are keeping it simple.
****************************************************************/

SET nocount on

-----------------  declares  ------------------

DECLARE
       @vc80a                 varchar (80)
      ,@vc255a                varchar (255)
      ,@int1                  int
      ,@NowDateTm             datetime
      ,@CountDBs              int
      ,@Loop22Count           int
      ,@G_O                   varchar (2)
      ,@TrueFalse             varchar (5)
      ,@CommentThisDBOption   char (1)
      ,@EOLWinNT              varchar (2)
      ,@OrigDBName            varchar (30)

DECLARE
       @cu33OptName           varchar (35)
      ,@cu33OptNumber         int

DECLARE
       @cu11DBName            varchar (30)
      ,@cu11DBId              smallint
      ,@cu11DBStatus          smallint
      ,@cu11DBSUID            smallint

DECLARE
       @cu22DBName            varchar (30)
      ,@cu22DBId              smallint
      ,@cu22DVName            varchar (30)
      ,@cu22FragSizePages     int
      ,@cu22FragSizeMb        varchar (15)
      ,@cu22SegMap            int
      ,@cu22LStart            int

DECLARE
       @LoginName             varchar (30)
      ,@LoginDBName           varchar (30)
      ,@LoginLanguage         varchar (30)

DECLARE
       @SPTValAllSettableOptions    int
      ,@SPTValDataAndLog            int
      ,@SPTValPageSize              int
      ,@SPTValLogOnly               int
      ,@cSPTValAllSettableOptions   varchar (15)
      ,@cSPTValDataAndLog           varchar (15)
      ,@cSPTValPageSize             varchar (15)
      ,@cSPTValLogOnly              varchar (15)
      ,@DefaultSortOrderId          int
      ,@OneMb                       numeric(9,1)
      ,@cOneMb                      varchar (15)


----------------  initial values  -------------------

Select
       @NowDateTm       = Getdate()
      ,@OneMb           = 1048576.0
      ,@G_O             = 'g' + 'o'
      ,@CountDBs        = 0            -- RETURNed
      ,@EOLWinNT        = 0x0D0A
      ,@OrigDBName      = Db_name()


Select
       @cOneMb          = Convert(varchar,@OneMb)


IF NOT EXISTS (SELECT * From master.dbo.sysdatabases
                 Where name LIKE @DBNamePattern)
   begin
   RaisError(15329,-1,-1)
   GOTO LABEL_86RETURN
   end


/*********************************************************************
 *
 *                Initialization
 *
 ********************************************************************/


Print  @EOLWinNT


----------------  code page and sort order config  ---------------


SELECT
             @DefaultSortOrderId    = c.value
      From
             master..syscurconfigs  c
      Where
             lower(c.comment)       = 'default sortorder id'


---------------------  Selects, cursor for spt_values  -----------


SELECT
             @SPTValAllSettableOptions    = v.number
            ,@cSPTValAllSettableOptions   = Convert(varchar,v.number)
      From
             master..spt_values     v
      Where
             v.type                 = 'D'
      And    v.name                 = 'ALL SETTABLE OPTIONS'


SELECT
             @SPTValPageSize        = v.low
            ,@cSPTValPageSize       = Convert(varchar,v.low)
      From
             master..spt_values     v
      Where
             v.type                 = 'E'
      And    v.name                 = 'WINDOWS/NT'


SELECT
             @SPTValDataAndLog      = v.number
            ,@cSPTValDataAndLog     = Convert(varchar,v.number)
      From
             master..spt_values     v
      Where
             v.type                 = 'S'
      And    v.name                 = 'data and log'


SELECT
             @SPTValLogOnly         = v.number
            ,@cSPTValLogOnly        = Convert(varchar,v.number)
      From
             master..spt_values     v
      Where
             v.type                 = 'S'
      And    v.name                 = 'log only'


--  cursor


EXECUTE(
'
DECLARE cursor_33SPTValDBOpts
   Insensitive
   Cursor For
   SELECT
             v.name
            ,v.number
      From
             master..spt_values   v
'+'
      Where
             v.type    = ''D''
      And    v.number <> ' + @cSPTValAllSettableOptions + '
      And    v.number >  0
      And    v.number  & ' + @cSPTValAllSettableOptions + ' = Abs(v.number)
      Order By
             v.name

   For Read Only
'
)


--------------------  Cursor for DB names  -------------------

EXECUTE(
'
DECLARE cursor_11DBNames
   Insensitive
   Cursor For
'+'
   SELECT
             d.name
            ,d.dbid
            ,d.status
            ,d.suid
      From
             master..sysdatabases   d
'+'
      Where
             d.name        LIKE ''' + @DBNamePattern + '''
      Order By
             d.name

   For Read Only
'
)




/****************************************************************
 *
 *                MainLine
 *
 ***************************************************************/



OPEN cursor_11DBNames


----------------------------------------------------------------
--              LOOP 11:  thru DBs
----------------------------------------------------------------


WHILE (11=11)
   Begin


   FETCH
             Next
      From
             cursor_11DBNames
      Into
             @cu11DBName
            ,@cu11DBId
            ,@cu11DBStatus
            ,@cu11DBSUID


   IF (@@fetch_status < 0)
      begin
      CLOSE cursor_11DBNames

      BREAK
      end


   Select @CountDBs = @CountDBs + 1



----------------------  Print the headers  ----------------------

   Print  @EOLWinNT
   Raiserror('%s%s',0,1,'/','********1*********2*********3*********4*********5*********6**')

   Select @vc80a = 'Reverse generated at '
            +   Substring(convert(varchar,@NowDateTm,111),1 ,10) + ' '
            +   Substring(convert(varchar,@NowDateTm,113),12,13)
   Print  @vc80a

   Print  @EOLWinNT
   Print  'Server / Database / Default sortorder ID :'

   Select @vc80a = @@servername + ' / '
            +   @cu11DBName + ' / '
            +   Convert(varchar,@DefaultSortOrderId)
   Print  @vc80a
   Print  ' '

   SELECT
		 'DBName'   =db_name(ug.dbid)
		,'FromLPage'=ug.lstart
		,'ToLPage'  =ug.lstart + ug.size - 1
		,ug.segmap
	from
		 master.dbo.sysusages ug
	where
		 ug.dbid = db_id(@cu11DBName)
	order by
		 DBName ,FromLPage

   Print  ' '
   Print  @EOLWinNT
   Select @vc255a = @@version
   Select @int1 = CharIndex(char(10),@vc255a)
   Select @vc255a = '@@version:  '  +  Substring(@vc255a ,1 ,@int1 - 1)
   Print  @vc255a

   Raiserror('%s%s',0,1,'*********1*********2*********3*********4*********5*********6**','/')
   Print  @G_O

   Print  @EOLWinNT
   Print  'USE master'
   Print  @G_O


----------------------  Refresh DV usage fragment cursor  --------------


   Select @vc255a = Convert(varchar,@cu11DBId)



   EXECUTE(
   '
   DECLARE cursor_22DVUsageFrags
      Insensitive
      Cursor For
   '+'
   SELECT
             db.name
            ,db.dbid
            ,dv.name
            ,ug.size

               -- (numPages * bytesPerPage) / 1 Mb power of 2

            ,Str( (Convert(numeric(25,0),ug.size)  * ' +
                     @cSPTValPageSize +  ') / '  + @cOneMb + ' ,13  ,1)

            ,ug.segmap
            ,ug.lstart
      From
             master..sysdatabases   db
            ,master..sysusages      ug
            ,master..sysdevices     dv
            ,master..spt_values     va
      Where
             db.dbid     = ug.dbid
      And    dv.low     <= ug.size + ug.vstart
      And    dv.high    >= ug.size + ug.vstart - 1
      And    db.dbid     = ' + @vc255a + '
      And    va.type = ''S''
      And    ug.segmap & ' + @cSPTValDataAndLog + ' =
                             va.number  --1,2,4 & 7 always 1,2,4
      And    dv.status & 2 > 0
      Order By
             ug.lstart  Asc

   For Read Only
   '
   )


----------------------------------------------------------------
--              LOOP 22:  thru DV frags
----------------------------------------------------------------

   Print  @EOLWinNT
   Print  '-----------------  Space and Log allocations  ---------------'
   Print  @EOLWinNT


   Select @Loop22Count = 0

   OPEN cursor_22DVUsageFrags


   WHILE (22=22)
      Begin


      FETCH
             Next
         From
             cursor_22DVUsageFrags
         Into
             @cu22DBName
            ,@cu22DBId
            ,@cu22DVName
            ,@cu22FragSizePages
            ,@cu22FragSizeMb
            ,@cu22SegMap
            ,@cu22LStart


      IF (@@fetch_status < 0)
         begin
         DEALLOCATE cursor_22DVUsageFrags

         BREAK
         end


      Select @cu22FragSizeMb = Rtrim(Ltrim(@cu22FragSizeMb))


---------------------  massage the fragemnt size  -------------------


      IF (     (Right(@cu22FragSizeMb,2) >= '.1')
         AND   (Right(@cu22FragSizeMb,2) <= '.9')
         )
         begin   -- thus not .0


         Select @cu22FragSizeMb =
                     Convert(varchar
                            ,(Convert(numeric(12,1) ,@cu22FragSizeMb) +
                              Convert(numeric( 3,1) ,0.9) -- Adding 0.9!
                             )
                            )


         Select @cu22FragSizeMb = Rtrim(Ltrim(@cu22FragSizeMb))


         Select @cu22FragSizeMb = Substring(@cu22FragSizeMb
                                           ,1
                                           ,Datalength(@cu22FragSizeMb)-2
                                           )
                                + '.0'

         Print  @EOLWinNT
         Print  @EOLWinNT

         Raiserror('%s%s',0,1,'/','***')
         Raiserror(15316,-1,-1)  --Frag in Mb rounded up from size in pages.
         Raiserror('%s%s',0,1,'***','/')

         Print  @G_O
         Print  @EOLWinNT
         end


-----------------------  first iteration for this DB?  -------------


      Select @Loop22Count = @Loop22Count + 1


      Print  @EOLWinNT


      IF (@Loop22Count = 1)
         begin
         Select @vc80a = 'CREATE  '
         end
      ELSE
         begin
         Select @vc80a = 'ALTER   '
         end


      Select @vc80a = @vc80a + 'Database  ' + @cu22DBName
      Print  @vc80a

      Select @vc80a = ' '


---------------------  is this a special system DB?  ----------------


      IF (     @cu22DBName     IN ('master','model','msdb'
                               -- ,'pubs'
                                  ,'tempdb')
      -- AND   @Loop22Count   =  1
         )
         begin
         Raiserror(15313,-1,-1,@cu22DBName)
         end


      Select @int1 = Datalength(@cu22FragSizeMb)
      Select @cu22FragSizeMb = Substring(@cu22FragSizeMb,1,@int1-2)


      Select @vc80a = @vc80a + '      on  ' + @cu22DVName + '  =  '
                        +  Ltrim(Rtrim(@cu22FragSizeMb))
                        +  '  -- ' + Convert(varchar,@cu22FragSizePages)
                        +  '  of two Kb pages'
      Print  @vc80a


      Print  @G_O


--------------------  is this a log fragment?  --------------------


      IF (@cu22SegMap = @SPTValLogOnly)
         begin

         Select @vc80a = 'EXECute sp_logdevice '
                           +  @cu22DBName + ' ,'
                           +  @cu22DVName
         Print  @vc80a
         Print  @G_O
         end


--------------------  make pretty  -------------------------


      IF (@Loop22Count = 1)
         begin
         Print  @EOLWinNT
         Print  @EOLWinNT
         end


      End  -- loop 22


----------------------------------------------------------------
--              LOOP 33:  thru DB options
----------------------------------------------------------------


   Print  @EOLWinNT
   Print  '---------------------  DB Options  -------------------'
   Print  @EOLWinNT


   OPEN cursor_33SPTValDBOpts


   WHILE (33=33)
      Begin

      FETCH
             Next
         From
             cursor_33SPTValDBOpts
         Into
             @cu33OptName
            ,@cu33OptNumber


      IF (@@fetch_status < 0)
         begin
         CLOSE cursor_33SPTValDBOpts

         BREAK
         end



      IF (@cu33OptNumber & @cu11DBStatus = @cu33OptNumber)
         begin
         Select @TrueFalse = 'TRUE'
         end
      ELSE
         begin
         Select @TrueFalse = 'false'
         end


      Print  @EOLWinNT


      IF (@cu33OptName IN (
             'ANSI null default'
            ,'dbo use only'
            ,'no chkpt on recovery'
            ,'read only'
            ,'select into/bulkcopy'
            ,'single user'
            ,'trunc. log on chkpt.'
                         )
         )
         begin
         Select @CommentThisDBOption = 'N'
         end
      ELSE
         begin
         Select @CommentThisDBOption = 'Y'
         end


      IF (@CommentThisDBOption = 'Y')
         begin
         Raiserror('%s%s',0,1,'/','***')
         end


      Select @vc255a =
         'EXECute sp_dboption  ' + @cu11DBName + ' ,''' + @cu33OptName + ''''
      Print  @vc255a


      Select @vc255a = Space(21 + Datalength(@cu11DBName))
                       +  ' , '  + @TrueFalse
      Print  @vc255a


      IF (@CommentThisDBOption = 'Y')
         begin
         Raiserror('%s%s',0,1,'***','/')
         end


--    Print  @G_O

      End  -- loop 33


   Print  @EOLWinNT
   Print  @G_O


-----------------------  dbo login  ----------------------------


   SELECT
       @LoginName       = Null
      ,@LoginDBName     = Null
      ,@LoginLanguage   = Null


   Select @vc255a = Null


   SELECT
             @LoginName       = l.name
            ,@LoginDBName     = l.dbname
            ,@LoginLanguage   = l.language
      From
             master..sysdatabases   d
            ,master..syslogins      l
      Where
             d.suid     = l.suid
      And    d.dbid     = @cu11DBId




   IF (     @LoginName         is Null
      OR    @LoginName         =  ''
      OR    Lower(@LoginName)  =  'sa'
      )
      begin

      Print  @EOLWinNT
      Print  '--------------------  sa  is  dbo  ---------------------'
      Print  @EOLWinNT

      Goto LABEL_91SAISDBO
      end



   Print  @EOLWinNT
   Print  '---------------------  DBO Login  --------------------'
   Print  @EOLWinNT



   SELECT @vc255a =
               'EXECute  sp_addlogin  ' +  @LoginName
            +  char(13) + char(10)
            +  '   ,Null  ,'
            +  Isnull(@LoginDBName,'Null')  +  '  ,'
            +  Isnull(@LoginLanguage,'Null')


   Print  @EOLWinNT
   Print  @EOLWinNT
   Print  @EOLWinNT

   Print  @vc255a
   Print  @G_O

   Print  @EOLWinNT
   Select @vc255a = 'USE ' + @cu11DBName
   Print  @vc255a
   Print  @G_O

   Print  @EOLWinNT
   Select @vc255a = 'EXECute sp_changedbowner '  +  @LoginName
   Print  @vc255a
   Print  @G_O

   Print  @EOLWinNT
   Print  'USE master'
   Print  @G_O



LABEL_91SAISDBO:


   Print  @EOLWinNT
   Print  @G_O
   Print  '---'
   Print  @EOLWinNT
   Print  @EOLWinNT


   End  -- loop 11


---------------------------  Finalization  -----------------------


DEALLOCATE cursor_33SPTValDBOpts
DEALLOCATE cursor_11DBNames
-- DEALLOCATE cursor_22DVUsageFrags

EXECUTE('USE ' + @OrigDBName)  --For 6.0 db resumption.

LABEL_86RETURN:

RETURN @CountDBs
go





raiserror(15339,-1,-1,'sp_helpdevice')
go
create procedure sp_helpdevice
@devname varchar(30) = '%'		/* device to check out */
as

/*
**  See if the device exists.
*/
if not exists (select * from sysdevices where name like @devname)
	begin
		raiserror(15012,-1,-1,@devname)
		return (1)
	end

/*
**  Create a temporary table where we can build up a translation of
**  the device status bits.
*/
create table #spdevtab
(
	name varchar(30)		NOT NULL,
	statusdesc varchar(255)	null
)

set nocount on

/*
**  Initialize the temporary table with the names of the devices.
*/
insert into #spdevtab (name)
	select name
		from sysdevices
		where name like @devname


/*
**  Now figure out what kind of controller type it is.
**
**  cntrltype =			0	special (data disk)
**				2	disk (dump)
**				3-4	floppy (dump)
**				5	tape
**				6	pipe
**				7	cdrom
*/
update #spdevtab
	set statusdesc = 'special'
		from sysdevices d, #spdevtab
			where d.cntrltype = 0
				and #spdevtab.name = d.name
update #spdevtab
	set statusdesc = 'disk'
		from sysdevices d, #spdevtab
			where d.cntrltype = 2
				and #spdevtab.name = d.name
update #spdevtab
	set statusdesc = 'diskette'
		from sysdevices d, #spdevtab
			where d.cntrltype between 3 and 4
				and #spdevtab.name = d.name

update #spdevtab
	set statusdesc = 'pipe'
		from sysdevices d, #spdevtab
			where d.cntrltype = 6
				and #spdevtab.name = d.name
update #spdevtab
	set statusdesc = 'cdrom'
		from sysdevices d, #spdevtab
			where d.cntrltype = 7
				and #spdevtab.name = d.name
/*
**  If a floppy dump device, also figure out the floppy capacity which
**	is listed in sysdevices.high in number of 62k blocks.
*/
update #spdevtab
	set statusdesc = statusdesc + ', '
		+ ltrim(str(((d.high * 63488.0) / 1000000.0), 5,1))
		+ ' MB'
	from sysdevices d, #spdevtab
		where d.cntrltype in (3,4)
			and d.high > 0
			and #spdevtab.name = d.name

/*
**  If a tape device, also figure out the tape capacity which is listed
**  in sysdevices.high in number of 62k blocks.
*/
update #spdevtab
	set statusdesc = statusdesc + ', ' + convert(varchar(10),
		round((d.high * convert(float, 63488)) / 1048576, 0))
		+ ' MB'
	from sysdevices d, #spdevtab
		where d.cntrltype = 5
			and d.high > 0
			and #spdevtab.name = d.name

update #spdevtab
	set statusdesc = 'UNKNOWN DEVICE'
		from sysdevices d, #spdevtab
			where d.cntrltype >= 8
				and #spdevtab.name = d.name

/*
**  Now check out the status bits and turn them into english.
**  The mirror status bits are between 32 and 512.
*/
if exists (select * from sysdevices d, master.dbo.spt_values v, #spdevtab
		where v.type = 'V' and v.number > -1
			and d.status & 992 <> 0		/* 992 = (32+64+128+256+512) */
			and #spdevtab.name = d.name)
begin
	/*
	**  Check to see if the mirror is enabled. (512 bit in status)
	*/
	update #spdevtab
		set statusdesc = statusdesc + ', MIRROR ENABLED'
		from sysdevices d, #spdevtab
		where d.status & 512 = 512
			and #spdevtab.name = d.name

	update #spdevtab
		set statusdesc = statusdesc + ', MIRROR DISABLED'
		from sysdevices d, #spdevtab
		where d.status & 512 <> 512
			and d.status & 480 <> 0		/* 480 = sum of bits */
			and #spdevtab.name = d.name	/* from 32 - 256     */

	/* add mirror name */
	update #spdevtab
		set statusdesc = statusdesc + ', mirrored on ''' + d.mirrorname
			+ ''''
		from sysdevices d, #spdevtab
		where #spdevtab.name = d.name
			and d.status & 992 <> 0		/* 992 = sum of bits from 32 - 512 */
end

/*
**  Check to see if there is a mirrorname entry but mirroring not enabled.
**  If so, then one side of the mirror is off-line.
*/
else if exists (select *
	from sysdevices d, #spdevtab
	where #spdevtab.name = d.name
		and d.mirrorname IS NOT NULL)
begin
	/*
	**  Figure out which side of the mirror is disabled.
	**  If 256 is on then phyname is disabled and mirrorname is enabled.
	*/
	update #spdevtab set statusdesc = 'only device ''' + d.mirrorname
			+ ''' of mirror is enabled -- device '''
			+ d.phyname + ''' is disabled'
		from sysdevices d, master.dbo.spt_values v, #spdevtab
		where v.type = 'V' and v.number > -1
			and d.status & v.number = 256
			and #spdevtab.name = d.name

	update #spdevtab set statusdesc = 'only device ''' + d.phyname
			+ ''' of mirror is enabled -- device '''
			+ d.mirrorname + ''' is disabled'
		from sysdevices d, sysdevices e, master.dbo.spt_values v,
			#spdevtab
		where v.type = 'V' and v.number > -1
			and d.status & v.number = 64
			and #spdevtab.name = d.name
			and e.status & 256 <> 256
			and #spdevtab.name = e.name
end

/*
**  Status of 32 is 'serial writes' for mirrored disks.
*/
update #spdevtab set statusdesc = statusdesc + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 32
		and #spdevtab.name = d.name

update #spdevtab set statusdesc = statusdesc + ', nonserial writes'
	from sysdevices d, #spdevtab
	where d.status & 960 <> 0		/* Sum of bits from 64 to 512 */
		and d.status & 32 <> 32
		and #spdevtab.name = d.name

/*
**  Status of 128 is 'reads mirrored' for mirrored disks.
*/
update #spdevtab set statusdesc = statusdesc + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 128
		and #spdevtab.name = d.name

/*
**  Now check out the status bits and turn them into english.
**  Status of 16 is a dump device.
*/
update #spdevtab set statusdesc = statusdesc + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 16
		and #spdevtab.name = d.name

/*
**  Status of 1 is a default disk.
*/
update #spdevtab set statusdesc = statusdesc + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 1
		and #spdevtab.name = d.name

/*
**  Status of 2 is a physical disk.
*/
update #spdevtab
	set statusdesc = substring(statusdesc, 1, 225) + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 2
		and #spdevtab.name = d.name

/*
**  Add in its size in MB.
*/
update #spdevtab
	set statusdesc = statusdesc + ', ' + convert(varchar(10),
		round(((d.high - d.low)
			* convert(float, v.low)) / 1048576, 0)) + ' MB'
	from sysdevices d, #spdevtab, master.dbo.spt_values v
	where d.status & 2 = 2
		and #spdevtab.name = d.name
		and v.number = 1
		and v.type = 'E'

/*
**  Status of 4 is a logical disk.
*/
update #spdevtab
	set statusdesc = substring(statusdesc, 1, 225) + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 4
		and #spdevtab.name = d.name

/*
**  Status of 8 is a skip tape header.
*/
update #spdevtab
	set statusdesc = substring(statusdesc, 1, 225) + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 8
		and #spdevtab.name = d.name
/*
**  Status of 4096 is read only.
*/
update #spdevtab
	set statusdesc = substring(statusdesc, 1, 225) + ', ' + rtrim(v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 4096
		and #spdevtab.name = d.name
/*
**  Status of 8192 is deferred.
*/
update #spdevtab
	set statusdesc = substring(statusdesc, 1, 225) + ', ' + (v.name)
	from sysdevices d, master.dbo.spt_values v, #spdevtab
	where v.type = 'V' and v.number > -1
		and d.status & v.number = 8192
		and #spdevtab.name = d.name

set nocount off

/*
**  The device number is in the high byte of sysdevices.low so
**  spt_values tells us which byte to pick out.
*/
select device_name = d.name, physical_name = substring(d.phyname, 1, 46),
	description = #spdevtab.statusdesc,
	d.status, d.cntrltype,
	device_number = convert(tinyint, substring(convert(binary(4), d.low),
		v.low, 1)),
	d.low, d.high
	from sysdevices d, #spdevtab, master.dbo.spt_values v
	where d.name = #spdevtab.name
		and v.type = 'E'
		and v.number = 3

return(0)
go


raiserror(15339,-1,-1,'sp_helpextendedproc')
go
create procedure sp_helpextendedproc
@funcname varchar(30) = NULL
as

set nocount on

/*
**  If no function name given, get 'em all.
*/
if @funcname is null
	select @funcname = '%'

/*
**  Make sure the function name exists
*/
if not exists (select * from master.dbo.sysobjects
		where type = 'X '
		  and name like @funcname)
begin
	if @funcname <> '%'
		begin
			raiserror(15019,-1,-1,@funcname)
			return (1)
		end
	else
		begin
			print 'No extended stored procedures exist.'
			return (0)
		end

end

/*
**  Now print out the function name info
*/
select distinct name = o.name, dll = substring(c.text,1,30)
	from master.dbo.sysobjects o, master.dbo.syscomments c
	where o.id = c.id
		and o.name like @funcname
		and o.type = 'X '
	order by o.name

return (0)
go


raiserror(15339,-1,-1,'sp_helpgroup')
go
create procedure sp_helpgroup
@grpname varchar(30) = NULL		/* group name of interest */
as

/*
**  If no group name given, list all the groups.
**  User ids are <= 16383 and group ids are > 16383 or = 0.
*/
if @grpname is null
begin
	select Group_name = name, Group_id = gid
		from sysusers
			where (uid > 16383 or uid = 0)
		order by name

	return (0)
end

/*
**  Check to see if group exists.
*/
if not exists (select * from sysusers where name = @grpname
		and (uid > 16383 or uid = 0))
	begin
		raiserror(15014,-1,-1,@grpname)
		return (1)
	end

/*
**  List the particulars for the group.
*/
select Group_name = substring(g.name, 1, 25), Group_id = g.gid,
	Users_in_group = substring(u.name, 1, 25), Userid = u.uid
		from sysusers u, sysusers g
			where g.name like @grpname
			and g.uid = u.gid
			and (g.uid > 16383 or g.uid = 0)
			and u.uid <> u.gid
		order by g.name, u.name

return (0)
go



raiserror(15339,-1,-1,'sp_helplog')
go
create procedure sp_helplog
as
declare @firstpage int,
	@devname varchar(255),
	@msg varchar(255)


/* Get the first page of the log from sysindexes */
select @firstpage = first
	from sysindexes
		where id = 8

/*
**  Get the name of the device which contains the first page of the log.
**  The device number is in the high byte of d.low and u.vstart and which is the
**  high byte is defined in spt_values.
*/
select @devname = d.name
	from sysdevices d, sysusages u, master.dbo.spt_values v
	where (d.status & 2 = 2 or d.status & 4 = 4)
		and @firstpage >= u.lstart
		and @firstpage < u.lstart + u.size - 1
		and convert(tinyint, substring(convert(binary(4), d.low),
			v.low, 1))
		  = convert(tinyint, substring(convert(binary(4), u.vstart),
		       v.low, 1))
		and v.type = 'E'
		and v.number = 3
		and u.dbid = db_id()

/* Print out the name of the device which contains the first page of the log */
select @msg = 'In database ''' + (select db_name())
	+ ''', the log starts on device ''' + @devname + '''.'

print @msg

return (0)
go




raiserror(15339,-1,-1,'sp_helplogins')
go
CREATE PROCEDURE sp_helplogins  --1995/11/20 16:50

    @LoginNamePattern     varchar(55)    = '%'
AS

Set nocount on

Declare
       @RetCode                        int
      ,@CountSkipPossUsers             int
      ,@Int1                           int

Declare
       @c10DBName                      varchar(30)
      ,@c10DBStatus                    smallint
      ,@c10DBSUID                      smallint

Declare
       @charMaxLenLoginName            varchar(11)
      ,@charMaxLenDBName               varchar(11)
      ,@charMaxLenUserName             varchar(11)
      ,@charMaxLenLangName             varchar(11)

Declare
       @DBOptLoading                   int   --0x0020      32  "DoNotRecover"
      ,@DBOptPreRecovery               int   --0x0040      64
      ,@DBOptRecovering                int   --0x0080     128

      ,@DBOptSuspect                   int   --0x0100     256  ("not recovered")
      ,@DBOptOffline                   int   --0x0200     512
      ,@DBOptDBOUseOnly                int   --0x0800    2048

      ,@DBOptSingleUser                int   --0x1000    4096


----------------  Initial data values  -------------------

Select
       @RetCode                        = 0  -- 0=good ,1=bad
      ,@CountSkipPossUsers             = 0


----------------  Only SA can run this  -------------------


IF (suser_id() <> 1)  --SA, else risk errors in DB's lacking GUEST.
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


---------------  Edit input parm values  ---------------


IF (      @LoginNamePattern IS Null)
   Select @LoginNamePattern  = '%'


-------------  create work holding tables  ----------------


CREATE Table #tb2_PlainLogins
   (
    LoginName                       varchar(30)    NOT Null
   ,SUID                            char(6)        NOT Null
   ,DefDBName                       varchar(30)    NOT Null
   ,DefLangName                     varchar(30)        Null
   ,AUser                           char(5)            Null
   ,ARemote                         char(7)            Null
   )


CREATE Table #tb1_UA
   (
    LoginName                       varchar(30)    NOT Null
   ,DBName                          varchar(30)    NOT Null
   ,UserName                        varchar(30)    NOT Null
   ,UserOrAlias                     char(5)        NOT Null
   )


----------------------  spt_values  ----------------


-------- 'D'

SELECT       @DBOptLoading       = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'loading'

SELECT       @DBOptPreRecovery   = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'pre recovery'

SELECT       @DBOptRecovering    = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'recovering'

SELECT       @DBOptSuspect       = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'not recovered'

SELECT       @DBOptOffline       = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'offline'

SELECT       @DBOptDBOUseOnly    = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'dbo use only'

SELECT       @DBOptSingleUser    = number
      from   master.dbo.spt_values
      where  type                = 'D'
      and    name                = 'single user'



---------------  Cursor, for DBNames  -------------------


DECLARE cursor10_DB
   Insensitive
   Cursor For
SELECT
             name ,status ,suid
      from
             master.dbo.sysdatabases



OPEN cursor10_DB


-----------------  LOOP 10:  thru Databases  ------------------


--------------
WHILE (10 = 10
      )
   begin    --LOOP 10: thru Databases


   FETCH
             Next
      from
             cursor10_DB
      into
             @c10DBName
            ,@c10DBStatus
            ,@c10DBSUID


   IF (@@fetch_status <> 0)
      begin
      Deallocate cursor10_DB
      BREAK
      end


--------------------  Okay if we peek inside this DB now?


   IF (     @c10DBStatus & @DBOptDBOUseOnly  > 0
       AND  @c10DBSUID                      <> suser_id()
      )
      begin
      Select @CountSkipPossUsers = @CountSkipPossUsers + 1
      CONTINUE
      end


   IF (@c10DBStatus & @DBOptSingleUser  > 0)
      begin

      SELECT    @Int1 = count(*)
         from   master.dbo.sysprocesses
         where  spid <> @@spid
         and    dbid  = db_id(@c10DBName)

      IF (@Int1 > 0)
         begin
         Select @CountSkipPossUsers = @CountSkipPossUsers + 1
         CONTINUE
         end
      end


   IF (@c10DBStatus &
         (
           @DBOptLoading
         | @DBOptRecovering
         | @DBOptSuspect
         | @DBOptPreRecovery
         )
               > 0
      )
      begin
      Select @CountSkipPossUsers = @CountSkipPossUsers + 1
      CONTINUE
      end


   IF (@c10DBStatus &
         (
           @DBOptOffline
         )
               > 0
      )
      begin
      --Select @CountSkipPossUsers = @CountSkipPossUsers + 1
      CONTINUE
      end


---------------------  Add the User info to holding table.


   EXECUTE(
   '
   INSERT    #tb1_UA
            (
             DBName
            ,LoginName
            ,UserName
            ,UserOrAlias
            )
      Select
             ''' + @c10DBName + '''
            ,l.name
            ,u.name
            ,''User''
         from
             ' + @c10DBName + '.dbo.sysusers       u
            ,master.dbo.syslogins                  l
         where
             u.suid  = l.suid
         and
             l.name LIKE ''' + @LoginNamePattern + '''

      UNION

      Select

             ''' + @c10DBName + '''
            ,l.name
            ,u.name
            ,''Alias''
         from
             ' + @c10DBName + '.dbo.sysalternates  a
            ,' + @c10DBName + '.dbo.sysusers       u
            ,master.dbo.syslogins                  l
         where
             a.suid     = l.suid
         and a.altsuid  = u.suid
         and
             l.name LIKE ''' + @LoginNamePattern + '''
   '
   )


   end --loop 10



---------------  Populate plain logins work table  ---------------


INSERT       #tb2_PlainLogins
            (
             LoginName
            ,SUID
            ,DefDBName
            ,DefLangName
            ,AUser
            ,ARemote
            )
   SELECT
             name
            ,convert(char(6),suid)
            ,dbname
            ,isnull(language,'us_english')
            ,Null
            ,Null
      from
             master.dbo.syslogins
      where
             name LIKE @LoginNamePattern


-- AUser

UPDATE       #tb2_PlainLogins
      set
             tb2.AUser  = 'yes'
      from
             #tb2_PlainLogins    tb2
            ,#tb1_UA             tb1
      where
             tb2.LoginName     = tb1.LoginName
      and    tb2.AUser        IS Null



UPDATE       #tb2_PlainLogins
      set
             AUser    =
                  CASE @CountSkipPossUsers
                     When  0  Then  'NO'
                     Else           '?'
                  END
      where
             AUser   IS Null


-- ARemote

UPDATE       #tb2_PlainLogins
      set
             tb2.ARemote   = 'YES'
      from
             #tb2_PlainLogins             tb2
            ,master.dbo.sysremotelogins   rl
      where
             convert(smallint,tb2.SUID)   = rl.suid
      and    tb2.ARemote                 IS Null



UPDATE       #tb2_PlainLogins
      set
             ARemote  = 'no'
      where
             ARemote IS Null



------------  Optimize widths for plain Logins report  ----------


SELECT
             @charMaxLenLoginName      =
                  convert ( varchar
                           ,isnull ( max(datalength(LoginName)) ,9)
                          )
            ,@charMaxLenDBName         =
                  convert ( varchar
                           ,isnull ( max(datalength(DefDBName)) ,9)
                          )
            ,@charMaxLenLangName   =
                  convert ( varchar
                           ,isnull ( max(datalength(DefLangName)) ,11)
                          )
      from
             #tb2_PlainLogins



----------------  Print out plain Logins report  -------------

/*** Message Handlers get confused.
Raiserror('...Logins...' ,0,1)
***/

EXECUTE(
'
Set nocount off


SELECT
          ''LoginName''       = substring (LoginName     ,1 ,'
                                       + @charMaxLenLoginName   + ')

         ,SUID

         ,''DefDBName''       = substring (DefDBName     ,1 ,'
                                       + @charMaxLenDBName      + ')

         ,''DefLangName''     = substring (DefLangName   ,1 ,'
                                       + @charMaxLenLangName    + ')

         ,AUser
         ,ARemote
   from
          #tb2_PlainLogins
   order by
          LoginName


Set nocount on
'
)



------------  Optimize UA report column display widths  -----------


SELECT
             @charMaxLenLoginName   =
                  convert ( varchar
                           ,isnull ( max(datalength(LoginName)) ,9)
                          )
            ,@charMaxLenDBName      =
                  convert ( varchar
                           ,isnull ( max(datalength(DBName)) ,6)
                          )
            ,@charMaxLenUserName    =
                  convert ( varchar
                           ,isnull ( max(datalength(UserName)) ,8)
                          )
      from
             #tb1_UA



------------  Print out the UserOrAlias report  ------------

/***
Raiserror('...Logins-to-Users...' ,0,1)
***/

EXECUTE(
'
Set nocount off


SELECT
          ''LoginName''    = substring (LoginName  ,1 ,'
                                       + @charMaxLenLoginName  + ')

         ,''DBName''       = substring (DBName     ,1 ,'
                                       + @charMaxLenDBName     + ')

         ,''UserName''     = substring (UserName   ,1 ,'
                                       + @charMaxLenUserName   + ')

         ,UserOrAlias
   from
          #tb1_UA
   order by
          1 ,2 ,3


Set nocount on
'
)


-----------------------  Finalization  --------------------


IF (object_id('tempdb..#tb2_PlainLogins') IS NOT Null)
            DROP Table #tb2_PlainLogins

IF (object_id('tempdb..#tb1_UA') IS NOT Null)
            DROP Table #tb1_UA


LABEL_86RETURN:

Return @RetCode
go




raiserror(15339,-1,-1,'sp_helpindex')
go
create procedure sp_helpindex
@objname varchar(92)		/* the table to check for indexes */
as

declare @objid int		/* the object id of the table */
declare @indid int		/* the index id of an index */
declare @keys varchar(200)	/* string to build up index key in */
declare @inddesc varchar(68)	/* string to build up index desc in */
declare @dbname varchar(30)

/*
**  Check to see that the object names are local to the current database.
*/
if @objname like '%.%.%' and
	substring(@objname, 1, charindex('.', @objname) - 1) <> db_name()
	begin
		raiserror(15250,-1,-1)
		return (1)
	end

/*
**  Check to see the the table exists and initialize @objid.
*/
select @objid = object_id(@objname)

/*
**  Table doesn't exist so return.
*/
if @objid is NULL
	begin
		select @dbname=db_name()
		raiserror(15009,-1,-1,@objname,@dbname)
		return (1)
	end

/*
**  See if the object has any indexes.
**  Since there may be more than one entry in sysindexes for the object,
**  this select will set @indid to the index id of the first index.
*/
select @indid = min(indid) from sysindexes
	where id = @objid
		and indid > 0
		and indid < 255

/*
**  If no indexes, return.
*/
if @indid is NULL
	begin
		print 'Object does not have any indexes.'
		return (0)
	end

set nocount on

/*
**  Now check out each index, figure out its type and keys and
**  save the info in a temporary table that we'll print out at the end.
*/
create table #spindtab
(
	index_name		varchar(30)	NOT NULL,
	index_keys		varchar(255)	NOT NULL,
	index_description	varchar(68)	NOT NULL
)

while @indid IS NOT NULL
begin

	/*
	**  First we'll figure out what the keys are.
	*/
	declare @i int
	declare @thiskey varchar(30)
	declare @lastindid int

	select @i = 1

	while @i <= 16
	begin
		select @thiskey = index_col(@objname, @indid, @i)

		if @thiskey is null
			goto keysdone

		if @i = 1
			select @keys = index_col(@objname, @indid, @i)
		else
			select @keys = @keys + ', '+index_col(@objname, @indid, @i)

		/*
		**  Increment @i so it will check for the next key.
		*/
		select @i = @i + 1

	end


	/*
	**  When we get here we now have all the keys.
	*/
	keysdone:

	/*
	**  Initialize the index description by figuring out if it's a
	**  clustered or nonclustered index.
	*/
	if @indid = 1
		select @inddesc = 'clustered'

	if @indid > 1
		select @inddesc = 'nonclustered'

	/*
	**  Now we'll check out the status bits for this index and
	**  build an english description from them.
	*/

	/*
	**  See if the index is ignore_dupkey (0x01).
	*/
	if exists (select *
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 1
			and i.id = @objid
			and i.indid = @indid)

		select @inddesc = @inddesc + ', ' + v.name
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 1
			and i.id = @objid
			and i.indid = @indid

	/*
	**  See if the index is unique (0x02).
	*/
	if exists (select *
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 2
			and i.id = @objid
			and i.indid = @indid)

		select @inddesc = @inddesc + ', ' + v.name
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 2
			and i.id = @objid
			and i.indid = @indid

	/*
	**  See if the index is ignore_dup_row (0x04).
	*/
	if exists (select *
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 4
			and i.id = @objid
			and i.indid = @indid)

		select @inddesc = @inddesc + ', ' + v.name
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 4
			and i.id = @objid
			and i.indid = @indid

	/*
	**  See if the index is allow_dup_row (0x40).
	*/
	if exists (select *
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 64
			and i.id = @objid
			and i.indid = @indid)

		select @inddesc = @inddesc + ', ' + v.name
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 64
			and i.id = @objid
			and i.indid = @indid

	/*
	** See if the index is primary key constraint (0x800).
	*/
	if exists (select *
		from master.dbo.spt_values v, sysindexes i
		where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 2048
 			and i.id = @objid
 			and i.indid = @indid)

			select @inddesc = @inddesc + ', ' + v.name
				from master.dbo.spt_values v, sysindexes i
				where i.status & v.number = v.number
					and v.type = 'I'
					and v.number = 2048
					and i.id = @objid
					and i.indid = @indid

	/*
	**  See if the index is unique key constraint (0x1000).
 	*/
	if exists (select * from master.dbo.spt_values v, sysindexes i
			where i.status & v.number = v.number
			and v.type = 'I'
			and v.number = 4096
			and i.id = @objid
 			and i.indid = @indid)

			select @inddesc = @inddesc + ', ' + v.name
				from master.dbo.spt_values v, sysindexes i
				where i.status & v.number = v.number
					and v.type = 'I'
					and v.number = 2048
					and i.id = @objid
					and i.indid = @indid

	/*
	**  Add the location of the data.
	*/

	select @inddesc = @inddesc + ' located on ' + s.name
		from syssegments s, sysindexes i
		where s.segment = i.segment
			and i.id = @objid
			and i.indid = @indid

	/*
	**  Now we have the whole description for the index so we'll add
	**  the goods to the temporary table.
	*/
	insert into #spindtab
		select name, @keys, @inddesc
			from sysindexes
			where id = @objid
				and indid = @indid
	/*
	**  Now move @indid to the next index.
	*/
	select @lastindid = @indid
	select @indid = NULL
	select @indid = min(indid)
		from sysindexes
		where id = @objid
			and indid > @lastindid
			and indid < 255
end

/*
**  Now print out the contents of the temporary index table.
*/
select index_name = substring(index_name, 1, 20),
	index_description = substring(index_description, 1, 56),
	index_keys = index_keys from #spindtab

set nocount off

return (0)
go


raiserror(15339,-1,-1,'sp_helpjoins')
go
create procedure sp_helpjoins
@lefttab varchar(92),			/* name of first table to join */
@righttab varchar(92)			/* name of first table to join */
as

declare @leftid int			/* id of first table */
declare @rightid int			/* id of second table */
declare @foundit bit			/* flag to indicate joins found */

/*
**  This procedure returns any foreign or common joins.
**  If none exists, then it returns any joins that have the same usertype.
**  If none exists, it returns any joins that have the same physical type.
*/

/*
**  Make sure the @objname is local to the current database.
*/
if (@lefttab like '%.%.%' and
	substring(@lefttab, 1, charindex('.', @lefttab) - 1) <> db_name())
OR
	(@righttab like '%.%.%' and
	substring(@righttab, 1, charindex('.', @righttab) - 1) <> db_name())
		begin
			raiserror(15250,-1,-1)
			return (1)
		end

/*
**  See if we can find the objects.  They must be a system table, user table,
**  or view.  The low 4 bits of sysobjects.sysstat indicate what the
**  object type is -- it's more reliable than using sysobjects.type which
**  could change.
*/
select @leftid = id
	from sysobjects
		where id = object_id(@lefttab)
			and (sysstat & 0xf = 1		/* system table */
				or sysstat & 0xf = 2	/* view */
				or sysstat & 0xf = 3)	/* user table */
select @rightid = id
	from sysobjects
		where id = object_id(@righttab)
			and (sysstat & 0xf = 1		/* system table */
				or sysstat & 0xf = 2	/* view */
				or sysstat & 0xf = 3)	/* user table */

/*
**  If either of the tables don't exist, quit.
*/
if @leftid is NULL
	begin
		raiserror(15195,-1,-1)
		return (1)
	end
if @rightid is NULL
	begin
		raiserror(15196,-1,-1)
		return (1)
	end

create table #hjtab
(
	a1	varchar(30) NOT NULL,
	a2	varchar(30) NOT NULL,
	b1	varchar(30) null,
	b2	varchar(30) null,
	c1	varchar(30) null,
	c2	varchar(30) null,
	d1	varchar(30) null,
	d2	varchar(30) null,
	e1	varchar(30) null,
	e2	varchar(30) null,
	f1	varchar(30) null,
	f2	varchar(30) null,
	g1	varchar(30) null,
	g2	varchar(30) null,
	h1	varchar(30) null,
	h2	varchar(30) null
)

/*
**  Look for foreign key joins.
*/
select @foundit = 0
if exists (select *
		from syskeys
			where type = 2
				and id = @leftid
				and depid = @rightid)
begin
	insert into #hjtab
	select distinct first_pair = col_name(id, key1), col_name(depid, depkey1),
		second_pair = col_name(id, key2), col_name(depid, depkey2),
		third_pair = col_name(id, key3), col_name(depid, depkey3),
		fourth_pair = col_name(id, key4), col_name(depid, depkey4),
		fifth_pair = col_name(id, key5), col_name(depid, depkey5),
		sixth_pair = col_name(id, key6), col_name(depid, depkey6),
		seventh_pair = col_name(id, key7), col_name(depid, depkey7),
		eighth_pair = col_name(id, key8), col_name(depid, depkey8)
	from syskeys
		where type = 2
			and id = @leftid
			and depid = @rightid

	select @foundit = 1
end

if exists (select *
		from syskeys
			where type = 2
				and id = @rightid
				and depid = @leftid)
begin
	insert into #hjtab
	select distinct first_pair = col_name(depid, depkey1), col_name(id, key1),
		second_pair = col_name(depid, depkey2), col_name(id, key2),
		third_pair = col_name(depid, depkey3), col_name(id, key3),
		fourth_pair = col_name(depid, depkey4), col_name(id, key4),
		fifth_pair = col_name(depid, depkey5), col_name(id, key5),
		sixth_pair = col_name(depid, depkey6), col_name(id, key6),
		seventh_pair = col_name(depid, depkey7), col_name(id, key7),
		eighth_pair = col_name(depid, depkey8), col_name(id, key8)
	from syskeys
		where type = 2
			and id = @rightid
			and depid = @leftid

	select @foundit = 1
end

/*
**  Look for common key joins.
*/
if exists (select *
		from syskeys
			where type = 3
				and id = @leftid
				and depid = @rightid)
begin
	insert into #hjtab
	select distinct first_pair = col_name(id, key1), col_name(depid, depkey1),
		second_pair = col_name(id, key2), col_name(depid, depkey2),
		third_pair = col_name(id, key3), col_name(depid, depkey3),
		fourth_pair = col_name(id, key4), col_name(depid, depkey4),
		fifth_pair = col_name(id, key5), col_name(depid, depkey5),
		sixth_pair = col_name(id, key6), col_name(depid, depkey6),
		seventh_pair = col_name(id, key7), col_name(depid, depkey7),
		eighth_pair = col_name(id, key8), col_name(depid, depkey8)
	from syskeys
		where type = 3
			and id = @leftid
			and depid = @rightid

	select @foundit = 1
end

if exists (select *
		from syskeys
			where type = 3
				and id = @rightid
				and depid = @leftid)
begin
	insert into #hjtab
	select distinct first_pair = col_name(depid, depkey1), col_name(id, key1),
		second_pair = col_name(depid, depkey2), col_name(id, key2),
		third_pair = col_name(depid, depkey3), col_name(id, key3),
		fourth_pair = col_name(depid, depkey4), col_name(id, key4),
		fifth_pair = col_name(depid, depkey5), col_name(id, key5),
		sixth_pair = col_name(depid, depkey6), col_name(id, key6),
		seventh_pair = col_name(depid, depkey7), col_name(id, key7),
		eighth_pair = col_name(depid, depkey8), col_name(id, key8)
	from syskeys
		where type = 3
			and id = @rightid
			and depid = @leftid

	select @foundit = 1
end

/*
**  We got a foreignkey and we didn't get a common key.
*/
if @foundit = 1
	begin
		select distinct * from #hjtab

		drop table #hjtab

		return (0)
	end

/*
**  We didn't find any defined joins so we'll look for common user types.
*/
if exists (select *
		from syscolumns a, syscolumns b
			where a.id = @leftid
				and b.id = @rightid
				and a.usertype = b.usertype
				and a.usertype > 99)
begin
	select distinct first_pair = col_name(a.id, a.colid),
		col_name(b.id, b.colid)
	from syscolumns a, syscolumns b
		where a.id = @leftid
			and b.id = @rightid
			and a.usertype = b.usertype
			and a.usertype > 99
	order by first_pair

	/*
	**  If we found something, we can stop.
	*/
	if @@rowcount > 0
		return (0)
end

/*
**  We couldn't find anything so far so we'll see if we have anything
**  that just shares the same physical type.
*/
if exists (select *
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
		where a.id = @leftid
			and b.id = @rightid
			and a.id <> b.id
			and a.name = b.name
			and y.type = 'J'
			and a.type = y.low
			and z.type = 'J'
			and b.type = z.low
			and y.number = z.number)
begin
	select distinct first_pair = col_name(a.id, a.colid),
		col_name(b.id, b.colid)
	from syscolumns a, syscolumns b, master.dbo.spt_values y,
		master.dbo.spt_values z
	where a.id = @leftid
		and b.id = @rightid
		and a.id <> b.id
		and a.name = b.name
		and y.type = 'J'
		and a.type = y.low
		and z.type = 'J'
		and b.type = z.low
		and y.number = z.number
	order by first_pair

end

return (0)
go


raiserror(15339,-1,-1,'sp_helpkey')
go
create procedure sp_helpkey
@tabname varchar(92) = null,	/* table or view we want to check */
@nomsg varchar(5) = 'msg'	/* option param. to suppress printing
				** of suggestion to also use
				** sp_helpconstraint to view additional
				** constraints. */
as

declare	@tabid	int	/* id of table or view we want to check */
declare @dbname varchar(30)

/*
**  Check to see that the object names are local to the current database.
*/
if @tabname like '%.%.%' and
	substring(@tabname, 1, charindex('.', @tabname) - 1) <> db_name()
	begin
		raiserror(15078,-1,-1)
		return (1)
	end

/*
**  If @tabname is null, show all the keys.
*/
print ''

if @tabname is null
begin
	select keytype = substring(v.name, 1, 10), object = object_name(k.id),
		related_object = isnull(object_name(k.depid), ' -- none --'),
		object_keys = substring(col_name(k.id, key1) + ', '
			+ isnull(col_name(k.id, key2), '*') + ', '
			+ isnull(col_name(k.id, key3), '*') + ', '
			+ isnull(col_name(k.id, key4), '*') + ', '
			+ isnull(col_name(k.id, key5), '*') + ', '
			+ isnull(col_name(k.id, key6), '*') + ', '
			+ isnull(col_name(k.id, key7), '*') + ', '
			+ isnull(col_name(k.id, key8), '*'), 1, 70),
		related_keys = substring(isnull(col_name(k.depid, depkey1), '*')
			+ ', '
			+ isnull(col_name(k.depid, depkey2), '*') + ', '
			+ isnull(col_name(k.depid, depkey3), '*') + ', '
			+ isnull(col_name(k.depid, depkey4), '*') + ', '
			+ isnull(col_name(k.depid, depkey5), '*') + ', '
			+ isnull(col_name(k.depid, depkey6), '*') + ', '
			+ isnull(col_name(k.depid, depkey7), '*') + ', '
			+ isnull(col_name(k.depid, depkey8), '*'), 1, 70)
	from syskeys k, master.dbo.spt_values v
	where k.type = v.number
		and v.type = 'K'
	order by object, keytype, related_object

	return (0)
end

/*
**  We're looking for a particular table or view.
*/
else
begin
	/*
	**  Make sure the table or view exists.
	*/
	select @tabid = object_id(@tabname)

	if @tabid is null
		begin
			select @dbname=db_name()
			raiserror(15009,-1,-1,@tabname,@dbname)
			return (1)
		end

	/*
	**  See if any keys exist.
	*/
	if not exists (select *
			from syskeys
			where id = @tabid or depid = @tabid)
		begin
			if @nomsg <> 'nomsg'
				begin
					print 'No keys were defined for this object using sp_primarykey,'
					print 'sp_foreignkey or sp_commonkey.  Please use sp_helpconstraint'
					print 'to list any ''system enforced'' keys.'
				end

			return (0)
		end

	select keytype = substring(v.name, 1, 10), object = object_name(k.id),
		related_object = isnull(object_name(k.depid), ' -- none --'),
		object_keys = substring(col_name(k.id, key1) + ', '
			+ isnull(col_name(k.id, key2), '*') + ', '
			+ isnull(col_name(k.id, key3), '*') + ', '
			+ isnull(col_name(k.id, key4), '*') + ', '
			+ isnull(col_name(k.id, key5), '*') + ', '
			+ isnull(col_name(k.id, key6), '*') + ', '
			+ isnull(col_name(k.id, key7), '*') + ', '
			+ isnull(col_name(k.id, key8), '*'), 1, 70),
		related_keys = substring(isnull(col_name(k.depid, depkey1), '*')
			+ ', '
			+ isnull(col_name(k.depid, depkey2), '*') + ', '
			+ isnull(col_name(k.depid, depkey3), '*') + ', '
			+ isnull(col_name(k.depid, depkey4), '*') + ', '
			+ isnull(col_name(k.depid, depkey5), '*') + ', '
			+ isnull(col_name(k.depid, depkey6), '*') + ', '
			+ isnull(col_name(k.depid, depkey7), '*') + ', '
			+ isnull(col_name(k.depid, depkey8), '*'), 1, 70)
	from syskeys k, master.dbo.spt_values v
	where k.type = v.number
		and v.type = 'K'
		and (k.id = @tabid or k.depid = @tabid)
	order by object, keytype, related_object

	return (0)
end
go


raiserror(15339,-1,-1,'sp_objectsegment')
go
create procedure sp_objectsegment
@objid	int
as
	/*
	** Print out the object's data segment if applicable.
	*/

	if exists (select * from sysobjects
			where id = @objid
			and sysstat & 0xf in (1,3))	-- system table or user table.
		begin
			select Data_located_on_segment = s.name
			from syssegments s, sysindexes i
			where i.id = @objid
				and i.indid < 2
				and i.segment = s.segment
		end

	/*
	**  It's not a table so segment is not applicable.
	*/
	else
		select Data_located_on_segment = 'not applicable'

return (0)
go



raiserror(15339,-1,-1,'sp_help')
go
create procedure sp_help  -- 1995/09/13 18:23
    @objname varchar(92) = NULL      /* object name we're after */
as

declare @objid int         /* id of the object */
declare @sysstat smallint     /* the type of the object */
declare @dbname varchar(30)
declare @colname varchar(30)

set nocount on

/*
**  If no @objname given, give a little info about all objects.
*/
if @objname is null
begin
   select Name = o.name,
      Owner = user_name(uid),
      Object_type = v.name + x.name
   from sysobjects o, master.dbo.spt_values v, master.dbo.spt_values x
   where o.sysstat & 0xf = v.number
      and v.type = 'O'
      and x.type = 'R'
      and o.userstat & -32768 = x.number
   order by Object_type desc, Name asc

   print ''

   select User_type = s.name,
          'Storage_type' = st.name,
          'Length' = s.length,
          'Prec' =
         case when s.type in  -- Prec. only valid for numerics.
         (38,48,52,55,56,59,60,62,63,106,108,109,110,122)
         then convert(varchar(4),s.prec)
         else ' '
         end,
          'Scale' =
         case when s.type in  -- Scale only valid for numerics.
         (38,48,52,55,56,59,60,62,63,106,108,109,110,122)
         then convert(varchar(4),s.scale)
         else ' '
         end,
          'Nullable' = (select name from spt_values
            where number = convert(int,s.allownulls)
            and type = 'B'),
          'Default_name' = isnull(object_name(s.tdefault),
         (select name from master.dbo.spt_values
            where number = 2 and type = 'B')),
          'Rule_name' = isnull(object_name(s.domain),
         (select name from master.dbo.spt_values
            where number = 2 and type = 'B'))
   from systypes s, systypes st
   where s.type = st.type
      and s.usertype > 99
      and st.usertype <= 99
      and st.usertype <> 18 /* ignore sysname */
   order by s.name

   return(0)
end

/*
**  Make sure the @objname is local to the current database.
*/
if @objname like '%.%.%' and
   substring(@objname, 1, charindex('.', @objname) - 1) <> db_name()
   begin
      raiserror(15250,-1,-1)
      return(1)
   end

/*
**  Now check to see if the @objname is in sysobjects.  It has to be either
**  in sysobjects or systypes.
*/
select @objid = id, @sysstat = sysstat from sysobjects
   where id = object_id(@objname)

/*
**  It wasn't in sysobjects so we'll check in systypes.
*/
if @objid is null
begin
   select @objid = usertype from systypes where name = @objname

   /*
   **  Time to give up -- @objname is not in sysobjects or systypes.
   */
   if @objid is null
      begin
         select @dbname=db_name()
         raiserror(15009,-1,-1,@objname,@dbname)
         return(1)
      end

   /*
   ** Print help about a data type.  Prec and scale only valid
   ** for numerics.
   */

   if (select type from systypes
      where usertype = @objid) in
         (38,48,52,55,56,59,60,62,63,106,108,109,110,122)

      select Type_name = s.name,
         Storage_type = st.name,
         Length = s.length,
         Prec = s.prec,
         Scale = s.scale,
         'Nullable' = (select name from master.dbo.spt_values
               where number =
                  convert(int,s.allownulls)
                  and type = 'B'),
         Default_name = isnull(object_name(s.tdefault),
            (select name from master.dbo.spt_values
               where number = 2 and type = 'B')),
         Rule_name = isnull(object_name(s.domain),
            (select name from master.dbo.spt_values
               where number = 2 and type = 'B'))
      from systypes s, systypes st
      where s.usertype = @objid
         and s.type = st.type
         and st.usertype <> 18 /* ignore sysname */
         and st.usertype < 100
   else
      select Type_name = s.name,
         Storage_type = st.name,
         Length = s.length,
         Prec = '',
         Scale = '',
         'Nullable' = (select name from master.dbo.spt_values
               where number =
                  convert(int,s.allownulls)
                  and type = 'B'),
         Default_name = isnull(object_name(s.tdefault),
            (select name from master.dbo.spt_values
               where number = 2 and type = 'B')),
         Rule_name =
            isnull(object_name(s.domain),
            (select name from master.dbo.spt_values
               where number = 2 and type = 'B'))
      from systypes s, systypes st
      where s.usertype = @objid
         and s.type = st.type
         and st.usertype <> 18 /* ignore sysname */
         and st.usertype < 100


   return(0)
end

/*
**  It's in sysobjects so print out the information.
*/
select Name = o.name,
   Owner = user_name(uid),
   Type = v.name + x.name,
   When_created = o.crdate
from sysobjects o, master.dbo.spt_values v, master.dbo.spt_values x
where o.id = @objid
   and o.sysstat & 0xf = v.number
   and v.type = 'O'
   and x.type = 'R'
   and o.userstat & -32768 = x.number

print ''
execute sp_objectsegment @objid

/*
**  If the object is a system table, view, or user table, we want to check
**  out the object's columns here.
*/

if @sysstat & 0xf in (1, 2, 3)   -- system table, view, or user table.
begin

   create table #sphelptab
   (
      col_name char (30)   NULL,
      col_type char (30)   NULL,
      col_len     tinyint     NULL,
      col_prec char (5) NULL,
      col_scale   char (5) NULL,
      col_status  tinyint     NULL,
      colid    tinyint     NULL,
      type_systemdata  tinyint  NULL
   )

   insert into #sphelptab
      select c.name, t.name, c.length, convert(char(5),c.prec),
         convert(char(5),c.scale), c.status,
         c.colid, t.type
      from syscolumns c, systypes t
      where c.id = @objid
         and c.usertype *= t.usertype

   /*
   ** Don't display precision and scale for datatypes
   ** for which they not applicable.
   */
   update #sphelptab
      set col_prec = '', col_scale = ''
      where col_type in
         (select name from systypes where type not in
         (38,48,52,55,56,59,60,62,63,106,108,109,110,122))

   print ''
   select Column_name = col_name,
          Type = col_type,
          Length = col_len,
          Prec = col_prec,
          Scale = col_scale,

          Nullable = case when (col_status & 8) = 0 then
            (select name from master.dbo.spt_values
               where number = 0
                  and type = 'B')
            else
            (select name from master.dbo.spt_values
               where number = 1
                  and type = 'B')
            end,

          TrimTrailingBlanks =  -- Blanks; or 0x00 bytes for varbinary
               CASE
                  When (type_systemdata NOT IN (45,47,39,37))
                     Then '(n/a)'
                  When (col_status & 0x10) > 0
                     Then (Select   name
                              from  master.dbo.spt_values
                              where number = 0 and type = 'B')
                  Else
                          (Select   name
                              from  master.dbo.spt_values
                              where number = 1 and type = 'B')
               END,

          FixedLenNullInSource =
               CASE
                  When (type_systemdata NOT IN (45,47,39,37))
                     Then '(n/a)'
                  When (col_status & 0x20) = 0
                     Then (Select   name
                              from  master.dbo.spt_values
                              where number = 0 and type = 'B')
                  Else
                          (Select   name
                              from  master.dbo.spt_values
                              where number = 1 and type = 'B')
               END

   from #sphelptab
   order by colid

   -- See if there is an identity column.

   print ''
   select @colname = null
   select @colname = col_name from #sphelptab
      where (col_status & 128) = 128

   select 'Identity' = isnull(@colname,'No identity column defined.'),
          'Seed' = ident_seed(@objname),
          'Increment' = ident_incr(@objname)

end

/*
**  For procedures, the parameters of the procedures are stored in syscolumns.
*/
if @sysstat & 0xf = 4   -- stored procedure
begin
   /*
   **  Does the sproc have any parameters?
   */
   if exists (select * from syscolumns c, systypes t
         where c.id = @objid
            and c.usertype *= t.usertype)
   begin
      print ''
      select Parameter_name = c.name,
         Type = t.name,
         Length = c.length,
         Prec = c.prec,
         Scale = c.scale,
         Param_order=c.colid
      from syscolumns c, systypes t
      where c.id = @objid
         and c.usertype *= t.usertype
   end
end

/*
**  If the object is a table, check out the indexes.
*/
if @sysstat & 0xf in (1, 3)   -- system table or user table
   begin
      print ''
      execute sp_helpindex @objname
   end

/*
**  If the object is a table or view, check out the constraints.
*/
if @sysstat & 0xf in (1, 2, 3)   -- system table, view, or user table
   begin
      print ''
      execute sp_helpconstraint @objname,'nomsg'
   end

return (0)
go


dump transaction master with no_log
go



raiserror(15339,-1,-1,'sp_a_count_bits_on')
go
CREATE Procedure sp_a_count_bits_on --1995/10/01 21:04

/**
Originally written 1995/10/01 for sp_helprotect.
Count of ON bits is RETURNed.
**/

    @p_int                       int

   ,@p_num_bits_want_counted     smallint    = 32 --  1 thru 32 are valid.
AS

Set nocount on

Declare
    @one_bit_int_value           int
   ,@count_on_bits               smallint
   ,@count_bits                  smallint
   ,@test_bit_int_value          int
   ,@two_byte_int                int
   ,@b4_p_int                    binary(4)
   ,@pos_b4                      smallint
   ,@bits_counted_previously     smallint
   ,@bits_counted_on_previously  smallint


-----------------  Edit input parms  --------------------


IF (@p_int IS Null)
   RETURN 0

Select @b4_p_int = convert(binary(4),@p_int)



IF (     isnull(@p_num_bits_want_counted,0) <  1
    OR   isnull(@p_num_bits_want_counted,0) > 32
   )
   RETURN 0



------------------  Mainline  -----------------------------


----------------  LOOP 10:  Halves of datatype INTEGER  ---


Select
       @bits_counted_previously     = 0
      ,@bits_counted_on_previously  = 0

Select @pos_b4 = 3




WHILE (@pos_b4 >= 1
      )
   begin --loop 10


   Select @two_byte_int = convert(int,substring(@b4_p_int,@pos_b4,2))



----------------  LOOP 20:  Individual bit tests  -----------


   Select
       @test_bit_int_value    = 1
      ,@count_bits            = 0
      ,@count_on_bits         = 0



   WHILE (     @count_bits                              < 16
          AND  (@bits_counted_previously + @count_bits) <
                                           @p_num_bits_want_counted
         )
      begin --loop 20

      Select @count_bits = @count_bits + 1

      Select @one_bit_int_value = @two_byte_int & @test_bit_int_value


      if (@one_bit_int_value > 0)
         Select @count_on_bits = @count_on_bits + 1


      select @test_bit_int_value = @test_bit_int_value * 2

      end --loop 20




   Select @bits_counted_previously =
          @bits_counted_previously + @count_bits

   Select @bits_counted_on_previously =
          @bits_counted_on_previously + @count_on_bits


   Select @pos_b4 = @pos_b4 - 2


   end --loop 10



-----------------  Finalization  ---------------------------


RETURN @bits_counted_on_previously
go



raiserror(15339,-1,-1,'sp_helprotect')
go
CREATE PROCEDURE sp_helprotect -- 1996/03/04 13:02

    @name   character varying(99)  = '%'
   ,@username                character varying(66)  = '%'
   ,@grantorname                character varying(66)  = '%'
   ,@permissionarea      character varying(10)  = 'o s'
AS

/********
      Explanation of the parms...
      ---------------------------
@name:  Name of [Owner.]Object and Statement; meaning
                             for sysprotects.id and sysprotects.action at the
                             same time; thus see parm @permissionarea.
   Examples-   'user2.tb%'  , 'create%'

@username:  Name of the grantee (for sysprotects.uid).
   Examples-   'user2'

@grantorname:  Name of the grantor (for sysprotects.grantor).
   Examples-   '[^d]%' --Would prevent report rows which would
                       --  have 'dbo' as grantor.

@permissionarea:  O=Object, S=Statement; include all which apply.
   Examples-   'o'  , ',s'  , 'os'  , 'so'  , 's o'  , 's,o'
GeneMi
********/


Set nocount on

Declare
       @RetCode               integer
      ,@High2Int              integer
      ,@High4Int              integer
      ,@Int1                  integer
      ,@Int2                  integer
      ,@Int3                  integer
      ,@Int4                  integer
      ,@vc1                   varchar(64)

Declare
       @full_len_need_sysprots_cols    integer
      ,@num_col_bits_on                integer

Declare
       @Tinyint1              tinyint

Declare
       @charMaxLenOwner       character varying(11)
      ,@charMaxLenObject      character varying(11)
      ,@charMaxLenGrantee     character varying(11)
      ,@charMaxLenGrantor     character varying(11)
      ,@charMaxLenAction      character varying(11)
      ,@charMaxLenColumnName  character varying(11)

Declare
       @OrderBy               character varying(255)

      ,@OwnerName             character varying(66)
      ,@ObjectStatementName   character varying(66)

      ,@VarBinFront           varbinary(32)
      ,@VarBinBack            varbinary(32)
      ,@Bin1                  varbinary(1)

Declare
       @c1pkid                integer
      ,@c1id                  integer
      ,@c1uid                 smallint
      ,@c1action              tinyint
      ,@c1protecttype         tinyint
      ,@c1columns             varbinary(32)
      ,@c1grantor             smallint

Declare
       @t1_all_col_bits_on             tinyint
      ,@t1_columns_orig_datalength     smallint
      ,@t1_columns_flip_datalength     smallint
      ,@t1_columns_flipped             varbinary(32)
      ,@t1_columns_orig                varbinary(32)
      ,@t1_max_colid                   smallint
      ,@t1_type1code                   char(6)
      ,@t1_objtype                     char(2)
      ,@t1_new_bit_on                  tinyint



----------------------------------------------------------------------------
--
--             Initialization
--
----------------------------------------------------------------------------


Select
       @RetCode               = 0            -- 0=good ,1=bad
      ,@High2Int              =      32767
      ,@High4Int              = 2147483647


-----------------------  Input parm edits  ---------------------


Select @permissionarea = upper( isnull(@permissionarea,'?') )

IF (     charindex('O',@permissionarea) <= 0
    AND  charindex('S',@permissionarea) <= 0
   )
   begin
   RaisError(15300,-1,-1 ,@permissionarea,'o,s')
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


--------


IF (     @name IS Null
    OR   @username              IS Null
    OR   @grantorname              IS Null
   )
   begin
   RaisError(15008,-1,-1)  --No nulls allowed, use '%' instead.
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


--------  Derive OwnerName


IF (@name LIKE '%.%.%')
   begin
   Select @Int1 = charindex('.',@name)

   Select @vc1 = substring(@name,1,(@Int1-1))

   IF (@vc1 <> db_name())
      begin
      RaisError(15302,-1,-1)  --Do not qualify with DB name.
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end

   Select @name =
            substring(@name,(@Int1+1),255)
   end




IF (@name LIKE '%.%')

   Select
          @OwnerName    =
               substring ( @name
                          ,1
                          ,charindex('.' ,@name) - 1
                         )
         ,@ObjectStatementName   =
               substring ( @name
                          ,charindex('.' ,@name) + 1
                          ,Datalength(@name)
                         )
ELSE

   Select
          @OwnerName             = '%'
         ,@ObjectStatementName   = @name



----------------------------------------------------------------------------
--
--             MainLine:  Phase 10
--
----------------------------------------------------------------------------



--------------  create a fixed copy of sysprotects for processing  --------


-- Simpler when bit 0 is OFF, because other ON bits really mean ON.


CREATE Table #t1_Prots
   (
    pkid                int               not null    identity(1,1)
   ,type1code           char(6)           not null
   ,status              smallint          not null -- 0=unprocessed
   ,objtype             char(2)               null

   ,id                  int                   null
   ,uid                 smallint              null
   ,action              tinyint               null
   ,protecttype         tinyint               null
   ,grantor             smallint              null
   ,columns_orig        varbinary(32)         null

   ,columns_flipped     varbinary(32)         null
   ,max_colid           smallint              null
   ,all_col_bits_on     tinyint               null
   ,new_bit_on          tinyint               null  -- 1=yes on
   )



CREATE Unique    Clustered Index ix1 on #t1_Prots (pkid)
CREATE Unique Nonclustered Index ix2 on #t1_Prots (id,uid,action,protecttype,grantor)




-- Will loop through OFF=ON rows to finish the copy of sysprotects.
-- For these rows, ON=ON only for the 0x01 bit.

DECLARE Cursor1_Prots
   Insensitive
   Cursor For
SELECT
             id
            ,uid
            ,action
            ,protecttype
            ,columns
            ,grantor
      from
             sysprotects
   For Read Only



OPEN Cursor1_Prots



---------------
WHILE (110=110)
   begin


   FETCH
             Next
      from
             Cursor1_Prots
      into
             @c1id
            ,@c1uid
            ,@c1action
            ,@c1protecttype
            ,@c1columns
            ,@c1grantor



   IF (@@fetch_status <> 0)
      begin
      Deallocate Cursor1_Prots
      BREAK
      end


   Select
          @t1_type1code               = Null
         ,@t1_columns_orig            = @c1columns
         ,@t1_columns_orig_datalength = datalength(@c1columns) --Null if null.
         ,@t1_max_colid               = Null
         ,@t1_all_col_bits_on         = Null
         ,@t1_new_bit_on              = Null
         ,@t1_type1code               = '1Regul'
         ,@t1_objtype                 = Null


   SELECT
             @t1_objtype   = ob.type
      from
             sysobjects    ob
      where
             ob.id         = @c1id




---------------  Handle the simple cases first.


   IF (@c1columns IS Null)
      begin
      Select @t1_type1code       = '2Simpl'
            ,@t1_columns_flipped = @c1columns
      GOTO LABEL_49INSERT1
      end



---------------------  Upcoming steps...  ------------------


--Pad columns bits variable to full needed length.
--Flip most bits in columns bits var, so ON=ON consistently.
--Count ON bits in columns bits var, compare to max syscolumns colid.
--Insert #t2



------------------------------------------------------------------------
--------------  Must first append some 0x00 paddings perhaps  ----------


   SELECT
             @t1_max_colid = max(colid)  --Cannot come back Null this time.
      from
             syscolumns
      where
             id    = @c1id



--As needed, later add 1 bitcount for the All/New 0x01 "zero" bit
--   of the first sysprotects.columns bytes.


   Select @full_len_need_sysprots_cols =
          (@t1_max_colid + 1) / 8       --8 bits per byte; trunc not round


   IF ((@t1_max_colid + 1) % 8 > 0)
      Select @full_len_need_sysprots_cols =
             @full_len_need_sysprots_cols + 1


   --------------------------------------
   WHILE (datalength(@c1columns) < @full_len_need_sysprots_cols
         )
      begin                      --Pad the columns bits variable.

      Select @c1columns = @c1columns + 0x00 --convert(binary(1),0x00) is trimmed

      end --loop to pad


   Select @t1_columns_flip_datalength = datalength(@c1columns)




------------------------------------------------------------------------
-----------------  Flip most bits, so never OFF=ON anymore  ------------



--Bit operators do not work against binarys, so use int.



   Select @Int1 = convert(int,substring(@c1columns,1,1))

   IF (@Int1 & 1 = 0
      )
      begin
      Select @t1_new_bit_on = 0

      GOTO LABEL_73BITONMEANSON  --ON already means ON consistently

      end
   ELSE
      Select @t1_new_bit_on = 1

   IF (@t1_objtype = 'V ')
      begin
      Select @t1_new_bit_on = 0

      Select @Int1 = @Int1 & ~1  --Views cannot get "New" columns.
      Select @Bin1 = convert(binary(1),@Int1)  --Len 1 not trimmed.
      Select @c1columns = @Bin1 +
                          substring(@c1columns,2,@t1_columns_flip_datalength-1)
      end





   Select @Int1 = 0  --Position in substring


--Proper for Revoke rows as well as for Grant rows.
   ------------------------------------
   WHILE (@t1_columns_flip_datalength > @Int1
         )
      begin  --Total length > current byte position, more Flipping.


      Select @Int1 = @Int1 + 1  --increment pos


      IF (1 = @Int1)
         begin
         Select @VarBinFront = Null
         Select @Bin1        = substring(@c1columns ,@Int1   ,1)
         Select @VarBinBack  = substring(@c1columns ,@Int1+1
                                        ,@t1_columns_flip_datalength-@Int1)
         end


      IF (     1                           < @Int1
          AND  @t1_columns_flip_datalength > @Int1
         )
         begin
         Select @VarBinFront = substring(@c1columns ,1       ,@Int1-1)
         Select @Bin1        = substring(@c1columns ,@Int1   ,1)
         Select @VarBinBack  = substring(@c1columns ,@Int1+1
                                        ,@t1_columns_flip_datalength-@Int1)
         end


      IF (@t1_columns_flip_datalength = @Int1)
         begin
         Select @VarBinFront = substring(@c1columns ,1       ,@Int1-1)
         Select @Bin1        = substring(@c1columns ,@Int1   ,1)
         Select @VarBinBack  = Null
         end



      Select @Int3 = convert(int,@Bin1)



      IF (     @Int1     = 1  --Byte containing the All/NewCols bit (0x01)
          AND  @Int3 & 1 > 0  --NewCols bit on
         )
         Select @Int3 = @Int3 & (~1)  --Flip (here Turn off) the 0x01 bit



      --Flip all the bits (so 0x01 bit return to its initial setting).
      Select @Int3 = ~@Int3

      Select @Bin1      = convert(binary(1),@Int3)

      Select @c1columns = @VarBinFront + @Bin1 + @VarBinBack


      end  --loop to flip most bits



LABEL_73BITONMEANSON:



------------------------------------------------------------------------------
-----------  Determine whether all current columns are individually ON!  -----



LABEL_42LOOP110EACHBIT:



   Select
       @Int1                     = 0  --POSition
      ,@num_col_bits_on          = 0



   WHILE (37=37)
      begin

      Select @Int1 = @Int1 + 1

      IF (@Int1 > @full_len_need_sysprots_cols)
         BREAK


      Select @Int2 = convert( int ,substring(@c1columns ,@Int1 ,1) )



      IF (@Int1 <= (@t1_max_colid + 1) / 8    --truncated, not rounded
         )
         Select @Int4 = 8  --num of Bits want tested in this byte/number
      ELSE
         Select @Int4 = (@t1_max_colid + 1) % 8



      Execute @Int3 =  sp_a_count_bits_on  @Int2 ,@Int4


      IF (     @Int1       = 1
          AND  @Int2 & 1   > 0
         )
         Select @Int3 = @Int3 - 1  --Do not count "New" bit.


      Select @num_col_bits_on = @num_col_bits_on + @Int3


      end --loop 37




   IF (@t1_max_colid = @num_col_bits_on)   --  @ < @  impossible
      Select @t1_all_col_bits_on = 1
   ELSE
      Select @t1_all_col_bits_on = 0




-------------------------------------------------------------------------
----------------  Finally, Ins modified copy of sysprotects row  --------



LABEL_49INSERT1:



   INSERT
             #t1_Prots
         (
           --pkid,
             type1code
            ,status
            ,objtype
            ,id
            ,uid
            ,action
            ,protecttype
            ,grantor
            ,columns_orig
            ,columns_flipped
            ,max_colid
            ,all_col_bits_on
            ,new_bit_on
         )
      Values
         (
             --identity,
             @t1_type1code
            ,0
            ,@t1_objtype
            ,@c1id
            ,@c1uid
            ,@c1action
            ,@c1protecttype
            ,@c1grantor
            ,@t1_columns_orig
            ,@c1columns
            ,@t1_max_colid
            ,@t1_all_col_bits_on
            ,@t1_new_bit_on
         )


   end  --loop 110




----------------------------------------------------------------------------
--
--             MainLine:  Phase 20
--
----------------------------------------------------------------------------



------------------  create smart temporary holding table  --------------


CREATE TABLE #t2_SmartProts    --The z's avoid label/colname sorting conflicts
   (
    zPKId               int            NOT Null    Identity(1,1)
   ,zType2Code          char(6)        NOT Null
   ,zStatus             smallint       NOT Null
   ,zOwnerName          varchar(30)    NOT Null
   ,zObjectName         varchar(30)    NOT Null
   ,zGranteeName        varchar(30)    NOT Null
   ,zGrantorName        varchar(30)    NOT Null
   ,zProtectTypeNum     tinyint        NOT Null --Revoke rows have effects.
   ,zProtectTypeName    char(10)           Null
   ,zProtectCategory    char(2)            Null
   ,zWGO                char(3)            Null
   ,zActionNum          tinyint        NOT Null
   ,zActionName         varchar(20)        Null
   ,zActionCategory     char(2)            Null
   ,zColumnName         varchar(30)    NOT Null
   ,zColId              smallint           Null
   )


CREATE Unique Clustered
   INDEX    ix1
   ON       #t2_SmartProts
      (zPKId)



---------------------  Populate the holding table  -----------------------


--------  Only non objects  ---


IF (charindex('S',@permissionarea) <= 0)
   GOTO LABEL_1NOOBJ



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '1NOOBJ'
            ,0
            ,'.'
            ,'.'
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,'.'
            ,Null
      from
             #t1_Prots              prot1
            ,sysusers               usr2
            ,sysusers               usr3
            ,master.dbo.spt_values  val1
      where
             prot1.columns_orig IS Null
      and    prot1.objtype      IS Null
      and
             usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             val1.number   =  prot1.action
      and    val1.type     = 'T'
      and
             val1.name  LIKE  @ObjectStatementName
      and
             prot1.id      = 0
      and
             prot1.status  = 0




UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,1)
   from
             #t1_Prots              prot1
            ,sysusers               usr2
            ,sysusers               usr3
            ,master.dbo.spt_values  val1
      where
             prot1.columns_orig IS Null
      and    prot1.objtype      IS Null
      and
             usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             val1.number   =  prot1.action
      and    val1.type     = 'T'
      and
             val1.name  LIKE  @ObjectStatementName
      and
             prot1.id      = 0
      and
             prot1.status  = 0



LABEL_1NOOBJ:




-----------  Only objects, and only null columns  ---------



IF (charindex('O',@permissionarea) <= 0)
   GOTO LABEL_2OBNUL



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '2OBNUL'
            ,0
            ,usr1.name
            ,obj1.name
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,'.'

            ,Null
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('X ' ,'P ' ,'U ' ,'S ' ,'V ')
      and
             usr1.uid      =  obj1.uid
      and    usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr1.name  LIKE  @OwnerName
      and    obj1.name  LIKE  @ObjectStatementName
      and    usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             prot1.columns_orig IS Null
      and
             prot1.status  = 0





UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,2)
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('X ' ,'P ' ,'U ' ,'S ' ,'V ')
      and
             usr1.uid      =  obj1.uid
      and    usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr1.name  LIKE  @OwnerName
      and    obj1.name  LIKE  @ObjectStatementName
      and    usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             prot1.columns_orig IS Null
      and
             prot1.status  = 0




LABEL_2OBNUL:




---------------------  Only tables where both All & New  -----------



IF (charindex('O',@permissionarea) <= 0)
   GOTO LABEL_3TBAN



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '3TBAN '
            ,0
            ,usr1.name
            ,obj1.name
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,'(All+New)'
            ,Null
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 1
      and    prot1.new_bit_on       = 1
      and
             prot1.status     = 0




UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,3)
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 1
      and    prot1.new_bit_on       = 1
      and
             prot1.status     = 0



/********
sysprotects.columns  and  spt_values.type='P':

NUMBER=ColId  ,LOW=SubstringPosOfByte  ,HIGH=Power(2,0-7 bit pos)

      NUMBER=0 detects 0x01 bit.   The 0x01 bit being on means New
columns will automatically be picked up.   And if sysprotects.columns
equals 0x01 entirely, then All Current and New columns are included.
Note that for Ins/Del Null should be treated as =0x01.
      In the first post-6.0 release the bit on/off meanings have reversed,
except for the 0x01 bit.

      Note that in MS SQL 6.0 and back, when the 0x01 bit was on
in sysprotects.columns, that no other bits were ever on or mattered.
After 6.0 the 0x01 can be on with a mixture of other bits which matter.
********/



LABEL_3TBAN:




-----------------  TBs & VWs where only All columns (not New)  -----------



IF (charindex('O',@permissionarea) <= 0)
   GOTO LABEL_4TBVWA



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '4TBVWA'
            ,0
            ,usr1.name
            ,obj1.name
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,'(All)'
            ,Null
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ' ,'V ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 1
      and    prot1.new_bit_on       = 0
      and
             prot1.status     = 0




UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,4)
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ' ,'V ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 1
      and    prot1.new_bit_on       = 0
      and
             prot1.status     = 0




LABEL_4TBVWA:




--------  TBs & VWs where not all columns were granted (avoid New)  ---------



IF (charindex('O',@permissionarea) <= 0)
   GOTO LABEL_5TBVWC



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '5TBVWC'
            ,0
            ,usr1.name
            ,obj1.name
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,col_name ( prot1.id ,val1.number )
            ,val1.number
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
            ,master.dbo.spt_values  val1
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ' ,'V ')
      and
             usr1.uid      =  obj1.uid
      and    usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr1.name  LIKE  @OwnerName
      and    obj1.name  LIKE  @ObjectStatementName
      and    usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             prot1.all_col_bits_on = 0
      and
             val1.type        = 'P'
      and
             val1.number BETWEEN 1 AND prot1.max_colid
      and
             val1.low        <= Datalength(prot1.columns_flipped)
      and
             val1.high  &
               convert(int, substring(prot1.columns_flipped ,val1.low ,1) )
                        <> 0
      and    prot1.status     = 0




UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,5)
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
            ,master.dbo.spt_values  val1
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ' ,'V ')
      and
             usr1.uid      =  obj1.uid
      and    usr2.uid      =  prot1.uid
      and    usr3.uid      =  prot1.grantor
      and
             usr1.name  LIKE  @OwnerName
      and    obj1.name  LIKE  @ObjectStatementName
      and    usr2.name  LIKE  @username
      and    usr3.name  LIKE  @grantorname
      and
             prot1.all_col_bits_on = 0
      and
             val1.type        = 'P'
      and
             val1.number BETWEEN 1 AND prot1.max_colid
      and
             val1.low        <= Datalength(prot1.columns_flipped)
      and
             val1.high  &
               convert(int, substring(prot1.columns_flipped ,val1.low ,1) )
                        <> 0
      and    prot1.status     = 0




LABEL_5TBVWC:



----------  Only tables where only New columns are authorized!  ---------



IF (charindex('O',@permissionarea) <= 0)
   GOTO LABEL_6TBNEW



INSERT
      into   #t2_SmartProts
   (
  --zPKId,
    zType2Code
   ,zStatus
   ,zOwnerName
   ,zObjectName
   ,zGranteeName
   ,zGrantorName
   ,zProtectTypeNum
   ,zProtectTypeName
   ,zProtectCategory
   ,zWGO
   ,zActionNum
   ,zActionName
   ,zActionCategory
   ,zColumnName
   ,zColId
   )
   SELECT
           --identity,
             '6TBNEW'
            ,0
            ,usr1.name
            ,obj1.name
            ,usr2.name
            ,usr3.name

            ,prot1.protecttype
            ,Null
            ,Null

            ,Null

            ,prot1.action
            ,Null
            ,Null

            ,'(New)'
            ,Null
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 0
      and    prot1.new_bit_on       = 1
      and
             prot1.status     IN (0,32)  --Some rows processed twice.




UPDATE
             #t1_Prots
   set
             prot1.status  = prot1.status + Power(2,6)
      from
             #t1_Prots              prot1
            ,sysobjects             obj1
            ,sysusers               usr1  --obj owner
            ,sysusers               usr2  --grantee
            ,sysusers               usr3  --grantor
      where
             prot1.id         = obj1.id
      and    prot1.objtype    = obj1.type
      and
             obj1.type       IN ('S ' ,'U ')
      and
             usr1.uid         =  obj1.uid
      and    usr2.uid         =  prot1.uid
      and    usr3.uid         =  prot1.grantor
      and
             usr1.name     LIKE  @OwnerName
      and    obj1.name     LIKE  @ObjectStatementName
      and    usr2.name     LIKE  @username
      and    usr3.name     LIKE  @grantorname
      and
             prot1.all_col_bits_on  = 0
      and    prot1.new_bit_on       = 1
      and
             prot1.status     IN (0,32)  --Some rows processed twice.




LABEL_6TBNEW:



----------------------------------------------------------------------------
--
--             MainLine:  Phase 30
--
----------------------------------------------------------------------------


IF NOT EXISTS (SELECT * From #t2_SmartProts)
   begin
   RaisError(15330,-1,-1)  --Error, no matching rows.
   Select @RetCode = 1

   GOTO LABEL_86RETURN
   end


----------------  Translations on the held data  --------------------


UPDATE
             #t2_SmartProts
      set
             zProtectTypeName = val2.name

            ,zProtectCategory =
               CASE
                  When zProtectTypeNum IN (204,205) Then 'Gr' --Grant
                  When zProtectTypeNum IN (206    ) Then 'Re' --Revoke
                  Else                   '??'
               END

            ,zWGO             =
               CASE zProtectTypeNum
                  When 204 Then 'YES'
                  When 205 Then 'no'
                  When 206 Then '.'
                  Else          '??'
                END

            ,zActionName      = val1.name

            ,zActionCategory  =
               CASE
                  When zActionNum IN ( 26, 57,193,195,196,197,224,228,235)
                                                    Then 'Ob' --Object
                  When zActionNum IN (198,203,207,222,233,236) Then 'St' --Statement
                  Else                   '??'
               END

            ,zColId        = isnull ( zColId , -123 )
      from
             #t2_SmartProts         tbz
            ,master.dbo.spt_values  val1
            ,master.dbo.spt_values  val2
      where
             val1.number   = tbz.zActionNum
      and    val1.type     = 'T'
      and
             val2.number   = tbz.zProtectTypeNum
      and    val2.type     = 'T' --T is overloaded.




-----------------  Dynamically tailor the report sorted order  ---------


--Specialized sort sequences not really needed in this app.

Select @OrderBy = '
  zActionCategory
 ,Owner            ,Object
 ,Grantee          ,Grantor
 ,zProtectCategory ,ProtectType
 ,Action
'



-----------------  Calculate dynamic display col widths  ---------------


SELECT
             @charMaxLenOwner       =
                  convert ( varchar
                           ,isnull ( max(datalength(zOwnerName)) ,5)
                          )
            ,@charMaxLenObject      =
                  convert ( varchar
                           ,isnull ( max(datalength(zObjectName)) ,6)
                          )
            ,@charMaxLenGrantee     =
                  convert ( varchar
                           ,isnull ( max(datalength(zGranteeName)) ,7)
                          )
            ,@charMaxLenGrantor     =
                  convert ( varchar
                           ,isnull ( max(datalength(zGrantorName)) ,7)
                          )
            ,@charMaxLenAction      =
                  convert ( varchar
                           ,isnull ( max(datalength(zActionName)) ,6)
                          )
            ,@charMaxLenColumnName  =
                  convert ( varchar
                           ,isnull ( max(datalength(zColumnName)) ,6)
                          )
      from
             #t2_SmartProts



--------------------  Output the report  -----------------------


EXECUTE(
'
Set nocount off


SELECT
          ''Owner''       = substring (zOwnerName   ,1 ,'
                                       + @charMaxLenOwner   + ')

         ,''Object''      = substring (zObjectName  ,1 ,'
                                       + @charMaxLenObject  + ')

         ,''Grantee''     = substring (zGranteeName ,1 ,'
                                       + @charMaxLenGrantee + ')

         ,''Grantor''     = substring (zGrantorName ,1 ,'
                                       + @charMaxLenGrantor + ')

      -- ,''WGO''         = zWGO

         ,''ProtectType'' = zProtectTypeName

         ,''Action''      = substring (zActionName ,1 ,'
                                       + @charMaxLenAction + ')

         ,''Column''      = substring (zColumnName ,1 ,'
                                       + @charMaxLenColumnName + ')
   from
          #t2_SmartProts
   order by
          ' + @OrderBy + '
         ,zColId  --Multiple  -123s  ( <0 )  possible
         ,zColumnName


Set nocount on
'
)



----------------------------------------------------------------------------
--
--             Finalization
--
----------------------------------------------------------------------------


LABEL_86RETURN:



IF (object_id('tempdb..#t1_Prots') IS NOT Null)
            DROP TABLE #t1_Prots

IF (object_id('tempdb..#t2_SmartProts') IS NOT Null)
            DROP TABLE #t2_SmartProts

Return @RetCode
go



raiserror(15339,-1,-1,'sp_helptext')
go
create procedure sp_helptext
@objname varchar(92)
as
declare @dbname varchar(30)

set nocount on

/*
**  Make sure the @objname is local to the current database.
*/
if (@objname like '%.%.%' and
        substring(@objname, 1, charindex('.', @objname) - 1) <> db_name() )
        begin
                raiserror(15250,-1,-1)
                return (1)
        end

/*
**  See if @objname exists.
*/
if (object_id(@objname) is null)
        begin
		select @dbname = db_name()
		raiserror(15009,-1,-1,@objname,@dbname)
                return (1)
        end

/*
**  Find out how many lines of text are coming back,
**  and return if there are none.
*/
if (select count(*) from syscomments where id = object_id(@objname)) = 0
        begin
                raiserror(15197,-1,-1,@objname)
                return (1)
        end

if (select count(*) from syscomments where id = object_id(@objname)
	and texttype & 4 = 0) = 0
        begin
                print 'The object''s comments have been encrypted.'
                return (0)
        end

/*
**  Else get the text.
*/
select text from syscomments where id = object_id(@objname)

return (0)
go



--Running this create AFTER create sp_helpgroup.
raiserror(15339,-1,-1,'sp_helpuser')
go
CREATE PROCEDURE sp_helpuser  --1996/03/04 13:06

    @name_in_db       varchar(30)    = NULL --User,Group,Alias
AS

Set nocount on


Declare
    @RetCode               int
   ,@_rowcount             int

Declare
    @charMaxLen_UsName     varchar(11)
   ,@charMaxLen_GrName     varchar(11)
   ,@charMaxLen_LoName     varchar(11)
   ,@charMaxLen_DbName     varchar(11)

Declare
    @Name1Type             char(2)
   ,@CMaxUsUID             smallint

--------

Select
    @RetCode               = 0
   ,@Name1Type             = Null
   ,@CMaxUsUID             = 16383


-----------------------  create holding table  --------------------


Create Table #tb1_uga
   (
    zUserName        varchar(30)        Null
   ,zGroupName       varchar(30)        Null
   ,zLoginName       varchar(30)        Null
   ,zDefDBName       varchar(30)        Null
   ,zUID             smallint           Null
   ,zSUID            smallint           Null
   )



-------------  What type of value (U,G,A) was input?  --------------


-------- NULL

IF (@name_in_db IS Null)
   begin

   Select @Name1Type = '-'


   INSERT
         into   #tb1_uga
               (
                zUserName
               ,zGroupName
               ,zLoginName
               ,zDefDBName
               ,zUID
               ,zSUID
               )
      SELECT
                   usu.name
                  ,usg.name
                  ,lo.name
                  ,lo.dbname
                  ,usu.uid
                  ,usu.suid
         from
                   sysusers               usu
                  ,sysusers               usg
                  ,master.dbo.syslogins   lo
         where
                   usu.suid   *= lo.suid
         and       usu.gid    *= usg.uid
         and
                   usg.uid     > @CMaxUsUID
         and
                   usu.uid    <= @CMaxUsUID
         and       usu.uid    >  0



   GOTO LABEL_25NAME1TYPEKNOWN

   end


-------- USER

INSERT
         into   #tb1_uga
               (
                zUserName
               ,zGroupName
               ,zLoginName
               ,zDefDBName
               ,zUID
               ,zSUID
               )
      SELECT
                   usu.name
                  ,usg.name
                  ,lo.name
                  ,lo.dbname
                  ,usu.uid
                  ,usu.suid
         from
                   sysusers               usu
                  ,sysusers               usg
                  ,master.dbo.syslogins   lo
         where
                   usu.suid   *= lo.suid
         and       usu.gid    *= usg.uid
         and
                   usg.uid     > @CMaxUsUID
         and
                   usu.uid    <= @CMaxUsUID
         and       usu.uid    >  0
         and
                   usu.name    = @name_in_db


Select @_rowcount = @@rowcount


IF (@_rowcount > 0)
   begin
   Select @Name1Type = 'US'

   GOTO LABEL_25NAME1TYPEKNOWN

   end


-------- ALIAS

INSERT
         into   #tb1_uga
               (
                zUserName
               ,zGroupName
               ,zLoginName
               ,zDefDBName
               ,zUID
               ,zSUID
               )
      SELECT
                   usu.name
                  ,usg.name
                  ,lo.name
                  ,lo.dbname
                  ,usu.uid
                  ,usu.suid
         from
                   sysusers               usu
                  ,sysusers               usg
                  ,master.dbo.syslogins   lo
                  ,sysalternates          al
         where
                   usu.suid   *= lo.suid
         and       usu.gid    *= usg.uid
         and
                   usg.uid     > @CMaxUsUID
         and
                   usu.uid    <= @CMaxUsUID
         and       usu.uid    >  0
         and
                   al.suid     = suser_id(@name_in_db)
         and       al.altsuid  = usu.suid


Select @_rowcount = @@rowcount


IF (@_rowcount > 0)
   begin
   Select @Name1Type = 'AL'

   GOTO LABEL_25NAME1TYPEKNOWN

   end


-------- GROUP

IF EXISTS
      (SELECT * FROM sysusers
         WHERE  name = @name_in_db
         AND   (uid > @CMaxUsUID  OR  uid = 0)
      )
   begin
   Select @Name1Type = 'GR'

   Execute sp_helpgroup @name_in_db

   GOTO LABEL_75FINAL  --Done

   end


-------- Error

Raiserror(15198,-1,-1 ,@name_in_db)  --Input Name is unfound
Select @RetCode = @RetCode | 1

GOTO LABEL_75FINAL



--------


LABEL_25NAME1TYPEKNOWN:



-----------------------  Printout the report  -------------------------

-------- Preparations for dynamic exec

SELECT
          @charMaxLen_UsName  = convert( varchar,
                  isnull( max( datalength( zUserName)),8))

         ,@charMaxLen_GrName  = convert( varchar,
                  isnull( max( datalength( zGroupName)),9))

         ,@charMaxLen_LoName  = convert( varchar,
                  isnull( max( datalength( zLoginName)),9))

         ,@charMaxLen_DbName  = convert( varchar,
                  isnull( max( datalength( zDefDBName)),9))
   from
          #tb1_uga


-------- Dynamic EXEC() to printout report


EXECUTE(
'
SELECT
             ''UserName''  =
                     substring(zUserName ,1,' + @charMaxLen_UsName + ')

            ,''GroupName'' =
                     substring(zGroupName,1,' + @charMaxLen_GrName + ')

            ,''LoginName'' =
                     substring(zLoginName,1,' + @charMaxLen_LoName + ')

            ,''DefDBName'' =
                     substring(zDefDBName,1,' + @charMaxLen_DbName + ')

            ,''UserID''    = convert(char(6),zUID)

            ,''SUserID''   = convert(char(7),zSUID)
      from
             #tb1_uga
      order by
             1
'
)


-----------------------  A little extra nice-to-have

IF (@Name1Type IN ('-','US'))
   begin

   IF EXISTS (SELECT * FROM #tb1_uga tb1 ,sysalternates al
                       WHERE tb1.zSUID = al.altsuid
             )
      begin

      SELECT   'LoginName' = suser_name(al.suid)
              ,'UserNameAliasedTo' = tb1.zUserName
         from  #tb1_uga tb1 ,sysalternates al
         where tb1.zSUID   = al.altsuid
         order by 1

      end
   end



-----------------------  Finalization  ----------------------


LABEL_75FINAL:


IF (object_id('tempdb..#tb1_uga') IS Null)
            Drop Table #tb1_uga

RETURN @RetCode
go



raiserror(15339,-1,-1,'sp_lock')
go
create procedure sp_lock
@spid1 int = NULL,		/* server process id to check for locks */
@spid2 int = NULL		/* other process id to check for locks */
as

/*
**  Show the locks for both parameters.
*/
if @spid1 is not NULL
begin
	select spid, locktype = name, table_id = id, page,
		dbname = substring(db_name(dbid), 1, 15)
		from syslocks, master.dbo.spt_values v
		where syslocks.type = v.number
			and v.type = 'L'
			and spid in (@spid1, @spid2)
end

/*
**  No parameters, so show all the locks.
*/
else
begin
	select spid, locktype = name, table_id = id, page,
		dbname = substring(db_name(dbid), 1, 15)
	from syslocks, master.dbo.spt_values v
	where syslocks.type = v.number
		and v.type = 'L'
	order by spid, dbname, table_id, locktype, page
end

return (0)
go



raiserror(15339,-1,-1,'sp_lock2')
go
CREATE PROCEDURE sp_lock2  --1995/11/20 07:19

    @spid1    integer = NULL
   ,@spid2    integer = NULL  --A second spid can be given also.
as
---Concerned in 6.5 that temp #tables accumulate if @@trancount>0.
---This sproc does not ins/upd/del any system data (not counting tempdb..sysobj).

Set nocount on

Declare
       @RetCode                  integer
      ,@SUID                     smallint
      ,@cu111_DBName             character varying(30)
      ,@OrigDBName               character varying(30)

Declare
       @charMaxLenLockTypeName   character varying(10)
      ,@charMaxLenTBName         character varying(10)
      ,@charMaxLenDBName         character varying(10)
      ,@charMaxLenOwner          character varying(10)

--------

Select
       @RetCode     = 0  -- 0=good ,1=bad
      ,@SUID        = suser_id()
      ,@OrigDBName  = db_name()

-------------  Capture raw lock info  ----------------

CREATE TABLE #Lock
   (
    TableId         int             Null
   ,DBName          varchar(30)     Null
   ,Page            int             Null

   ,LockTypeId      smallint        Null
   ,LockTypeName    varchar(35)     Null
   ,SPID            smallint        Null

   ,OwnerName       varchar(30)     Null
   ,TableName       varchar(30)     Null
   )


INSERT
      into   #Lock
   SELECT
             l.id
            ,db_name(dbid)
            ,l.page

            ,l.type
            ,Null
            ,l.spid

            ,'-'
            ,'-'
      from
             master.dbo.syslocks    l   (nolock)
      where
            (
             (     @spid1 IS NOT Null
              AND  l.spid  IN (@spid1 ,@spid2)
             )
            OR
             (     @spid1 IS     Null
             )
            )



UPDATE --Delayed until here to avoid reporting on self (spt_values).
               #Lock
      set
               LockTypeName    = v.name
      from
               #Lock                  tb2
              ,master.dbo.spt_values  v      (nolock)
      where
               tb2.LockTypeId  = v.number
        and    v.type          = 'L'


--------------  This phase will convert IDs to Names  --------------


EXECUTE(
'
DECLARE Cursor111_LockDB
   Insensitive
   Cursor
For
SELECT
      DISTINCT
             DBName
      from
             #Lock
'
)


OPEN Cursor111_LockDB


WHILE (111=111)   -----------  LOOP 111: thru DBNames  ------------
   begin


   FETCH
                NEXT
         from
                Cursor111_LockDB
         into
                @cu111_DBName


   IF (@@fetch_status <> 0)
      begin
      Deallocate Cursor111_LockDB
      BREAK
      end


   IF (     @SUID         = 1
      or    @cu111_DBName IN ('tempdb' ,'master',@OrigDBName)
      or    @cu111_DBName = (SELECT   dbname
                               from  master.dbo.syslogins (nolock)
                               where suid=@SUID)
      or    @SUID         = (SELECT   suid
                               from  master.dbo.sysdatabases (nolock)
                               where name=@cu111_DBName)
      )
      begin --USE will not error.  sysdb.status bit for GUEST?


      EXECUTE(
      '
      USE ' + @cu111_DBName + '

      UPDATE
                #Lock
         set
                TableName  = object_name(tb2.TableId)
               ,OwnerName  = user_name(o.uid)
         from
                #Lock      tb2
               ,sysobjects o   (nolock)
         where
                tb2.TableId   = o.id
         and    tb2.DBName    = ''' + @cu111_DBName + '''
      '
      )

      end


   end  --loop 111


-------------------  Shorten those pesky temp #tb names  ------------

UPDATE
             #Lock
      set
             TableName = substring(TableName,1
                               ,patindex('%[_][_]%',TableName)-1) + '-'
      where
             TableName LIKE '#%[_][_]%'  --Start of system assigned portion.

/***
-------------------  special case  ----------------------

UPDATE
             #Lock
      set
             TableName  =  '(work)'  --Little white lie; syslogs?
            ,OwnerName  =  '(n/a)'
      where
             TableId    =  0
      and    TableName  =  '-'
***/
----------------  Prepare dynamic column widths  ------------------

SELECT
             @charMaxLenLockTypeName =
                  convert( varchar
                          ,isnull( max( datalength(LockTypeName)) ,8)
                         )
            ,@charMaxLenTBName       =
                  convert( varchar
                          ,isnull( max( datalength(TableName)) ,6)
                         )
            ,@charMaxLenDBName       =
                  convert( varchar
                          ,isnull( max( datalength(DBName)) ,6)
                         )
            ,@charMaxLenOwner        =
                  convert( varchar
                          ,isnull( max( datalength(OwnerName)) ,5)
                         )
      from
             #Lock

----------------  Output the report  --------------------

EXECUTE(
'
SELECT
             SPID
            ,LockType  = substring(LockTypeName,1,' + @charMaxLenLockTypeName + ')
            ,TableId
            ,Page
            ,DBName    = substring(DBName,1,' + @charMaxLenDBName + ')
            ,TableName = substring(TableName,1,' + @charMaxLenTBName + ')
            ,Owner     = substring(OwnerName,1,' + @charMaxLenOwner + ')
      from
             #Lock
      order by
             SPID ,DBName ,Owner ,TableName ,TableId ,LockType ,Page
'
)

-----------------  Finalization  ------------------


LABEL_86RETURN:


EXECUTE('USE ' + @OrigDBName) --So this will work on 6.0 too.

IF (object_id('tempdb..#Lock') IS NOT Null)
            Drop table #Lock

Return @RetCode
go




raiserror(15339,-1,-1,'sp_lockinfo')
go

create procedure sp_lockinfo
as
/* ====================================================*/
/* sp_lockinfo - returns detailed lock                 */
/* information for the server                          */
/* Microsoft SQL Server 6.5 		               */
/* ====================================================*/

declare @lkdbnm varchar(32),@lkdbid smallint,@lkobjid int,@UserDBID smallint,@usrdbnm varchar(32),@User_ID smallint, @grpid smallint, @stmt varchar(255)

/* ===========================================================*/
/* build temp table with processes and their associated locks */
/* ===========================================================*/

select
	'FullName'	= case when p.spid > 9 then lo.name else 'System' end,
	'UserID'= p.uid,
	'UName'	= '                                ',
	'ProcessID'= p.spid,
	'Status'= p.status,
	'DBID'		= p.dbid,
	'DbName'= d.name,
	'Command'= p.cmd,
	'Host'= p.hostname,
	'Application'= p.program_name,
	'Blocking'	= case when l.type >= 256 then 100 else 0 end,
	'Blockedby'= p.blocked,
	'LockType'	= l.type,
	'LKObjDBID'	= l.dbid,
	'LKObjDB'	= '                                ',
	'LKObjID'	= l.id,
	'LKObj'		= case when l.id = 0 then 
(select name from master..spt_values where number = l.type and type = 'SFL')			else '                                                                                     ' end,
	'LockedPage'	= l.page,'GroupID'	= p.gid,'GName'	= '                                ','CPUUsage'	= p.cpu,
	'PhysicalIO'	= p.physical_io,'HostProcess'	= p.hostprocess
into #info from master..sysprocesses p,	master..syslocks l,master..syslogins lo (nolock),master..sysdatabases d (nolock)
where	p.spid 	= l.spid and p.suid = lo.suid and p.dbid= d.dbid

/* ======================= */
/* flag blocking processes */	
/* ======================= */

update #info set Blocking = 1 where ProcessID in (select Blockedby from #info where Blockedby > 0)

/* =============================================*/
/* get list of locked object IDs */
/* =============================================*/

exec ('declare c1 cursor for select distinct LockedDBName = d.name, LKObjID , LKObjDBID from #info, master..sysdatabases d
where LKObjDBID = d.dbid  and LKObjID > 0 FOR READ ONLY')

open c1

fetch c1 into @lkdbnm, @lkobjid, @lkdbid

while @@fetch_status >= 0
   begin
	/* set database.owner.name of locked objects in #info */
	select @stmt ='Update #info set LKObj=' + '''' + @lkdbnm + '''' + '+ ''.'' + u.name + ''.'' + o.name' + 
 	',LKObjDB=' + ''''+@lkdbnm + '''' + ' from '+@lkdbnm+'..sysobjects o,'+@lkdbnm+'..sysusers u ' +
	'where o.id='+convert(char(10),@lkobjid)+ 
	' and LKObjID=o.id' +  
	' and u.uid=o.uid and LKObjDBID=' + convert(char,@lkdbid)  
	exec(@stmt )
	/* next please */
	fetch c1 into @lkdbnm, @lkobjid, @lkdbid
   end
deallocate c1

/* =============================================*/
/* resolve UserID, GroupID for all processes    */
/* get a list of each database we need to visit */
/* =============================================*/

exec ('declare c1 cursor for select distinct DBID, DbName from #info FOR READ ONLY')

open c1

fetch c1 into  @UserDBID, @usrdbnm

while @@fetch_status >= 0
   begin
	/* set user/group in #info */
	select @stmt = 'Update #info set GName=g.name,UName=u.name from '+@usrdbnm+'..sysusers u,'+
	@usrdbnm+'..sysusers g,#info '+	'where u.uid=UserID and g.uid=GroupID and DBID=' + convert(char(10),@UserDBID)
	exec(@stmt )
	/* next please */
	fetch c1 into  @UserDBID, @usrdbnm
   end
deallocate c1

/* ====== return the #info table ===== */
SELECT	
	FullName , ProcessID, 	Status,	DName = DbName,	Command,Host, Application, Blockedby,LockType,LKObj,
	GName = GName,CPUUsage, PhysicalIO, HostProcess,UName,Blocking
FROM #info (nolock) ORDER BY LKObj, ProcessID

return(0)
GO

raiserror(15339,-1,-1,'sp_logdevice')
go
create procedure sp_logdevice  --1995/11/11 16:45
@dbname	varchar(30),		/* database name that has the syslogs */
@devname	varchar(30)	/* device name to put syslogs on */
as

declare @dbid	smallint	/* dbid of the database to be changed */
declare @dbuid	smallint	/* id of the owner of the database */
declare @logbit	int		/* this is the bit to turn on in sysusages */
declare @sum_rowcount int	/* used to determine no action needed */

select @logbit = 4		/* bit 3 is the one to turn on */
select @sum_rowcount = 0

/*
**  Verify the database name and get the @dbid and @dbuid
*/
select @dbid = dbid, @dbuid = suid
	from sysdatabases
		where name = @dbname

/*
**  If @dbname not found, say so.
*/
if @dbid is null
begin
	raiserror(15010,-1,-1,@dbname)
	return (1)
end

/*
**  See if the device exists.
*/
if not exists (select * from sysdevices where name like @devname)
	begin
		raiserror(15012,-1,-1,@devname)
		return (1)
	end

/*
**  You must be SA or the dbo to execute this sproc.
*/
if suser_id() <> 1 and suser_id() <> @dbuid
	begin
		raiserror(15199,-1,-1)
		return (1)
	end

/*
**  Now see if the @dbname uses the @devname
*/
if not exists (select * from sysusages u, sysdevices d
		where d.name = @devname
			and u.vstart between d.low and d.high
			and u.dbid = @dbid)
	begin
		raiserror(15073,-1,-1,@devname,@dbname)
		return (1)
	end

/*
**  Check to see if the user specified that the original device be used
**  as dedicated log which would necessitate mixing fragment usage on
**  the device.
*/
if exists (select * from sysusages u, sysdevices d
		where d.name = @devname
			and u.vstart between d.low and d.high
			and u.dbid = @dbid
			and lstart = 0)
	begin
	raiserror(15320,-1,-1,@dbname,@devname) --lpage 0 never log only
	return (1)
	end

/*
**  clear the bit from any database segments that aren't already log only
*/
update sysusages
	set   segmap  = segmap & ~@logbit
	from  sysusages
	where dbid    = @dbid
	and   segmap <> @logbit
	and   segmap  & @logbit > 0

select @sum_rowcount = @sum_rowcount + @@rowcount

/*
**  Now set the segments on @devname as log-only.
*/
update sysusages
	set   segmap = @logbit
	from  sysusages u, sysdevices d
	where d.name = @devname
	and   u.dbid = @dbid
	and   u.vstart between d.low and d.high
	and   u.segmap <> @logbit

select @sum_rowcount = @sum_rowcount + @@rowcount


--Any action needed?
if @sum_rowcount = 0
	begin
	raiserror(15317,-1,-1,@dbname,@devname) --okay no action
	return (0)
	end

/*
**  Now we need to activate the new segment map.
*/
dbcc dbrepair (@dbname, remap)

if @@error=0
	begin
	raiserror(15318,-1,-1,@dbname,@devname)
	end
else
	begin
	raiserror(15319,-1,-1,@dbname,@devname)
	return (1)
	end

return (0)
go



raiserror(15339,-1,-1,'sp_lookup')
go
create procedure sp_lookup
@typearg int,
@owname	varchar(30) = '%', /* owner of the desired objects (except indexes) */
@obname	varchar(30) = '%', /* name of the desired objects (including indexes) */
@indtab	varchar(30) = '%', /* table associated with the desired index */
@indown varchar(30) = '%'  /* owner of the desired index */
as
	create table #ddtab
	(
		name	varchar(30)	NOT NULL,
		owner	varchar(30)	NOT NULL,
		type	int		NOT NULL,
		indtab	varchar(30)	NOT NULL
	)

declare @table	int
declare @view	int
declare @index	int
declare @sproc	int
declare @trgr	int
declare @dflt	int
declare @rule	int
declare @dtype	int
declare @db	int
declare @report int

select @table = 1, @view = 2, @index = 4, @sproc = 8, @trgr = 16, @dflt = 32,
	@rule = 64, @dtype = 128, @db = 256, @report = 512

if (@typearg & @table = @table)
	insert into #ddtab
		select name, user_name(uid), @table, '' from dbo.sysobjects
			where name like @obname
				and user_name(uid) like @owname
				and (sysstat & 0xf = 1	/* system table */
		  		or sysstat & 0xf = 3)	/* user table */


if (@typearg & @view = @view)
	insert into #ddtab
		select name, user_name(uid), @view, '' from dbo.sysobjects
			where name like @obname
				and user_name(uid) like @owname
			  	and sysstat & 0xf = 2		/* view */

if (@typearg & @index = @index)
	insert into #ddtab
		select i.name, user_name(o.uid), @index, o.name
			from dbo.sysindexes i, dbo.sysobjects o
				where i.name like @obname
					and i.indid > 0
					and i.id = o.id
					and user_name(o.uid) like @indown
					and o.name = object_name(o.id)
					and o.name like @indtab

if (@typearg & @report = @report)
	insert into #ddtab
		select name, user_name(uid), @report, '' from dbo.sysobjects
			where name like @obname
				and user_name(uid) like @owname
				and sysstat & 0xf = 4		/* sproc */
				and userstat & -32768 = -32768	/* report */

if (@typearg & @sproc = @sproc)
begin
	/*
	**  If we also wanted reports, don't pick up reports again as sprocs.
	*/
	if (@typearg & @report = @report)
	begin
		insert into #ddtab
			select name, user_name(uid), @sproc, '' from dbo.sysobjects
			 where name like @obname
				and user_name(uid) like @owname
				and sysstat & 0xf = 4	/* stored procedure */
				and userstat & -32768 <> -32768	/* report */
	end
	else
	begin
		insert into #ddtab
			select name, user_name(uid), @sproc, '' from dbo.sysobjects
			 where name like @obname
				and user_name(uid) like @owname
				and sysstat & 0xf = 4	/* stored procedure */
	end
end

if (@typearg & @trgr = @trgr)
	insert into #ddtab
		select name, user_name(uid), @trgr, '' from dbo.sysobjects
			where name like @obname
				and user_name(uid) like @owname
			  	and sysstat & 0xf = 8	/* trigger */

if (@typearg & @dflt = @dflt)
	insert into #ddtab
		select name, user_name(uid), @dflt, '' from dbo.sysobjects
			 where name like @obname
			 	and user_name(uid) like @owname
			 	and sysstat & 0xf = 6		/* default */

if (@typearg & @rule = @rule)
	insert into #ddtab
		select name, user_name(uid), @rule, '' from dbo.sysobjects
			 where name like @obname
			 	and user_name(uid) like @owname
			 	and sysstat & 0xf = 7		/* rule */

if (@typearg & @dtype = @dtype)
	insert into #ddtab
		select name, user_name(uid), @dtype, '' from dbo.systypes
			where name like @obname
				and user_name(uid) like @owname

if (@typearg & @db = @db)
	insert into #ddtab
		select name, suser_name(suid), @db, ''
			from sysdatabases
				where (name like @obname)
					and suser_name(suid) like @owname

select * from #ddtab order by name
return (0)
go


dump transaction master with no_log
go



raiserror(15339,-1,-1,'sp_helpremotelogin')
go
create procedure sp_helpremotelogin
@remoteserver varchar(30) = NULL,	/* remote server name */
@remotename varchar(30) = NULL		/* remote login name */
as

set nocount on

/*
**  If no server given, get 'em all.
*/
if @remoteserver is null
	select @remoteserver = '%'
else
	if not exists (select *
		from sysservers s, sysremotelogins r
		where s.srvid = r.remoteserverid
			and s.srvname like @remoteserver
			and s.srvid > 0)
		begin
			if @remoteserver = '%'
				begin
					raiserror(15200,-1,-1)
					return (1)
				end

			raiserror(15201,-1,-1,@remoteserver)
			return (1)
		end

/*
**  If no remotename given, get 'em all.
*/
if @remotename is null
	begin
		select @remotename = '%'
	end
else
	begin
		if not exists (select * from sysremotelogins
			where isnull(remoteusername, '') like @remotename)

			begin
				if @remotename = '%'
					begin
						raiserror(15202,-1,-1)
						return (1)
					end

				raiserror(15203,-1,-1,@remotename)
				return (1)
			end
	end

/*
**  Check for empty results.
*/
if not exists (select *
		from sysremotelogins r, sysservers s
		where isnull(r.remoteusername, '') like @remotename
			and s.srvid = r.remoteserverid
			and s.srvname like @remoteserver)
	begin
		if ((@remoteserver = '%') and (@remotename = '%'))
			raiserror(15202,-1,-1)
		else
			raiserror(15204,-1,-1,@remotename,@remoteserver)

		return (1)
	end

/*
**  Select the information.
*/
select server = substring(s.srvname, 1, 22),
	local_user_name =
		substring(isnull(suser_name(r.suid), '** use local name **'), 1, 22),
	remote_user_name =
		substring(isnull(r.remoteusername, '** mapped locally **'), 1, 22),
	options = substring(v.name, 1, 9)
		from sysservers s, sysremotelogins r,
			master.dbo.spt_values v
	where s.srvid = r.remoteserverid
		and s.srvname like @remoteserver
		and s.srvid > 0
		and isnull(r.remoteusername, '') like @remotename
		and v.type = 'F'
		and v.number = r.status
order by server, remote_user_name

return (0)
go


raiserror(15339,-1,-1,'sp_helpsegment')
go
create procedure sp_helpsegment
@segname varchar(30) = NULL		/* segment name */
as

declare	@segbit	int	/* this is the bit version of the segment # */
declare	@segment int	/* the segment number of the segment */

set nocount on

/*
**  If no segment name given, get 'em all.
*/
if @segname is null
	begin
		select * from syssegments
		return (0)
	end

/*
**  Make sure the segment exists
*/
if not exists (select * from syssegments where name = @segname)
	begin
		raiserror(15018,-1,-1,@segname)
		return (1)
	end

/*
**  Show the syssegment entry, then the fragments and size it is on,
**  then any dependent objects in the database.
*/
select * from syssegments where name = @segname

/*
**  Set the bit position for the segment.
*/
select @segment = segment from syssegments where name = @segname

/*
**  Now set the segments on @devname sysusages.
*/
if (@segment < 31)
	select @segbit = power(2, @segment)
else
	/*
	**  Since this is segment 31, power(2, 31) will overflow
	**  since segmap is an int.  We'll grab the machine-dependent
	**  bit mask from spt_values to set the right bit.
	*/
	select @segbit = low
		from master.dbo.spt_values
		where type = 'E'
			and number = 2

select device = d.name, size = convert(varchar(20),
		round((u.size * convert(float, v.low)) / 1048576, 0)) + 'MB'
	from sysusages u, sysdevices d, master.dbo.spt_values v
	where u.segmap & @segbit = @segbit
		and d.low <= u.size + u.vstart
		and d.high >= u.size + u.vstart - 1
		and u.dbid = db_id()
		and d.status & 2 = 2
		and v.number = 1
		and v.type = 'E'

if exists (select * from sysindexes i, syssegments s
		where s.name = @segname
			and s.segment = i.segment)

	select table_name = object_name(i.id), index_name = i.name, i.indid
		from sysindexes i, syssegments s
		where s.name = @segname
			and s.segment = i.segment
		order by table_name, indid

return (0)
go


raiserror(15339,-1,-1,'sp_helpsort')
go
create procedure sp_helpsort
AS
set nocount on

declare @sortid tinyint, @charid tinyint, @status tinyint
declare @image binary(1)
declare @count int, @end_flag int

declare @string varchar(66)
create table #helpsort3 (string varchar(66)	NOT NULL)

/*
** Get the sortorder ID, character set ID, and status
*/
select @sortid = id, @charid = csid, @image = convert(binary(1), definition)
    from syscharsets, syscurconfigs
    where id = value and config = 1123

/*
** Get the name and description of the character set and sort order
*/
if (@sortid is null)
 BEGIN
    select @sortid = 0, @charid = 0, @status = 0
    insert #helpsort3 values ('Character Set = 0, ascii_8')
    insert #helpsort3 values ('    8-bit ASCII Character Set - System Default')
    insert #helpsort3 values ('Sort Order = 0, bin_ascii_8')
    insert #helpsort3 values ('    Binary Ordering - System Default')
 END
else
 BEGIN
    select @status = convert(tinyint, @image)

    select @string = 'Character Set = ' + convert(varchar(4), id) + ', ' + name
	    from syscharsets
	    where id = @charid and type = 1001

    insert into #helpsort3 values (@string)

    select @count = 1
    select @end_flag = 1

    while (@end_flag <> 0)
    begin
	    select @string = substring(description, @count, 62)
		    from syscharsets
		    where id = @charid and type = 1001
	    select @end_flag = isnull(ascii(@string), 0)

	    if (@end_flag <> 0)
	    begin
		    select @string = '    ' + @string
		    insert #helpsort3 values (@string)
	    end
	    select @count = @count + 62
    end

    select @string = 'Sort Order = ' + convert(varchar(4), id) + ', ' + name
	    from syscharsets
	    where id = @sortid and type = 2001

    insert into #helpsort3 values (@string)

    select @count = 1
    select @end_flag = 1

    while (@end_flag <> 0)
    begin
	    select @string = substring(description, @count, 62)
		    from syscharsets
		    where id = @sortid and type = 2001
	    select @end_flag = isnull(ascii(@string), 0)

	    if (@end_flag <> 0)
	    begin
		    select @string = '    ' + @string
		    insert #helpsort3 values (@string)
	    end

	    select @count = @count + 62
    end
END

select 'Sort Order Description' = string from #helpsort3

/*
** Build the sorted list of characters for this sort order.
** If it's not stored in spt_values yet, then put the results in there.
*/
if not exists (select * from master.dbo.spt_values
		where type = 'Z'
			and high = @sortid)
BEGIN

    create table #helpsort1 (char_val char(1) NOT NULL)



    if @charid = 0       /*    ascii_8 has valid values from 32 to 126 */
	begin
    		select @count = 32
    		while @count <= 126
    		begin
    			insert #helpsort1 (char_val)
    				values (char(@count))
    			select @count = @count + 1
    		end
	end

    if @charid = 1  	/*     iso_1 has values from 32 to 126, 160 to 255 */
	begin
    		select @count = 32
    		while @count <= 126
    		begin
    			insert #helpsort1 (char_val)
    				values (char(@count))
    			select @count = @count + 1
    		end

        	select @count = 160
        	while @count <= 255
        	begin
    	   		insert #helpsort1 (char_val)
    		    		values (char(@count))
    	    		select @count = @count + 1
        	end
	end

    if @charid = 2      /*     cp850 has valid values from 0 to 255 */
	begin
    		select @count = 32
    		while @count <= 255
    		begin
    			insert #helpsort1 (char_val)
    				values (char(@count))
    			select @count = @count + 1
    		end
	end

    if @charid = 3      /*     cp437 has valid values from 0 to 255 */
	begin
    		select @count =32
    		while @count <= 255
    		begin
    			insert #helpsort1 (char_val)
    				values (char(@count))
    			select @count = @count + 1
    		end
	end

    if @charid = 4
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (127, 128, 129, 131, 136, 144, 152)

        end

    if @charid = 5
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (127, 136, 152)

        end

    if @charid = 6
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (128, 129, 136, 138, 140, 141, 142, 143, 144, 152, 154, 156, 157, 158, 159)

        end

    if @charid = 7
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (128, 129, 141, 142, 143, 144, 157, 158)

        end

    if @charid = 8
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (128, 129, 138, 140, 141, 142, 143, 144, 154, 156, 157, 158, 159)

        end

    if @charid = 9
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (128, 138, 143, 152, 154, 159)

        end

    if @charid = 10
        begin
                select @count =32
                while @count <= 255
                begin
                        insert #helpsort1 (char_val)
                                values (char(@count))
                        select @count = @count + 1
                end

                /* Remove unwanted values */

                delete #helpsort1 where ascii(char_val) in (128, 129, 131, 136, 138, 140, 143, 144, 156, 159)

        end


    if @charid > 10     /* User Character Set Not recognised by sp_helpsort */
	begin
   		select 'Unknown Character Set : ' + name from syscharsets
	    			where id = @sortid and type = 2001
		return (0)
	end

    select (char_val) into #helpsort2
    	from #helpsort1
    	order by char_val

    declare @char char(1)
    declare @char_str varchar(20)
    declare @incr int
    declare @seq_num int
    declare @rel char(1)
    declare @old_char char(1)

    select @char = char(0), @seq_num = 0, @count = 0, @incr = 8, @end_flag = 1
    select @rel = ' ', @old_char = NULL

    set rowcount 1

    while @end_flag <> 0
    begin
        select @char_str = ''

		/* If PST_NOTUNIQ is set, then possibly caseless */
		if (@status & 8 = 8)
            while (@count < @incr  and  @end_flag <> 0)
            begin
                select @char = char_val
    	            from #helpsort2
    	            where char_val >= @char
                select @end_flag = @@rowcount

		if (@end_flag <> 0)
		begin
		    if (@char = @old_char)
			select @rel = '='
		    else
			select @rel = ' '

		    select @old_char = @char
		    select @char_str = @char_str + @rel + @char
		    delete from #helpsort2 where ascii(@char) = ascii(char_val)

		    select @count = @count + 1
		end
	end
	else
		while (@count < @incr  and  @end_flag <> 0)
			begin
				select @char = char_val
					from #helpsort2
					where char_val > @char
				select @end_flag = @@rowcount
				if (@end_flag <> 0)
					begin
						select @char_str = @char_str + @rel + @char
						delete from #helpsort2 where ascii(@char) = ascii(char_val)
						select @count = @count + 1
					end
			end

        select @incr = @incr + 8, @seq_num = @seq_num + 1
        insert master.dbo.spt_values (name, number, type, low, high)
		values (@char_str, @seq_num, 'Z', @charid, @sortid)
    end

    set rowcount 0

END

/*
** Display the sorted list of characters.
*/
select @count = 1
select @end_flag = 1
select @incr = 5

truncate table #helpsort3

while @end_flag <> 0
BEGIN
	select @string = ''

	while @count < @incr
	begin
		select @string = @string + substring(name, 2, 19)
			from master.dbo.spt_values
			where type = 'Z'
				and number = @count
				and high = @sortid
		select @end_flag = @@rowcount
		select @count = @count + 1
	end

	select @incr = @incr + 4

	insert into #helpsort3 values (@string)
END

select 'Characters, in Order' = string
	from #helpsort3
set nocount off
return(0)
go


raiserror(15339,-1,-1,'sp_helpstartup')
go
create procedure sp_helpstartup
as

/*
**  Only the SA can do this.
*/
if suser_id() <> 1
begin
	raiserror(15003,-1,-1)
	return (1)
end

select 'Startup stored procedures:' = name from sysobjects
	where category & 16 = 16 order by name

return(0)
go


raiserror(15339,-1,-1,'sp_helpserver')
go
create procedure sp_helpserver  --1996/01/26 20:20
@server varchar(30) = NULL,		/* server name */
@optname varchar(20) = NULL,
@show_topology varchar(1) = NULL
as

declare @optbit int

set nocount on

/*
**  If no server name given, get 'em all.
*/
if @server = null
	select @server = '%'

/*
**  Does the server exist?
*/
if not exists (select *
		from sysservers
			where srvname like @server
				or srvnetname like @server)
	begin
		if @server = '%'
			raiserror(15205,-1,-1)
		else
			raiserror(15015,-1,-1,@server)

		return (1)
	end

/*
**  Display server information.
**  First put it into a temp table so we can blot inappropriate status
**  for the local server.  It's ugly but I couldn't think of another way.
*/
declare @cursrvid smallint	/* the one we're currently working on */
declare @srvdesc varchar(11)	/* the total description for the server */
declare @bitdesc varchar(30)    /* the bit description for the server  */
create table #spt_server
(
	name	varchar(30)	NOT NULL,
	network	varchar(30)	NOT NULL,
	status	varchar(11)	NOT NULL,
	id	smallint        NOT NULL,
	topx	int		NULL,
	topy	int		NULL
)

/*
**  Allow option specification.
*/
select @optbit = -1     /* 0xffffffff */
if @optname is not null
	begin
		select @optbit = null
		select @optbit = number
			from master.dbo.spt_values
			where type = 'A'
				and name = @optname
		if @optbit is null or @optbit <= 0
			begin
				raiserror(15206,-1,-1,@optname)
				return(1)
			end
	end

/*
**  Set @cursrvid to the first or only srvid.
**  Mask out 'rpc' for the local server.
*/
if @server = '%'
	select @cursrvid = min(srvid) from sysservers
		where (@optname is null or srvstatus & @optbit <> 0)
		and not (@optbit = 1 and srvid = 0)
else
	select @cursrvid = srvid from sysservers
		where srvname =	@server
		and (@optname is null or srvstatus & @optbit <> 0)
		and not (@optbit = 1 and srvid = 0)

while @cursrvid <> NULL
begin
	/*
	**  Initialize @srvdesc.
	*/
	select @srvdesc = ''

	/*
	** Check rpc bit (1)
	*/
	if @cursrvid <> 0
		begin
			select @bitdesc = null
			select @bitdesc = v.name
				from master.dbo.spt_values v, sysservers s
				where s.srvid = @cursrvid
					and v.type = 'A'
					and v.name = 'rpc'
					and s.srvstatus & v.number = 1

			if @bitdesc <> null
				begin
					if @srvdesc <> ''
						select @srvdesc = @srvdesc + ',' +  @bitdesc
					else
						select @srvdesc = @bitdesc
				end
         end

	/*
	** Check publisher bit (2)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'pub'
			and s.srvstatus & v.number = 2
	
	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	/*
	** Check subscriber bit (4)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'sub'
			and s.srvstatus & v.number = 4

	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	/*
	** Check distribution bit (8)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'dist'
			and s.srvstatus & v.number = 8

	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	/*
	** Check distribution publisher bit (16)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'dpub'
			and s.srvstatus & v.number = 16

	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	/*
	** Check ODBC DSN bit (32)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'dsn'
			and s.srvstatus & v.number = 32

	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	/*
	** Check Fallback bit (64)
	*/
	select @bitdesc = null
	select @bitdesc = v.name
		from master.dbo.spt_values v, sysservers s
		where s.srvid = @cursrvid
			and v.type = 'A'
			and v.name = 'fallback'
			and s.srvstatus & v.number = 64

	if @bitdesc <> null
		begin
			if @srvdesc <> ''
				select @srvdesc = @srvdesc + ',' +  @bitdesc
			else
				select @srvdesc = @bitdesc
		end

	insert into #spt_server
		select s.srvname, s.srvnetname, @srvdesc, id = s.srvid,
			s.topologyx,s.topologyy
		from sysservers s
			where s.srvid = @cursrvid

	/*
	** Quit if server specified or increment to next server.
	*/
	if @server = '%'
		select @cursrvid = min(srvid) from sysservers
			where srvid > @cursrvid
			and (@optname is null or srvstatus & @optbit <> 0)
			and not (@optbit = 1 and srvid = 0)
	else
		select @cursrvid = NULL
end

if lower(@show_topology) <> 't' or @show_topology is null
	select name, network_name = substring(network, 1, 28),
		status = status, id = convert(char(4), id)
	from #spt_server
	order by name
else
	select name, network_name = substring(network, 1, 28),
		status = status, id = convert(char(4), id),
		topx,topy
	from #spt_server
	order by name

return(0)
go


raiserror(15339,-1,-1,'sp_makestartup')
go
create procedure sp_makestartup
@procname varchar(30) = null
as
declare @objid	int
declare @dbname varchar(30)

/*
**	Check to see if a proc. name was specified.
*/
if @procname is null
	begin
		raiserror(15207,-1,-1)
		return (1)
	end

/*
**  Only the SA can do this.
*/
if suser_id() <> 1
begin
	raiserror(15003,-1,-1)
	return (1)
end

/*
**  Make sure the @procname is in the master database.
*/
if @procname like '%.%.%' and	-- Explicit db name supplied
	substring(@procname, 1, charindex('.', @procname) - 1) <> 'master'
	begin
		raiserror(15272,-1,-1,@procname)
		return (1)
	end
else	-- No explicit name supplied so we need to be in the 'master' db
	if db_name() <> 'master'
		begin
			select @dbname = db_name()
			raiserror(15273,-1,-1,@procname,@dbname)
			return(1)
		end
/*
**  Make sure the procedure exists and get its id so we can use
**	a simpler where clause.
*/
select @objid = id from master..sysobjects
	where sysstat & 0xf = 4
	and name = @procname

if @objid is null
	begin
		raiserror(15020,-1,-1,@procname)
		return (1)
	end

/*
**  Make sure that the procedure is owned by the SA.  We're looking
**	in master so if the uid indicates dbo it has to be the SA.
*/
if (select uid from master..sysobjects
		where id = @objid) <> 1
	begin
		raiserror(15208,-1,-1)
		return (1)
	end

/*
**  Check to see that the procedure doesn't expect any parameters.
*/
if exists (select * from master..syscolumns
			where id = @objid)
	begin
		raiserror(15209,-1,-1)
		return (1)
	end

/*
**	If we made it to here, make it autoexec.
*/
if (select category & 16 from master..sysobjects where id = @objid) <> 16
	begin
		update master..sysobjects set category = category | 16
			where id = @objid
		print 'Procedure has been marked as ''startup''.'
	end
else
	print 'Procedure is already designated as ''startup''.'

return (0)
go


raiserror(15339,-1,-1,'sp_markreport')
go
create procedure sp_markreport
@reportname varchar(92)		/* proc name we want to mark as report */
as

/*
**  Make sure the @reportname is local to the current database.
*/
if @reportname like '%.%.%' and
	substring(@reportname, 1, charindex('.', @reportname) - 1) <> db_name()
	begin
		raiserror(15083,-1,-1)
		return (1)	
	end

/*
**  Make sure that it actually exists as a sproc.
*/
if not exists (select * from sysobjects
		where id = object_id(@reportname)
		and sysstat & 0xf = 4	/* stored procedure */
		and uid = user_id())
	begin
		raiserror(15021,-1,-1,@reportname)
		return (1)
	end

update sysobjects
	set userstat = userstat | -32768	/* high bit means report */
		from sysobjects
			where id = object_id(@reportname)
			and sysstat & 0xf = 4		/* stored procedure */
			and uid = user_id()

return (0)
go


raiserror(15339,-1,-1,'sp_monitor')
go
create procedure sp_monitor
as

/*
**  Declare variables to be used to hold current monitor values.
*/
declare @now 		datetime
declare @cpu_busy 	int
declare @io_busy	int
declare @idle		int
declare @pack_received	int
declare @pack_sent	int
declare @pack_errors	int
declare @connections	int
declare @total_read	int
declare @total_write	int
declare @total_errors	int

declare @oldcpu_busy 	int	/* used to see if DataServer has been rebooted */
declare @interval	int
declare @mspertick	int	/* milliseconds per tick */

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_monitor')
		return (1)
	end

/*
**  Set @mspertick.  This is just used to make the numbers easier to handle
**  and avoid overflow.
*/
select @mspertick = convert(int, @@timeticks / 1000.0)

/*
**  Get current monitor values.
*/
select
	@now = getdate(),
	@cpu_busy = @@cpu_busy,
	@io_busy = @@io_busy,
	@idle = @@idle,
	@pack_received = @@pack_received,
	@pack_sent = @@pack_sent,
	@connections = @@connections,
	@pack_errors = @@packet_errors,
	@total_read = @@total_read,
	@total_write = @@total_write,
	@total_errors = @@total_errors

/*
**  Check to see if DataServer has been rebooted.  If it has then the
**  value of @@cpu_busy will be less than the value of spt_monitor.cpu_busy.
**  If it has update spt_monitor.
*/
select @oldcpu_busy = cpu_busy
	from spt_monitor
if @oldcpu_busy > @cpu_busy
begin
	update spt_monitor
		set
			lastrun = @now,
			cpu_busy = @cpu_busy,
			io_busy = @io_busy,
			idle = @idle,
			pack_received = @pack_received,
			pack_sent = @pack_sent,
			connections = @connections,
			pack_errors = @pack_errors,
			total_read = @total_read,
			total_write = @total_write,
			total_errors = @total_errors
end

/*
**  Now print out old and new monitor values.
*/
set nocount on
select @interval = datediff(ss, lastrun, @now)
	from spt_monitor
/* To prevent a divide by zero error when run for the first
** time after boot up
*/
if @interval = 0
	select @interval = 1
select last_run = lastrun, current_run = @now, seconds = @interval
	from spt_monitor

select
	cpu_busy = substring(convert(varchar(11),
		convert(int, ((@cpu_busy * @mspertick) / 1000)))
		+ '('
		+ convert(varchar(11), convert(int, (((@cpu_busy - cpu_busy)
		* @mspertick) / 1000)))
		+ ')'
		+ '-'
		+ convert(varchar(11), convert(int, ((((@cpu_busy - cpu_busy)
		* @mspertick) / 1000) * 100) / @interval))
		+ '%',
		1, 25),
	io_busy = substring(convert(varchar(11),
		convert(int, ((@io_busy * @mspertick) / 1000)))
		+ '('
		+ convert(varchar(11), convert(int, (((@io_busy - io_busy)
		* @mspertick) / 1000)))
		+ ')'
		+ '-'
		+ convert(varchar(11), convert(int, ((((@io_busy - io_busy)
		* @mspertick) / 1000) * 100) / @interval))
		+ '%',
		1, 25),
	idle = substring(convert(varchar(11),
		convert(int, ((@idle * @mspertick) / 1000)))
		+ '('
		+ convert(varchar(11), convert(int, (((@idle - idle)
		* @mspertick) / 1000)))
		+ ')'
		+ '-'
		+ convert(varchar(11), convert(int, ((((@idle - idle)
		* @mspertick) / 1000) * 100) / @interval))
		+ '%',
		1, 25)
from spt_monitor

select
	packets_received = substring(convert(varchar(11), @pack_received) + '(' +
		convert(varchar(11), @pack_received - pack_received) + ')', 1, 25),
	packets_sent = substring(convert(varchar(11), @pack_sent) + '(' +
		convert(varchar(11), @pack_sent - pack_sent) + ')', 1, 25),
	packet_errors = substring(convert(varchar(11), @pack_errors) + '(' +
		convert(varchar(11), @pack_errors - pack_errors) + ')', 1, 25)
from spt_monitor

select
	total_read = substring(convert(varchar(11), @total_read) + '(' +
		convert(varchar(11), @total_read - total_read) + ')', 1, 19),
	total_write = substring(convert(varchar(11), @total_write) + '(' +
		convert(varchar(11), @total_write - total_write) + ')', 1, 19),
	total_errors = substring(convert(varchar(11), @total_errors) + '(' +
		convert(varchar(11), @total_errors - total_errors) + ')', 1, 19),
	connections = substring(convert(varchar(11), @connections) + '(' +
		convert(varchar(11), @connections - connections) + ')', 1, 18)
from spt_monitor

/*
**  Now update spt_monitor
*/
update spt_monitor
	set
		lastrun = @now,
		cpu_busy = @cpu_busy,
		io_busy = @io_busy,
		idle = @idle,
		pack_received = @pack_received,
		pack_sent = @pack_sent,
		connections = @connections,
		pack_errors = @pack_errors,
		total_read = @total_read,
		total_write = @total_write,
		total_errors = @total_errors

return (0)
go


raiserror(15339,-1,-1,'sp_password')
go
create procedure sp_password  --1995/12/22 10:43 #12799
@old varchar(30) = NULL,	/* the old (current) password */
@new varchar(30),		/* the new password */
@loginame varchar(30) = NULL	/* user to change password on */
as

declare @suid int		/* suid of person to change pw on */

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_password')
		return (1)
	end

/*
**  If the system administrator (sa) is running this command, the sa can
**  change anyone's password and doesn't have to know the old password.
**  We have this case is suser_id() = 1 and @loginame is NOT NULL.
**  In this case, we'll fill in the old password and set the suid.
*/
if suser_id() <> 1 and @loginame IS NOT NULL
	begin
		/*
		**  Only the sa can use the @loginame.
		*/
		raiserror(15210,-1,-1)
		return (1)
	end

/*
**  Does the SA want to change someone's password?
*/
if suser_id() = 1 and @loginame IS NOT NULL
begin
	/*  Check to see if the user exists. */

	select @suid = suid from syslogins where name = @loginame

	if @suid is null
		begin
			raiserror(15007,-1,-1,@loginame)
			return (1)
		end

	/*
	**  Get the old password for the user.  If @old not given, don't
	**  bother checking against the old password.
	*/
	if @old IS NOT NULL
	begin
		/*
		** Reinitialize @suid since previous assignment
		** set it.
		*/
		select @suid = NULL

		select @suid = suid
			from	 syslogins
			where	 name     = @loginame
			and	(password = @old or
				 pwdcompare(@old, password) = 1
				)

		if @suid is null
			begin
				raiserror(15211,-1,-1)
				return (1)
			end
	end
end

/*
**  This is just the normal case when someone wants to change their own
**  password.  Set the @suid.
*/
else
	if @loginame is null
		select @suid = suid
			from syslogins
			where (password = @old or pwdcompare(@old, password) = 1)
				and suid = suser_id()


if @suid is null
	begin
		raiserror(15211,-1,-1)
		return (1)
	end

/*
**  This is the final case.  The sa is running the command to change
**  someone else's password and is supplying the old password.  Confirm
**  that the old password is correct.
*/
if suser_id() = 1
	begin
		select @suid = suid
			from syslogins
			where (password = @old or pwdcompare(@old, password) = 1)
				and suid = suser_id(@loginame)

		if @suid is null				      	
			begin
				raiserror(15211,-1,-1)
				return (1)
			end
	end

/*
**  If @suid still hasn't been set then the user running the procedure
**  doesn't have the right current password.
*/
if @suid is null
	begin
		raiserror(15211,-1,-1)
		return (1)
	end

/*
**  Everything is consistent so change the password and set encrypt flag.
*/
update syslogins set password = pwdencrypt(@new),status = status | 8
	where suid = @suid

print 'Password changed.'

return (0)
go


raiserror(15339,-1,-1,'sp_placeobject')
go
create procedure sp_placeobject
@segname	varchar(30),	/* segment name */
@objname	varchar(62)	/* object name */
as

declare	@msg		char(100)
declare @objid		int
declare @tabname	varchar(30)
declare @indexname	varchar(30)
declare	@indexid	smallint
declare	@segment	smallint
declare @dbname		varchar(30)

/*
**  Check to see if the segment exists.
*/
select @segment = segment from syssegments where name = @segname
if @segment is null
	begin
		raiserror(15018,-1,-1,@segname)
		return (1)
	end

select @dbname = db_name()

/*
**  Are we dealing with a table or its index?
*/
if @objname like '%.%'
	begin

		/*
		**  Get the table name out.
		*/
		select @tabname = substring(@objname, 1, charindex('.', @objname) - 1)
		select @indexname = substring(@objname, charindex('.', @objname) + 1, 61)
	end
else
		select @tabname = @objname, @indexname = null

/*
**  Can't use placeobject to move syslogs.
*/
if (object_id(@tabname) = 8)
	begin
		raiserror(15212,-1,-1)
		return (1)
	end

/*
**  Can't move system tables.
*/
if object_id(@tabname) < 100
	begin
		raiserror(15213,-1,-1)
		return (1)
	end

/*
**  If the user is not the dbo or the SA, make sure he/she owns it.
*/
if suser_id() <> 1 and user_id() <> 1
	begin
		if not exists (select *
			from sysobjects
				where name = @tabname
					and uid = user_id())
			begin
				raiserror(15214,-1,-1,@tabname)
				return (1)
			end
	end
else
	begin
		/*
		**  If dbo or SA, make sure the table exists.
		*/
		if not exists (select * from sysobjects where name = @tabname)
			begin
				raiserror(15009,-1,-1,@tabname,@dbname)
				return (1)
			end
	end

/*
**  If we are dealing with an index, make sure it exists.
*/
if @indexname IS NOT NULL and not exists (select *
					from sysindexes
						where id = object_id(@tabname)
							and name = @indexname)
begin
	raiserror(15215,-1,-1,@indexname,@tabname)
	return (1)

end

/*
**  Everything's ok so change the segment for the object.
*/
if @indexname is null
begin
	select @indexid = indid
		from sysindexes
			where id = object_id(@tabname)
				and indid < 2
end
else
begin
	select @indexid = indid
		from sysindexes
			where id = object_id(@tabname)
				and name = @indexname
end

update sysindexes
set segment = @segment
	from sysindexes
		where id = object_id(@tabname)
			and indid = @indexid

dbcc dbrepair (@dbname, remap)
select @msg = '''' + @objname + ''' is now on segment ''' + @segname + '''.'
print @msg

return (0)
go


raiserror(15339,-1,-1,'sp_primarykey')
go
create procedure sp_primarykey
@tabname  varchar(92),			/* table name that has the key */
@col1     varchar(30), 			/* columns that make up the key */
@col2     varchar(30) = NULL,
@col3     varchar(30) = NULL,
@col4     varchar(30) = NULL,
@col5     varchar(30) = NULL,
@col6     varchar(30) = NULL,
@col7     varchar(30) = NULL,
@col8     varchar(30) = NULL
as

declare @objid int			/* object id of the table */
declare @uid smallint			/* owner id of the object */
declare @cnt smallint			/* howmany columns in key */
declare @key1 tinyint			/* colids of the columns in the key */
declare @key2 tinyint
declare @key3 tinyint
declare @key4 tinyint
declare @key5 tinyint
declare @key6 tinyint
declare @key7 tinyint
declare @key8 tinyint
declare @dbname	varchar(30)

/*
**  Check to see that the tabname is local.
*/
if @tabname like '%.%.%' and
	substring(@tabname, 1, charindex('.', @tabname) - 1) <> db_name()
	begin
		raiserror(15078,-1,-1)
		return (1)
	end

/*
**  See if we can find the object.  It must be a system table, user table,
**  or view.  The low 4 bits of sysobjects.sysstat indicate what the
**  object type is -- it's more reliable than using sysobjects.type which
**  could change.
*/
select @objid = id, @uid = uid
	from sysobjects
		where id = object_id(@tabname)
			and (sysstat & 0xf = 1		/* system table */
				or sysstat & 0xf = 2	/* view */
				or sysstat & 0xf = 3)	/* user table */

if @objid is NULL
	begin
		select @dbname=db_name()
		raiserror(15009,-1,-1,@tabname,@dbname)
		return (1)
	end

/*
**  Check to see that object owner is adding the key.
*/
if @uid <> user_id()
	begin
		raiserror(15172,-1,-1)
		return (1)
	end

/*
**  See if the primary key exists already.  Syskeys.type = 1 indicates
**  a primary key.
*/
if exists (select * from syskeys where id = @objid and type = 1)
	begin
		raiserror(15173,-1,-1)
		return (1)
	end

/*
**  Now check out each column argument to verify its existence.
*/
select @cnt = 1, @key1 = colid
	from syscolumns
		where name = @col1
			and id = @objid
if @key1 is NULL
	begin
		raiserror(15154,-1,-1)
		return (1)
	end

if @col2 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key2 = colid
			from syscolumns
			where name = @col2
			and id = @objid

		if @key2 is NULL
			begin
				raiserror(15155,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col3 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key3 = colid
			from syscolumns
			where name = @col3
			and id = @objid

		if @key3 is NULL
			begin
				raiserror(15156,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col4 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key4 = colid
			from syscolumns
			where name = @col4
			and id = @objid

		if @key4 is NULL
			begin
				raiserror(15157,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col5 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key5 = colid
			from syscolumns
			where name = @col5
			and id = @objid

		if @key5 is NULL
			begin
				raiserror(15158,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col6 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key6 = colid
			from syscolumns
			where name = @col6
			and id = @objid

		if @key6 is NULL
			begin
				raiserror(15159,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col7 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key7 = colid
			from syscolumns
			where name = @col7
			and id = @objid

		if @key7 is NULL
			begin
				raiserror(15160,-1,-1)
				return (1)
			end
	end
else goto doinsert

if @col8 IS NOT NULL
	begin
		select @cnt = @cnt + 1, @key8 = colid
			from syscolumns
			where name = @col8
			and id = @objid

		if @key8 is NULL
			begin
				raiserror(15161,-1,-1)
				return (1)
			end
	end

/*
**  Type 1 is a primary key, 2 is a foreignkey, and 3 is a commonjoin.
*/
doinsert:

insert into syskeys
	(id, type, depid, keycnt, size, key1, key2, key3, key4, key5,
		key6, key7, key8)
values (@objid, 1, NULL, @cnt, 0, @key1, @key2, @key3, @key4, @key5,
		@key6, @key7, @key8)

print 'New primary key added.'
return (0)
go


raiserror(15339,-1,-1,'sp_processmail')
go
create procedure sp_processmail @subject varchar(255)=NULL,
				@filetype varchar(3)='txt',
				@separator varchar(3)='tab',
				@set_user varchar(30)='guest',
				@dbuse varchar(30)='master'
as

declare @status int
declare @msg_id varchar(64)
declare @originator varchar(255)
declare @cc_list varchar(255)
declare @msgsubject varchar(255)
declare @query varchar(255)
declare @messages int
declare @mapifailure int
declare @resultmsg varchar(80)
declare @filename varchar(12)

select @messages=0
select @mapifailure=0

if @separator='tab' select @separator=CHAR(9)

while (1=1)
  begin
    exec @status = master..xp_findnextmsg
		@msg_id=@msg_id output,
		@unread_only='true'

    if @status <> 0
	begin
		select @mapifailure=1
		break
	end

    if @msg_id is null break

    exec @status = master..xp_readmail
		@msg_id=@msg_id,
		@originator=@originator output,
		@cc_list=@cc_list output,
		@subject=@msgsubject output,
		@message=@query output,
		@peek='true',
		@suppress_attach='true'

    if @status <> 0
	begin
		select @mapifailure=1
		break
	end

    if ((@subject IS NULL) OR (@subject=@msgsubject))
    begin
	/* generate random filename */
	select @filename='SQL' + convert(varchar,ROUND(RAND()*100000,0)) + '.' + @filetype

	exec @status = master..xp_sendmail
			@recipients=@originator,
			@copy_recipients=@cc_list,
			@message=@query,
			@query=@query,
			@subject='Query Results',
			@separator=@separator,
			@width=256,
			@attachments=@filename,
			@attach_results='true',
			@no_output='false',
			@echo_error='true',
			@set_user=@set_user,
			@dbuse=@dbuse

	if @status <> 0
		begin
			select @mapifailure=1
			break		
		end
	
	select @messages=@messages+1

	exec master..xp_deletemail @msg_id

    end /* end of xp_sendmail block */
  end  /* end of xp_findnextmsg loop */

  /* finished examining the contents of inbox;  now send results */
  if @mapifailure=0
      	begin
		raiserror(15079,-1,-1,@messages)
		return(1)
	end
  else	
	return(0)
go


raiserror(15339,-1,-1,'sp_recompile')
go
create procedure sp_recompile
@objname	varchar(92)
as
declare @id	int
declare @type	smallint
declare @uid	smallint
declare @errmsg	varchar(250)
declare @dbname varchar(30)

if @objname like '%.%.%'
	begin
		select @dbname=substring(@objname, 1, charindex('.', @objname) - 1)

		if @dbname <> db_name()
			begin
				raiserror(15250,-1,-1)
				return(1)
			end
	end
else
	select @dbname=db_name()

select @id = id, @type = sysstat & 0xf, @uid = uid
from sysobjects
where id = object_id(@objname)

if @id is null
	begin
		raiserror(15009,-1,-1,@objname,@dbname)
		return(1)
	end

if @type = 1
	begin
		raiserror(15217,-1,-1,@objname)
		return(1)
	end
if @type <> 3
	begin
		raiserror(15218,-1,-1,@objname)
		return(1)
end

if user_id() <> 1 and @uid <> user_id()
	begin
		raiserror(15219,-1,-1,@objname)
		return(1)
	end

set nocount on

update sysobjects set schema_ver = schema_ver + 1 where id = @id

select @errmsg = 'Each stored procedure and trigger that uses table ' + @objname
print @errmsg
print 'will be recompiled the next time it is executed.'
go


raiserror(15339,-1,-1,'sp_remoteoption')
go
create procedure sp_remoteoption
@remoteserver varchar(30) = NULL,	/* server name to change */
@loginame varchar(30) = NULL,		/* user's remote name */
@remotename varchar(30) = NULL,		/* user's local user name */
@optname varchar(20) = NULL,		/* option name to turn on/off */
@optvalue varchar(10) = NULL		/* true or false */
as

declare @statvalue smallint		/* number of option */
declare @optcount int			/* number of options like @optname */
declare	@msg	varchar(100)
declare @suid	smallint

/*
**  If no @server given, just list the possible remote login options.
**  Only certain status bits may be set or cleared.
**	   settable                        not settable
**     ------------------------------  --------------------------
**     trusted (1)
*/
if @remoteserver is null
begin
	print 'Settable remote login options.'
	select remotelogin_option = name
		from master.dbo.spt_values
		where type = 'F'
			and number in (1, 1)
			and number > 0
		order by name
	return (0)
end

/*
**  If @loginame is NULL then we want to set @suid = -1. Otherwise get
**  it real value.
*/
if @loginame is null
	select @suid = -1
else select @suid = suser_id(@loginame)

/*
**  Verify the server name, local, and remote names.
*/
if not exists (select *
		from sysremotelogins r, sysservers s
			where r.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and r.remoteusername = @remotename
				and r.suid = @suid)
	begin

		raiserror(15185,-1,-1,@remotename,@loginame,@remoteserver)
		return (1)
	end

/*
**  Check remaining parameters.
*/
if @optname is NULL or lower(@optvalue) not in ('true', 'false') or @optvalue = null
	begin
		raiserror(15220,-1,-1)
		return (1)
	end

/*
**  Use @optname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @optcount = count(*)
	from master.dbo.spt_values
	where name like '%' + @optname + '%'
		and type = 'F'
		and number in (1, 1)
		and number > 0

/*
**  If no option, show the user what the options are.
*/
if @optcount = 0
	begin
		raiserror(15221,-1,-1)
		return (1)
	end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
	begin
		raiserror(15222,-1,-1,@optname)
		print ''

		select duplicate_option = name
		from master.dbo.spt_values
		where name like '%' + @optname + '%'
			and type = 'F'
			and number in (1, 1)
			and number > 0

		return (1)
	end

/*
**  Only the SA or the dbo of @dbnbame can execute the update part
**  of this procedure so check.  Also the sproc must be executed in the master
**  database.
*/
if suser_id() <> 1
begin
	print 'Only the System Administrator (SA) may set remote login options.'
	return (1)
end

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_remoteoption')
		return (1)
	end

/*
**  Get the number which is the bit value to set
*/
select @statvalue = number
	from master.dbo.spt_values
	where name like '%' + @optname + '%'
		and type = 'F'
		and number in (1, 1)
		and number > 0


/*
**  Now update sysremotelogins.
*/
if lower(@optvalue) = 'true'
	begin
		update sysremotelogins
		set status = status | @statvalue
			from sysremotelogins r, sysservers s
			where r.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and r.remoteusername = @remotename
				and r.suid = @suid
		select @msg = 'Option ''' + @optname + ''' turned on.'
		print @msg
		return (0)
	end

/*
**  We want to turn it off.
*/
else
	begin
		update sysremotelogins
		set status = status & ~@statvalue
			from sysremotelogins r, sysservers s
			where r.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and r.remoteusername = @remotename
				and r.suid = @suid
		select @msg = 'Option ''' + @optname + ''' turned off.'
		print @msg
		return (0)
	end

return (0)
go


raiserror(15339,-1,-1,'sp_rename')
go
CREATE PROCEDURE sp_rename  --1996/03/04 12:45
       @objname    varchar(150)            -- Could be highly qualified.
      ,@newname        varchar( 30)
      ,@objtype  varchar( 13)   = null
as
/*************************************************
DOCUMENTATION (originally written 1996/01 for 6.5):

   [1]  To rename a table, OldName can be passed in totally
unqualified or fully qualified.
   [2]  The SA or DBO can rename objects owner by lesser users,
without the need for SetUser.
   [3]  The Owner portion of a qualified name can usually be
passed in the omitted form (as in MyDb..MyTab or MyTab).  The
typical exception is when the SA/DBO is trying to rename a table
where the OldName is present twice in sysobjects as a table
owned only by two different lesser users; requiring an explicit
owner qualifier in OldName.
   [4]  An unspecified Owner qualifier will default to the
current user if doing so will either resolve what would
otherwise be an ambiguity within ItemType, or will result
in exactly one match.
   [5]  If Database is part of the qualified OldName,
then it must match the current database.  NewName can
never be qualified.
*************************************************/

Set nocount    on
Set ansi_nulls on  -- So "(1=null OR 1<>null)" resolves to false.


Declare
       @OrigParm1ItemType  varchar(13)  -- max length + 1
      ,@WorkParm1ItemType  varchar(13)

Declare
       @RetCode            integer
      ,@ExecRC             integer
      ,@CurrentDb         varchar(30)
      ,@Int1               integer
      ,@Int2               integer

Declare
       @Tab_id             integer
      ,@Tab_uid            smallint
      ,@Tab_name           varchar(30)

      ,@Obj_id             integer
      ,@Obj_uid            smallint
      ,@Obj_type           char(2)
      ,@Obj_type_name      varchar(33)

      ,@Typ_usertype       smallint
      ,@Typ_uid            smallint

      ,@Col_colid          smallint
      ,@Idx_indid          smallint
      ,@Cns_constid        integer
      ,@Cns_obj_uid        smallint

Declare
       @QualName1          varchar(30)
      ,@QualName2          varchar(30)
      ,@QualName3          varchar(30)
      ,@QualName4          varchar(30)
      ,@QualName5          varchar(30)

      ,@WQualName1         varchar(30)
      ,@WQualName2         varchar(30)

Declare
       @UnqualOldName      varchar(30)

      ,@OldName1           varchar(30)    -- svr (possibly, ultimately)
      ,@OldName2           varchar(30)    -- db
      ,@OldName3           varchar(30)    -- own
      ,@OldName4           varchar(30)    -- tab
      ,@OldName5           varchar(30)    -- col
      ,@OldName6           varchar(30)    -- Problem?

--------

Select
       @RetCode         = 0  -- 0=good ,1=bad
      ,@ExecRC          = 1
      ,@UnqualOldName   = null
      ,@CurrentDb      = db_name()

      ,@Tab_id          = null
      ,@Tab_uid         = null
      ,@Tab_name        = null
      ,@Obj_id          = null
      ,@Obj_uid         = null
      ,@Obj_type        = null
      ,@Obj_type_name   = null
      ,@Typ_usertype    = null
      ,@Typ_uid         = null
      ,@Col_colid       = null
      ,@Idx_indid       = null
      ,@Cns_constid     = null
      ,@Cns_obj_uid     = null

      ,@QualName1       = null
      ,@QualName2       = null
      ,@QualName3       = null
      ,@QualName4       = null
      ,@QualName5       = null

      ,@WQualName1      = null
      ,@WQualName2      = null


------------------------------------------------------------------------
-------------------  PHASE 10:  Simple parm edits  ---------------------
------------------------------------------------------------------------


-------- Is explicit Parm1ItemType valid?

Select @OrigParm1ItemType = @objtype

IF (@OrigParm1ItemType IS NOT null)
   begin

   Select @Int1 = 0

   IF ('column'         LIKE (lower(@OrigParm1ItemType)+'%'))
      begin
      Select @objtype  = 'Column'
            ,@Int1            = @Int1 + 1
      end
   IF ('index'          LIKE (lower(@OrigParm1ItemType)+'%'))
      begin
      Select @objtype  = 'Index'
            ,@Int1            = @Int1 + 1
      end
   IF ('object'         LIKE (lower(@OrigParm1ItemType)+'%'))
      begin
      Select @objtype  = 'Object'
            ,@Int1            = @Int1 + 1
      end
   IF ('userdatatype'   LIKE (lower(@OrigParm1ItemType)+'%'))
      begin
      Select @objtype  = 'UserDataType'
            ,@Int1            = @Int1 + 1
      end

   IF (@Int1 <> 1)
      begin
      RaisError(15249,-1,-1,@OrigParm1ItemType,@Int1)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   end
--ELSE  -- Parm1ItemType IS null
--   begin
--
--   IF (@objname LIKE '%.%')
--      begin
--      RaisError(15247,-1,-1)
--      Select @RetCode = 1
--      GOTO LABEL_86_RETURN
--      end
--   end


-------- Parse apart the perhaps dots-qualified name.

IF (@objname IS null)
   begin
   RaisError(15223,-1,-1,'OldName')
   Select @RetCode = 1
   GOTO LABEL_86_RETURN
   end


Execute @ExecRC = sp_namecrack2 @objname
            ,@OldName1  Output  -- Leftmost node.
            ,@OldName2  Output  -- Next leftmost node (or null).
            ,@OldName3  Output  -- Next leftmost node (or null).
            ,@OldName4  Output
            ,@OldName5  Output
            ,@OldName6  Output

IF (@ExecRC <> 0)
   begin
   RaisError(15253,-1,-1,@objname,@OldName6)
   Select @RetCode = 1
   GOTO LABEL_86_RETURN
   end



IF      (@OldName6 IS NOT null)
           begin
           Select @UnqualOldName = @OldName6
                 ,@QualName1     = @OldName5 -- Right-most qualifier.
                 ,@QualName2     = @OldName4
                 ,@QualName3     = @OldName3
                 ,@QualName4     = @OldName2
                 ,@QualName5     = @OldName1
           end
ELSE IF (@OldName5 IS NOT null)
           begin
           Select @UnqualOldName = @OldName5
                 ,@QualName1     = @OldName4
                 ,@QualName2     = @OldName3
                 ,@QualName3     = @OldName2
                 ,@QualName4     = @OldName1
           end
ELSE IF (@OldName4 IS NOT null)
           begin
           Select @UnqualOldName = @OldName4
                 ,@QualName1     = @OldName3
                 ,@QualName2     = @OldName2
                 ,@QualName3     = @OldName1
           end
ELSE IF (@OldName3 IS NOT null)
           begin
           Select @UnqualOldName = @OldName3
                 ,@QualName1     = @OldName2
                 ,@QualName2     = @OldName1
           end
ELSE IF (@OldName2 IS NOT null)
           begin
           Select @UnqualOldName = @OldName2
                 ,@QualName1     = @OldName1
           end
ELSE IF (@OldName1 IS NOT null)
           begin
           Select @UnqualOldName = @OldName1
           end


---------------  Is NewName minimally valid?


Execute @ExecRC = sp_validname @newname

IF (     @ExecRC                    <>    0
   OR    @newname                  IS    null
   OR    @newname                  LIKE  '%.%'
   OR    substring(@newname,1,1)   =     '#'
   )
   begin
   RaisError(15224,-1,-1,@newname)
   Select @RetCode = 1
   GOTO LABEL_86_RETURN
   end


---------------------------------------------------------------------------
----------------------  PHASE 20:  Settle Parm1ItemType  ------------------
---------------------------------------------------------------------------
---- (Plus gather related info.) ----


------------ syscolumns?

Select @WorkParm1ItemType = 'column'


IF (     lower(@objtype)  = @WorkParm1ItemType
   OR    @OrigParm1ItemType      IS null
   )
   begin

   Select
       @WQualName1 = @QualName1
      ,@WQualName2 = @QualName2  -- Owner, might be modified/defaulted from null.

---- Must handle mytab.col1 even when there are two tables with same name.
   IF (@WQualName2 IS null)  -- owner
      begin
      SELECT
                @Int1         = count(*)
         from
                sysobjects    o1
         where
                o1.type       IN ('U','V')
         and    o1.name       = @WQualName1

      IF (@Int1 > 1)
         begin  -- Resolve owner ambiguity.
         Select @WQualName2 = user_name()
         end
      end


   Select @Int1 = null

   SELECT
             @Int1         = c1.colid
            ,@Col_colid    = c1.colid
      from
             syscolumns    c1
            ,sysobjects    o1
      where
             c1.name       = @UnqualOldName
      and    o1.name       = @WQualName1
      and   (o1.uid        = user_id(@WQualName2)  OR  -- Ensures max of 1 row.
             @WQualName2   IS null
            )
      and    c1.id         = o1.id
      and    o1.id         > 99  -- Avoid system tables/views.


   IF (          (@Int1                   IS     null
            AND   lower(@objtype)  =      @WorkParm1ItemType)
      OR
                 (@Int1                   IS NOT null
            AND   isnull(lower(@objtype) ,@WorkParm1ItemType)
                                          <>     @WorkParm1ItemType)
      )
      begin
      RaisError(15248,-1,-1,@OrigParm1ItemType)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   IF (@Int1 IS NOT null)  -- Get related useful info.
      begin
      Select @objtype = @WorkParm1ItemType  -- Common to all sections.

      Select @QualName2 = @WQualName2

      SELECT
                @Tab_id       = o1.id
               ,@Tab_uid      = o1.uid
         from
                sysobjects    o1
         where
                o1.type       IN ('U','V')
         and    o1.name       = @QualName1
         and   (o1.uid        = user_id(@WQualName2)  OR
                @WQualName2   IS null
               )
      end
   end


------------ sysindexes?

Select @WorkParm1ItemType = 'index'


IF (     lower(@objtype)  = @WorkParm1ItemType
   OR    @OrigParm1ItemType      IS null
   )
   begin

   Select
       @WQualName1 = @QualName1
      ,@WQualName2 = @QualName2

   IF (@WQualName2 IS null)  -- owner
      begin
      SELECT
                @Int1         = count(*)
         from
                sysobjects    o1
         where
                o1.type       = 'U'
         and    o1.name       = @WQualName1

      IF (@Int1 > 1)
         begin  -- Resolve owner ambiguity.
         Select @WQualName2 = user_name()
         end
      end


   Select @Int1 = null

   SELECT
             @Int1         = i1.indid
            ,@Idx_indid    = i1.indid
      from
             sysindexes    i1
            ,sysobjects    o1
      where
             i1.name       = @UnqualOldName
      and    o1.name       = @WQualName1
      and   (o1.uid        = user_id(@WQualName2)  OR
             @WQualName2   IS null
            )
      and    i1.id         = o1.id
      and    i1.indid      NOT IN (0,255)
      and    o1.id         > 99


   IF (          (@Int1                   IS     null
            AND   lower(@objtype)  =      @WorkParm1ItemType)
      OR
                 (@Int1                   IS NOT null
            AND   isnull(lower(@objtype) ,@WorkParm1ItemType)
                                          <>     @WorkParm1ItemType)
      )
      begin
      RaisError(15248,-1,-1,@OrigParm1ItemType)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   IF (@Int1 IS NOT null)
      begin
      Select @objtype = @WorkParm1ItemType

      Select @QualName2 = @WQualName2

      SELECT
                @Tab_id       = o1.id
               ,@Tab_uid      = o1.uid
         from
                sysobjects    o1
         where
                o1.type       = 'U'
         and    o1.name       = @WQualName1
         and   (o1.uid        = user_id(@WQualName2)  OR
                @WQualName2   IS null
               )

      SELECT
                @Cns_constid     = c2.constid
               ,@Cns_obj_uid     = o1.uid
         from
                sysconstraints   c2
               ,sysindexes       i1
               ,sysobjects       o1
         where
                i1.id            = c2.id
         and    i1.id            = @Tab_id
         and    i1.indid         = @Idx_indid
         and    o1.id            = c2.constid
         and    o1.name          = @UnqualOldName
         and    o1.uid           = @Tab_uid
      end
   end


------------ sysobjects.

Select @WorkParm1ItemType = 'object'


IF (     lower(@objtype)  = @WorkParm1ItemType
   OR    @OrigParm1ItemType      IS null
   )
   begin

   Select
       @WQualName1 = @QualName1

   IF (@WQualName1 IS null)  -- owner
      begin
      SELECT
                @Int1         = count(*)
         from
                sysobjects    o1
         where
                o1.name       = @UnqualOldName

      IF (@Int1 > 1)
         begin  -- Resolve owner ambiguity.
         Select @WQualName1 = user_name()
         end
      end


   Select @Int1 = null

   SELECT
             @Int1         = o1.id
            ,@Obj_id       = o1.id
            ,@Obj_uid      = o1.uid
            ,@Obj_type     = o1.type
      from
             sysobjects    o1
      where
             o1.name       = @UnqualOldName
      and   (o1.uid        = user_id(@WQualName1)  OR
             @WQualName1   IS null
            )
      and    o1.id         > 99  -- Avoid system objects.


   IF (          (@Int1                   IS     null
            AND   lower(@objtype)  =      @WorkParm1ItemType)
      OR
                 (@Int1                   IS NOT null
            AND   isnull(lower(@objtype) ,@WorkParm1ItemType)
                                          <>     @WorkParm1ItemType)
      )
      begin
      RaisError(15248,-1,-1,@OrigParm1ItemType)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end


   IF (@Int1 IS NOT null)
      begin
      Select @objtype = @WorkParm1ItemType

      Select @QualName1 = @WQualName1


      Select @Obj_type_name =
               CASE @Obj_type
                  When 'D ' Then 'Default'
                  When 'F ' Then 'Foreign Key'
                  When 'K ' Then 'Primary/Unique Key'
                  When 'P ' Then 'Procedure'
                  When 'R ' Then 'Rule'
                  When 'RF' Then 'Replication Filter' -- ?
                  When 'TR' Then 'Trigger'
                  When 'V ' Then 'View'
                  Else           ' ? '
               END

--      IF (@Obj_type IN ('D','P','R' ,'RF','TR','V') ) -- 'C' lacks name in syscomments.text
--         begin
--         Raiserror(15336,-1,-1,@Obj_type_name)  -- "dbcc upgradedb(null)" seems to handle these discrepancies.
--         Select @RetCode = 1
--         GOTO LABEL_86_RETURN
--         end


      IF (@Obj_type = 'K')
         begin

         SELECT
                   @Tab_id          = o2.id
                  ,@Tab_uid         = o2.uid
                  ,@Tab_name        = o2.name
            from
                   sysobjects       o1  -- cns=obj
                  ,sysobjects       o2  -- tab
                  ,sysconstraints   c2
            where
                   c2.constid       = @Obj_id
            and    c2.id            = o2.id
            and    c2.constid       = o1.id


         SELECT
                   @Idx_indid       = i1.indid
            from
                   sysindexes       i1
            where
                   i1.id            = @Tab_id
            and    i1.name          = @UnqualOldName

         end
      end
   end


------------ systypes.

Select @WorkParm1ItemType = 'userdatatype'


IF (     lower(@objtype)  = @WorkParm1ItemType
   OR    @OrigParm1ItemType      IS null
   )
   begin
---- systypes.name is unique, without uid.

   Select @Int1 = null

   SELECT
             @Int1         = t1.usertype
            ,@Typ_usertype = t1.usertype
            ,@Typ_uid      = t1.uid
      from
             systypes      t1
      where
             t1.name       = @UnqualOldName
      and   (t1.uid        = user_id(@QualName1)  OR
             @QualName1 IS null
            )
      and    t1.usertype   > 99  -- Avoid system datatypes.


   IF (          (@Int1                   IS     null
            AND   lower(@objtype)  =      @WorkParm1ItemType)
      OR
                 (@Int1                   IS NOT null
            AND   isnull(lower(@objtype) ,@WorkParm1ItemType)
                                          <>     @WorkParm1ItemType)
      )
      begin
      RaisError(15248,-1,-1,@OrigParm1ItemType)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   IF (@Int1 IS NOT null)
      begin
      Select @objtype = @WorkParm1ItemType
      end
   end



LABEL_28_AFTERPARM1ITEMTYPE:



-----------------  Valid Parm1ItemType?  ---------------------------


-------- Parm1ItemType determined?

   IF (@objtype IS null)
      begin
      RaisError(15225,-1,-1,@objname,@CurrentDb,@OrigParm1ItemType)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end


-------- Valid combination?

   IF (     lower(@objtype)  IN       ('column','index')
      AND   @objname           NOT LIKE '%.%'
      )
      begin
      RaisError(15332,-1,-1,@objtype)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end



---------------------------------------------------------------------
-------------------  PHASE 30:  More parm edits  --------------------
---------------------------------------------------------------------


---------------  verify any database qualifier matches current db  -----------


IF       (lower(@objtype) IN ('column','index'))
         begin
         IF (isnull(@QualName3,@CurrentDb) <> @CurrentDb)
            begin
            RaisError(15333,-1,-1,@QualName3)
            Select @RetCode = 1
            GOTO LABEL_86_RETURN
            end
         end
ELSE IF  (lower(@objtype) IN ('object','userdatatype'))
         begin
         IF (isnull(@QualName2,@CurrentDb) <> @CurrentDb)
            begin
            RaisError(15333,-1,-1,@QualName2)
            Select @RetCode = 1
            GOTO LABEL_86_RETURN
            end
         end
ELSE
         begin  -- Never will happen.
         RaisError('Error, this procedure has calculated a null or unrecognized ItemType value (%s).   Please give an explicit value for ItemType and retry.'
                  ,11,1,@objtype)
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end


-------------------  Validate ownership/authorization issues  ---------------


-------- systypes?

IF (lower(@objtype) = 'userdatatype')
   begin

   IF (     suser_id()  <> 1
      AND   user_id()   <> 1
      AND   @Typ_uid    <> user_id()
      )
      begin
      RaisError(15334,-1,-1)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


IF (lower(@objtype) = 'object')
   begin

   IF (     suser_id()  <> 1
      AND   user_id()   <> 1
      AND   @Obj_uid    <> user_id()
      )
      begin
      RaisError(15334,-1,-1)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


IF (lower(@objtype) IN ('index','column'))
   begin

   IF (     suser_id()  <> 1
      AND   user_id()   <> 1
      AND   @Tab_uid    <> user_id()
      )
      begin
      RaisError(15334,-1,-1)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


-------------------  Catch NewName clashes now before Upd  -----------------


IF (lower(@objtype) = 'column')
   begin

   IF exists (SELECT * from syscolumns c1 where c1.id=@Tab_id
                  and c1.name=@newname and c1.name<>@UnqualOldName
             )
      begin
      RaisError(15335,-1,-1,@newname,@objtype)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


IF (lower(@objtype) = 'index')
   begin

   IF exists (   (SELECT * from sysindexes i1 where i1.id=@Tab_id
                     and i1.name=@newname and i1.name<>@UnqualOldName)
             )
      begin
      RaisError(15335,-1,-1,@newname,@objtype)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   IF (@Cns_constid IS NOT null)
      begin

      IF exists (SELECT * from sysobjects o1 ,sysconstraints c2
                     where c2.constid=@Cns_constid and o1.id<>@Cns_constid
                     and   o1.name=@UnqualOldName  and o1.uid=@Cns_obj_uid
                )
         begin
         RaisError(15335,-1,-1,@newname,@objtype)
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end
      end
   end


IF (lower(@objtype) = 'object')
   begin

   IF exists (SELECT * from sysobjects o1
                  where o1.name=@newname and o1.id<>@Obj_id
                  and   o1.uid=@Obj_uid
             )
      begin
      RaisError(15335,-1,-1,@newname,@objtype)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

---- Indirect duplicates object related?

   IF (@Obj_type IN ('K'))
      begin

      ---- other indexes?
      SELECT
                @Int1            = count(*)
         from
                sysindexes       i1
               ,sysconstraints   c2
         where
                c2.constid       = @Obj_id
         and    i1.name         <> @UnqualOldName
         and    i1.name          = @newname  -- Not worry about 't'ext clashes.
         and    c2.id            = i1.id

      IF (@Int1 > 0)
         begin
         RaisError(15335,-1,-1,@newname,@objtype)
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end
      end
   end


IF (lower(@objtype) = 'userdatatype')
   begin

   IF exists (SELECT * from systypes t1
                  where t1.name=@newname and t1.name<>@UnqualOldName
             )
      begin
      RaisError(15335,-1,-1,@newname,@objtype)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


--------------------------------------------------------------------------
--------------------  PHASE 34:  Cautionary messages  --------------------
--------------------------------------------------------------------------


IF (lower(@objtype) = 'objects')
   begin

   IF exists (SELECT * from sysdepends where depid = @Obj_id)
      begin
      Raiserror(15337,-1,-1)
      end
   end



--------------------------------------------------------------------------
---------------------  PHASE 40:  Update system tables  ------------------
--------------------------------------------------------------------------


-------- Upd systypes

IF (lower(@objtype) = 'userdatatype')
   begin


   BEGIN  TRANSACTION txn_typ1_sp_rename

   UPDATE
             systypes
      set
             name       = @newname
      where
             usertype   = @Typ_usertype

   ---- These Upds should never error, thus do not bother with sysmessages.
   IF (@@error<>0 or @@rowcount<>1)
      begin
      RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_typ1,name')
      Rollback Transaction
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   COMMIT TRANSACTION txn_typ1_sp_rename

   end


-------- Upd sysobjects

IF (lower(@objtype) = 'object')
   begin

   IF (@Obj_type = 'K ')  -- P/U Key
      begin

      BEGIN  TRANSACTION txn_obj2_sp_rename


      UPDATE
                sysindexes
         set
                name       = @newname
         where
                id         = @Tab_id
         and    indid      = @Idx_indid

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj2,k10')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end


      UPDATE
                sysobjects
         set
                name       = @newname  -- Constraint renamed.
         where
                id         = @Obj_id

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj2,k20')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end


      UPDATE
                sysobjects
         set
                schema_ver = schema_ver + 1  -- Force recompiles.
         where
                id         = @Tab_id

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj2,k30')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end


      COMMIT TRANSACTION txn_obj2_sp_rename


      GOTO LABEL_51_AFTERUPDATES  ------------ Jumping.

      end



-------- Default "plain" objects section.


   SELECT
             @Int1      = min(i1.indid)
            ,@Int2      = max(i1.indid)
      from
             sysindexes i1
      where
             i1.id      = @Obj_id


   BEGIN  TRANSACTION txn_obj1_sp_rename


   UPDATE
             sysobjects
      set
             name       = @newname
            ,schema_ver = schema_ver + 1
      where
             id         = @Obj_id

   IF (@@error<>0 or @@rowcount<>1)
      begin
      RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj1,schema_ver')
      Rollback Transaction
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end


   IF (isnull(@Int1,-123) = 0)  -- Tab with no clus Idx.
      begin

      UPDATE
             sysindexes
         set
             name    = @newname
         where
             id      = @Obj_id
         and indid   = 0

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj1,0')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end
      end


   IF (isnull(@Int2,-123) = 255)  -- 't'ext col in tab.
      begin

      UPDATE
             sysindexes
         set
             name    = 't' + substring(@newname,1,29)
         where
             id      = @Obj_id
         and indid   = 255

      IF (@@error<>0 or @@rowcount<>1)  -- Only 1 indid=255 row for all text+image cols per table.
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_obj1,255')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end
      end


   COMMIT TRANSACTION txn_obj1_sp_rename

   end


-------- Upd sysindexes

IF (lower(@objtype) = 'index')
   begin


   BEGIN  TRANSACTION txn_idx1_sp_rename

   UPDATE
             sysindexes
      set
             name       = @newname
      where
             id         = @Tab_id
      and    indid      = @Idx_indid

   IF (@@error<>0 or @@rowcount<>1)
      begin
      RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_idx1,idx name')
      Rollback Transaction
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end


   IF (@Cns_constid IS NOT null)
      begin
      UPDATE
             sysobjects
         set
             name       = @newname
         where
             id         = @Cns_constid

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_idx1,const name')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end

      UPDATE
             sysobjects
         set
             schema_ver = schema_ver + 1
         where
             id         = @Tab_id

      IF (@@error<>0 or @@rowcount<>1)
         begin
         RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_idx1,schema_ver b')
         Rollback Transaction
         Select @RetCode = 1
         GOTO LABEL_86_RETURN
         end
      end


   COMMIT TRANSACTION txn_idx1_sp_rename

   end


-------- Upd syscolumns

IF (lower(@objtype) = 'column')
   begin


   BEGIN  TRANSACTION txn_col1_sp_rename

   UPDATE
             syscolumns
      set
             name       = @newname
      where
             id         = @Tab_id
      and    name       = @UnqualOldName

   IF (@@error<>0 or @@rowcount<>1)
      begin
      RaisError('Error during Update, issuing Rollback! (%s)',16,1,'txn_col1,col name')
      Rollback Transaction
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end

   -- Perhaps schema_ver+1 good here.

   COMMIT TRANSACTION txn_col1_sp_rename


   GOTO LABEL_51_AFTERUPDATES

   end


LABEL_51_AFTERUPDATES:


-------------------------  Finalization  -----------------------


Raiserror(15338,-1,-1,@objtype,@newname)


LABEL_86_RETURN:

Return @RetCode --sp_rename
go



raiserror(15339,-1,-1,'sp_renamedb')
go
create procedure sp_renamedb
@dbname sysname,			/* old (current) db name */
@newname sysname			/* new name we want to call it */
as

declare @objid int			/* object id of the thing to rename */
declare @bitdesc varchar(30)		/* bit description for the db */
declare @curdbid int			/* id of database to be changed */

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_renamedb')
		return (1)
	end

/*
**  Only the SA can do this.
*/
if suser_id() <> 1
	begin
		raiserror(15226,-1,-1)
		return (1)
	end

/*
**  Make sure the database exists.
*/
if not exists (select * from sysdatabases where name = @dbname)
	begin
		raiserror(15010,-1,-1,@dbname)
		return (1)
	end

/*
**  Make sure that the @newname db doesn't already exist.
*/
if exists (select * from sysdatabases where name = @newname)
	begin
		raiserror(15032,-1,-1,@newname)
		return (1)
	end

/*
**  Check to see that the @newname is valid.
*/
declare @returncode int
exec @returncode = sp_validname @newname
if @returncode <> 0
	return(1)

/*
**  Don't allow the names of master, tempdb, and model to be changed.
*/
if @dbname in ('master', 'model', 'tempdb')
	begin
		raiserror(15227,-1,-1,@dbname)
		return (1)
	end

/* Get current database id */
select @curdbid = db_id(@dbname)

/*
** Check single user bit (4096)
** Database must be in single user mode to necessitate the rid update in the
** database's DBTABLE
*/
select @bitdesc = null
select @bitdesc = v.name
	from master.dbo.spt_values v, sysdatabases d
	where d.dbid = @curdbid
		and v.type = 'D'
		and d.status & v.number = 4096

if @bitdesc is null
	begin
		raiserror(15228,-1,-1,@dbname)
		return(1)
	end

/*
**  Everything is ok so do it.
*/
update sysdatabases set name = @newname
	where name = @dbname

/*
** Mark dbtable status dirty to update to the new name in Resources.
**
*/
dbcc dbrepair (@newname,markdirty)

print 'Database is renamed and in single-user mode.'
print 'System Administrator (SA) must reset it to multi-user mode with sp_dboption.'

return (0)
go


raiserror(15339,-1,-1,'sp_serveroption')
go
create procedure sp_serveroption --1996/02/28 13:56
@server varchar(30) = NULL,	/* server name to change */
@optname varchar(20) = NULL,	/* option name to turn on/off */
@optvalue varchar(10) = NULL	/* true or false */
as

set ansi_nulls on

declare @srvid int			/* id of the server */
declare @statvalue smallint		/* number of option */
declare @optcount int			/* number of options like @optname */
declare @fallback_bit integer

/*
**  If no @server given, just list the possible server options.
**  Only certain status bits may be set or cleared.
**    settable                        not settable
**    ------------------------------  --------------------------
**	  rpc (1)
**	  pub (2)
**	  sub (4)
**	  dist (8)
**	  dpub (16)
**	  dsn (32)
**	  fallback (64)
*/
if @server is null
	begin
		print 'Settable server options.'
		select server_option = name
			from master.dbo.spt_values
			where type = 'A'
				and number not in (-1)
			order by name
		return (0)
	end

/*
**  Verify the server name and get the @srvid
*/
select @srvid = srvid
	from sysservers
		where srvname = @server

/*
**  If @server not found, say so.
*/
if @srvid is NULL
	begin
		raiserror(15015,-1,-1,@server)
		return (1)
	end

/*
**  Check remaining parameters.
*/
if @optname is NULL or lower(@optvalue) not in ('true', 'false')
	begin
		raiserror(15229,-1,-1)
		return (1)
	end

/*
**  Use @optname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @optcount = count(*) from master.dbo.spt_values
	where name like @optname
		and type = 'A'
		and number not in (-1)

/*
**  If no option, show the user what the options are.
*/
if @optcount = 0
	begin
		raiserror(15230,-1,-1,@optname)
		return (1)
	end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
	begin
		raiserror(15231,-1,-1,@optname)
		print ''

		select duplicate_option = name
			from master.dbo.spt_values
			where name like @optname
				and type = 'A'
				and number not in (-1)
		return (1)
	end

/*
**  Only the SA or the dbo of @dbnbame can execute the update part
**  of this procedure so check.  Also the sproc must be executed in the master
**  database.
*/
if suser_id() <> 1
	begin
		raiserror(15232,-1,-1)
		return (1)
	end

/*
**  Get the number which is the bit value to set
*/
select @statvalue = number
	from master.dbo.spt_values
	where name like @optname
		and type = 'A'
		and number > 0

/*
** Only one server may be a distribution server.
*/
if @optname like 'dist'
  begin
     if lower(@optvalue) = 'true'
        begin
	if exists (select * from sysservers where (srvstatus & @statvalue) <>
	   0)
	   begin
	      raiserror(14090,-1,-1)
	      return (1)
	   end
	/* Add remote mapping of sa, if the distributor is remote. */
	if @srvid <> 0
	   begin
    	      execute sp_addremotelogin @server, sa, sa
              execute sp_remoteoption @server, sa, sa, trusted, true
	   end
	end
     else /* @optvalue = 'false' */
	/* Drop remote mapping of sa, if the distributor is remote. */
        if @srvid <> 0
    	   execute sp_dropremotelogin @server, sa, sa
  end

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_serveroption')
		return (1)
	end

/*
**  Now update sysservers.
*/
if lower(@optvalue) = 'true'
	begin

	select @fallback_bit = min(val.number) from master..spt_values val
		where val.type='A  ' and val.name='fallback'

	---- Ensure max of 1 fallback server.
	if not 0 = (select count(*) from master..sysservers
			where srvstatus & 64 > 0
		)
		begin
		RaisError(15378,-1,-1)
		return(1)
		end

	update sysservers
		set srvstatus = srvstatus | @statvalue
		where srvid = @srvid
	end

/*
**  We want to turn it off.
*/
else
	update sysservers set srvstatus = srvstatus & ~@statvalue
		where srvid = @srvid

return (0)
go


raiserror(15339,-1,-1,'sp_setnetname')
go
create procedure sp_setnetname  --1995/12/22 13:07
	 @server	varchar(30)	-- server name
	,@netname	varchar(30)	-- new net name
as

---- The server must exist, so check.

if not exists (select * from sysservers where srvname = @server)
	begin
		raiserror(15015,-1,-1,@server)
		return (1)
	end

-- sysservers.srvnetname need not be unique, logic and Msg 15233 removed (1995/12/22).

-- We will not validate @server name here, would be redundant (1995/11/28).

update sysservers set srvnetname = @netname where srvname = @server

print 'Server network name set.'
return (0)
go

dump transaction master with no_log
go


raiserror(15339,-1,-1,'sp_spaceused')
go
create procedure sp_spaceused
@objname varchar(92) = null,		-- The object we want size on.
@updateusage varchar(5) = false		-- Param. for specifying that
					-- usage info. should be updated.
as

declare @id	int			-- The object id of @objname.
declare @type	smallint		-- The object type.
declare	@pages	int			-- Working variable for size calc.
declare @dbname varchar(30)
declare @dbsize dec(15,0)

/*
**  Check to see if user wants usages updated.
*/

if @updateusage is not null
	begin
		select @updateusage=lower(@updateusage)

		if @updateusage not in ('true','false')
			begin
				raiserror(15143,-1,-1,@updateusage)
				return(1)
			end
	end
/*
**  Check to see that the objname is local.
*/
if @objname IS NOT NULL
begin
	if @objname like '%.%.%'
		begin
			select @dbname =
				substring(@objname, 1, charindex('.', @objname) - 1)

			if @dbname <> db_name()
				begin
					raiserror(15250,-1,-1)
					return (1)
				end
		end
	else
		select @dbname = db_name()

	/*
	**  Try to find the object.
	*/
	select @id = null
	select @id = id, @type = sysstat & 0xf
		from sysobjects
			where id = object_id(@objname)

	/*
	**  Does the object exist?
	*/
	if @id is null
		begin
			raiserror(15009,-1,-1,@objname,@dbname)
			return (1)
		end

	/*
	**  See if it's a space object.
	**  types are:
	**	1 - system table
	**	2 - view
	**	3 - user table
	**	4 - sproc
	**	6 - default
	**	7 - rule
	**	8 - trigger
	**	9 - primary key
	**	10 - check constraint
	**	11 - foreign key
	**	12 - replication filter stored proc
	*/

	if not exists (select * from sysindexes
				where @id = id and indid < 2)

		if @type in (4, 6, 7, 8, 10, 12)	-- data stored
				begin			-- in sysprocedures
					raiserror(15234,-1,-1)
					return (1)
				end
		else if @type = 2	-- View => no physical data storage.
				begin
					raiserror(15235,-1,-1)
					return (1)
				end
		else if @type = 9	-- PK => no physical data storage.
				begin
					raiserror(15064,-1,-1)
					return (1)
				end
		else if @type = 11	-- FK => no physical data storage.
				begin
					raiserror(15275,-1,-1)
					return (1)
				end
end

/*
**  Update usages if user specified to do so.
*/

if @updateusage = 'true'
	begin
		if @objname is null
			dbcc updateusage(0) with no_infomsgs
		else
			dbcc updateusage(0,@objname) with no_infomsgs
		print ''
	end

/*
**  We need to create a temp table to do the calculation.
**  reserved: sum(reserved) where indid in (0, 1, 255)
**  data: sum(dpages) where indid < 2 + sum(used) where indid = 255 (text)
**  indexp: sum(used) where indid in (0, 1, 255) - data
**  unused: sum(reserved) - sum(used) where indid in (0, 1, 255)
*/
create table #spt_space
(
	rows		int null,
	reserved	dec(15) null,
	data		dec(15) null,
	indexp		dec(15) null,
	unused		dec(15) null
)
set nocount on

/*
**  If @id is null, then we want summary data.
*/
if @id is null
begin
	select @dbsize = sum(convert(dec(15),size))
		from sysusages
		where dbid = db_id()

	select  database_name = db_name(),
		database_size =
			ltrim(str(@dbsize / 512,15,2) + ' MB'),
		'unallocated space' =
			ltrim(str((@dbsize -
				(select sum(convert(dec(15),reserved))
					from sysindexes
						where indid in (0, 1, 255)
				))/512,15,2)+ ' MB')

	print ''
	/*
	**  Now calculate the summary data.
	**  reserved: sum(reserved) where indid in (0, 1, 255)
	*/
	insert into #spt_space (reserved)
		select sum(convert(dec(15),reserved))
			from sysindexes
				where indid in (0, 1, 255)

	/*
	** data: sum(dpages) where indid < 2
	**	+ sum(used) where indid = 255 (text)
	*/
	select @pages = sum(convert(dec(15),dpages))
			from sysindexes
				where indid < 2
	select @pages = @pages + isnull(sum(convert(dec(15),used)), 0)
		from sysindexes
			where indid = 255
	update #spt_space
		set data = @pages


	/* index: sum(used) where indid in (0, 1, 255) - data */
	update #spt_space
		set indexp = (select sum(convert(dec(15),used))
				from sysindexes
					where indid in (0, 1, 255))
			    - data

	/* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */
	update #spt_space
		set unused = reserved
				- (select sum(convert(dec(15),used))
					from sysindexes
						where indid in (0, 1, 255))

	select reserved = ltrim(str(reserved * d.low / 1024.,15,0) +
				' ' + 'KB'),
		data = ltrim(str(data * d.low / 1024.,15,0) +
				' ' + 'KB'),
		index_size = ltrim(str(indexp * d.low / 1024.,15,0) +
				' ' + 'KB'),
		unused = ltrim(str(unused * d.low / 1024.,15,0) +
				' ' + 'KB')
		from #spt_space, master.dbo.spt_values d
		where d.number = 1
			and d.type = 'E'
end

/*
**  We want a particular object.
*/
else
begin
	/*
	**  Now calculate the summary data.
	**  reserved: sum(reserved) where indid in (0, 1, 255)
	*/
	insert into #spt_space (reserved)
		select sum(reserved)
			from sysindexes
				where indid in (0, 1, 255)
					and id = @id

	/*
	** data: sum(dpages) where indid < 2
	**	+ sum(used) where indid = 255 (text)
	*/
	select @pages = sum(dpages)
			from sysindexes
				where indid < 2
					and id = @id
	select @pages = @pages + isnull(sum(used), 0)
		from sysindexes
			where indid = 255
				and id = @id
	update #spt_space
		set data = @pages


	/* index: sum(used) where indid in (0, 1, 255) - data */
	update #spt_space
		set indexp = (select sum(used)
				from sysindexes
					where indid in (0, 1, 255)
						and id = @id)
			    - data

	/* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */
	update #spt_space
		set unused = reserved
				- (select sum(used)
					from sysindexes
						where indid in (0, 1, 255)
							and id = @id)
	update #spt_space
		set rows = i.rows
			from sysindexes i
				where i.indid < 2
					and i.id = @id

	select name = substring(object_name(@id), 1, 20),
		rows = convert(char(11), rows),
		reserved = ltrim(str(reserved * d.low / 1024.,15,0) +
				' ' + 'KB'),
		data = ltrim(str(data * d.low / 1024.,15,0) +
				' ' + 'KB'),
		index_size = ltrim(str(indexp * d.low / 1024.,15,0) +
				' ' + 'KB'),
		unused = ltrim(str(unused * d.low / 1024.,15,0) +
				' ' + 'KB')
	from #spt_space, master.dbo.spt_values d
		where d.number = 1
			and d.type = 'E'
end

return (0)
go


raiserror(15339,-1,-1,'sp_sqlexec')
go
create procedure sp_sqlexec @p1 text as exec(@p1)
go



raiserror(15339,-1,-1,'sp_unbindefault')
go
create procedure sp_unbindefault
--1995/09/14 15:06
@objname varchar(61),         /* table/column or datatype name */
@futureonly varchar(15) = NULL   /* flag to indicate extent of binding */
as

declare @olddefault int  --current default for type
declare @tabname varchar(92)  --possible name of table
       ,@colname varchar(92)  --possible name of column

declare @futurevalue varchar(15) /* the value of @futureonly that causes
               ** the binding to be limited */

select @futurevalue = 'futureonly'  /* initialize @futurevalue */

/*
**  When a default or rule is bound to a user-defined datatype, it is also
**  bound, by default, to any columns of the user datatype that are currently
**  using the existing default or rule as their default or rule.  This default
**  action may be overridden by setting @futureonly = @futurevalue when the
**  procedure is invoked.  In this case existing columns with the user
**  datatype won't have their existing default or rule changed.
*/

/*
**  Check to see that the object names are local to the current database.
*/
if @objname like '%.%.%'  --61?
   and substring(@objname, 1, charindex('.', @objname) - 1) <> db_name()
   begin
      raiserror(15084,-1,-1)
      return (1)
   end

/*
**  If @objname is of the form tab.col then we are unbinding a column.
**  Otherwise its a datatype.  In the column case, we need to extract
**  and verify the table and column names and make sure the user owns
**  the table that is getting the default unbound.
*/
if @objname like '%.%'
begin
   /*
   **  Get the table name out.
   */
   select @tabname = substring(@objname, 1, charindex('.', @objname) - 1)
   select @colname = substring(@objname, charindex('.', @objname) + 1, 61)

   if (     datalength(@tabname) > 30
      or    datalength(@colname) > 30
      )
      begin
      raiserror(15299,-1,-1,@objname)
      return (1)
      end

   /*
   **  Find it and unbind it.
   */
   if exists (select *
         from syscolumns, sysobjects
      where syscolumns.id = object_id(@tabname)
         and syscolumns.name = @colname
         and sysobjects.id = object_id(@tabname)
         and uid = user_id()
         and sysobjects.sysstat & 0xf = 3)      /* user table */
   begin
      /*
      **  Is there something bound to it?
      */
      if exists (select *
         from syscolumns, sysobjects
      where syscolumns.id = object_id(@tabname)
         and syscolumns.name = @colname
         and sysobjects.id = object_id(@tabname)
         and uid = user_id()
         and sysobjects.sysstat & 0xf = 3      /* user table */
         and cdefault <> 0)
      begin
         update syscolumns
            set cdefault = 0
               from syscolumns, sysobjects
            where syscolumns.id = object_id(@tabname)
               and syscolumns.name = @colname
               and sysobjects.id = object_id(@tabname)
               and uid = user_id()
               and sysobjects.sysstat & 0xf = 3

         /*
         **  Since binding a default is a schema change,
         **  update schema count
         **  for the object in the sysobjects table.
         */
         update sysobjects set schema_ver = schema_ver + 1
            from sysobjects
            where id = object_id(@tabname)
               and uid = user_id()

         print 'Default unbound from table column.'
         return (0)
      end

      else
         begin
            raiserror(15236,-1,-1,@objname)
            return (1)
         end
   end

   /*
   **  If we got here, there was no such object.
   */
   raiserror(15104,-1,-1,@tabname,@colname)
   return (1)

end

else

begin
   /*
   **  We're unbinding to a user type.  In this case, the @objname
   **  is really the name of the user datatype.
   **  When we unbind to a user type, any existing columns get changed
   **  to the new binding unless their current binding is not equal
   **  to the current binding for the usertype or if they set the
   **  @futureonly parameter to @futurevalue.
   */

   if (     datalength(@objname) > 30)
      begin
      raiserror(15299,-1,-1,@objname)
      return (1)
      end

   /*
   **  Get the current default for the datatype.
   */
   select @olddefault = tdefault
      from systypes
         where name = @objname
            and uid = user_id()
            and usertype > 100

   if @olddefault is null
      begin
         raiserror(15036,-1,-1,@objname)
         return (1)
      end

   if @olddefault = 0
      begin
         raiserror(15237,-1,-1,@objname)
         return (1)
      end

   update systypes set tdefault = 0
      from systypes
      where name = @objname
         and uid = user_id()
         and usertype > 100

   print 'Default unbound from datatype.'

   /*
   **  Now see if there are any columns with the usertype that
   **  need the new binding.
   */
   if isnull(@futureonly, '') <> @futurevalue
      and exists (select *
         from syscolumns, systypes
            where syscolumns.usertype = systypes.usertype
               and systypes.name = @objname
               and systypes.usertype > 100
               and systypes.uid = user_id()
               and syscolumns.cdefault = @olddefault)
   begin
      /*
      **  Update syscolumns with new binding.
      */
      update syscolumns set cdefault = systypes.tdefault
         from syscolumns, systypes
         where syscolumns.usertype = systypes.usertype
            and systypes.name = @objname
            and systypes.usertype > 100
            and systypes.uid = user_id()
            and syscolumns.cdefault = @olddefault

      /*
      **  Update the table schema to indicate that something
      **  has changed in the table's schema.
      */
      update sysobjects set schema_ver = schema_ver + 1
         from sysobjects, syscolumns, systypes
         where sysobjects.id = syscolumns.id
            and syscolumns.usertype = systypes.usertype
            and systypes.name = @objname
            and systypes.usertype > 100
            and systypes.uid = user_id()
            and syscolumns.cdefault = systypes.tdefault

      print 'Columns of the user datatype specified had their defaults unbound.'
   end
end

return (0)
go



raiserror(15339,-1,-1,'sp_unbindrule')
go
create procedure sp_unbindrule
--1995/09/14 15:24
@objname varchar(61),         /* table/column or datatype name */
@futureonly varchar(15) = NULL      /* flag to indicate extent of binding */
as

declare @oldrule int /* current rule for type */
declare @tabname varchar(30)     /* name of table */
declare @colname varchar(30)     /* name of column */
declare @futurevalue varchar(15) /* the value of @futureonly that causes
                           ** the binding to be limited */

select @futurevalue = 'futureonly'  /* initialize @futurevalue */

/*
**  When a default or rule is bound to a user-defined datatype, it is also
**  bound, by default, to any columns of the user datatype that are currently
**  using the existing default or rule as their default or rule.  This default
**  action may be overridden by setting @futureonly = @futurevalue when the
**  procedure is invoked.  In this case existing columns with the user
**  datatype won't have their existing default or rule changed.
*/

/*
**  Check to see that the object names are local to the current database.
*/
if @objname like '%.%.%'
   begin
      raiserror(15084,-1,-1)
      return (1)
   end

/*
**  If @objname is of the form tab.col then we are unbinding a column.
**  Otherwise its a datatype.  In the column case, we need to extract
**  and verify the table and column names and make sure the user owns
**  the table that is getting the default unbound.
*/
if @objname like '%.%'
begin
   /*
   **  Get the table name out.
   */
   select @tabname = substring(@objname, 1, charindex('.', @objname) - 1)
   select @colname = substring(@objname, charindex('.', @objname) + 1, 61)

   if (     datalength(@tabname) > 30
      or    datalength(@colname) > 30
      )
      begin
      raiserror(15299,-1,-1,@objname)
      return (1)
      end

   /*
   **  Find it and unbind it.
   */
   if exists (select * from syscolumns, sysobjects
      where syscolumns.id = object_id(@tabname)
         and syscolumns.name = @colname
         and sysobjects.id = object_id(@tabname)
         and uid = user_id()
         and sysobjects.sysstat & 0xf = 3)      /* user table */
   begin
      /*
      **  Is there something bound to it?
      */
      if exists (select * from syscolumns, sysobjects
      where syscolumns.id = object_id(@tabname)
         and syscolumns.name = @colname
         and sysobjects.id = object_id(@tabname)
         and uid = user_id()
         and sysobjects.sysstat & 0xf = 3      /* user table */
         and domain <> 0)
      begin
         update syscolumns set domain = 0
            from syscolumns, sysobjects
            where syscolumns.id = object_id(@tabname)
               and syscolumns.name = @colname
               and sysobjects.id = object_id(@tabname)
               and uid = user_id()
               and sysobjects.sysstat & 0xf = 3

         /*
         **  Since binding a rule is a schema change,
         **  update schema count
         **  for the object in the sysobjects table.
         */
         update sysobjects set schema_ver = schema_ver + 1
            from sysobjects
            where id = object_id(@tabname)
               and uid = user_id()

         print 'Rule unbound from table column.'
         return (0)
      end

      else
         begin
            raiserror(15238,-1,-1,@colname)
            return (1)
         end
   end

   /*
   **  If we got here, there was no such object.
   */
   raiserror(15104,-1,-1,@tabname,@colname)
   return (1)

end

else

begin
   /*
   **  We're unbinding to a user type.  In this case, the @objname
   **  is really the name of the user datatype.
   **  When we unbind to a user type, any existing columns get changed
   **  to the new binding unless their current binding is not equal
   **  to the current binding for the usertype or if they set the
   **  @futureonly parameter to @futurevalue.
   */

   if (     datalength(@objname) > 30)
      begin
      raiserror(15299,-1,-1,@objname)
      return (1)
      end

   /*
   **  Get the current rule for the datatype.
   */
   select @oldrule = domain
   from systypes
   where name = @objname
      and uid = user_id()
      and usertype > 100

   if @oldrule is null
      begin
         raiserror(15036,-1,-1,@objname)
         return (1)
      end

   if @oldrule = 0
      begin
         raiserror(15239,-1,-1,@objname)
         return (1)
      end

   update systypes set domain = 0
      from systypes
      where name = @objname
         and uid = user_id()
         and usertype > 100

   print 'Rule unbound from datatype.'

   /*
   **  Now see if there are any columns with the usertype that
   **  need the new binding.
   */
   if isnull(@futureonly, '') <> @futurevalue
      and exists (select * from syscolumns, systypes
            where syscolumns.usertype = systypes.usertype
               and systypes.name = @objname
               and systypes.usertype > 100
               and systypes.uid = user_id()
               and syscolumns.domain = @oldrule)
   begin
      /*
      **  Update syscolumns with new binding.
      */
      update syscolumns set domain = systypes.domain
         from syscolumns, systypes
         where syscolumns.usertype = systypes.usertype
            and systypes.name = @objname
            and systypes.usertype > 100
            and systypes.uid = user_id()
            and syscolumns.domain = @oldrule

      /*
      **  Update the table schema to indicate that something
      **  has changed in the table's schema.
      */
      update sysobjects set schema_ver = schema_ver + 1
         from sysobjects, syscolumns, systypes
         where sysobjects.id = syscolumns.id
            and syscolumns.usertype = systypes.usertype
            and systypes.name = @objname
            and systypes.usertype > 100
            and systypes.uid = user_id()
            and syscolumns.domain = systypes.domain

      print 'Columns of the user datatype specified had their rules unbound.'
   end
end

return (0)
go



raiserror(15339,-1,-1,'sp_unmakestartup')
go
create procedure sp_unmakestartup
@procname varchar(30) = null
as
declare @objid	int
declare @dbname varchar(30)

/*
**	Check to see if a proc. name was specified.
*/
if @procname is null
	begin
		raiserror(15240,-1,-1)
		return (1)
	end

/*
**  Only the SA can do this.
*/
if suser_id() <> 1
	begin
		raiserror(15003,-1,-1)
		return (1)
	end

/*
**  Make sure the @procname is in the master database.
*/
if @procname like '%.%.%' and	-- Explicit db name supplied
	substring(@procname, 1, charindex('.', @procname) - 1) <> 'master'
	begin
		raiserror(15272,-1,-1,@procname)
		return (1)
	end
else	-- No explicit name supplied so we need to be in the 'master' db
	if db_name() <> 'master'
		begin
			select @dbname = db_name()
			raiserror(15274,-1,-1,@procname,@dbname)
			return(1)
		end

/*
**  Make sure the procedure exists and get its id so we can use
**	a simpler where clause.
*/
select @objid = id from master..sysobjects
	where sysstat & 0xf = 4
	and name = @procname

if @objid is null
	begin
		raiserror(15020,-1,-1,@procname)
		return (1)
	end

/*
**	If we made it to here, set it to no longer be 'startup'.
*/
if (select category & 16 from master..sysobjects where id = @objid) = 16
	begin
		update master..sysobjects set category = category & ~16
			where id = @objid
		print 'Procedure is no longer marked as ''startup''.'
	end
else
	print 'Procedure was not designated as ''startup''.'

return (0)
go



raiserror(15339,-1,-1,'sp_who')
go
create procedure sp_who  --1995/11/28 15:48
       @loginame varchar(30) = NULL --or 'active'
as

declare	 @low		int
	,@high		int
	,@spidlow	int
	,@spidhigh	int

select	 @low		=     0
	,@high		= 32767

select	 @spidlow	=     0
	,@spidhigh	= 32767


if (	@loginame is not NULL
   AND	upper(@loginame) <> 'ACTIVE'
   )
begin
	select @low = suser_id(@loginame), @high = suser_id(@loginame)
	if @low is NULL
	begin
		if @loginame like '[0-9]%'
		begin
			select	@spidlow  = convert(int, @loginame),
				@spidhigh = convert(int, @loginame),
				@low = 0, @high = 32767
		end
		else
		begin
			raiserror(15007,-1,-1,@loginame)
			return (1)
		end
	end
end


if (	@loginame is not NULL
   AND	upper(@loginame) = 'ACTIVE'
   )
	begin

	select spid ,status
              ,loginame=substring(suser_name(suid),1,12)
	      ,hostname ,blk=convert(char(5),blocked)
	      ,dbname=substring(db_name(dbid),1,10),cmd
	from  sysprocesses
	where suid >= @low     and suid <= @high
	and   spid >= @spidlow and spid <= @spidhigh
	AND   upper(cmd) <> 'AWAITING COMMAND'

	end
else
	begin

	select spid ,status
              ,loginame=substring(suser_name(suid),1,12)
	      ,hostname ,blk=convert(char(5),blocked)
	      ,dbname=substring(db_name(dbid),1,10),cmd
	from  sysprocesses
	where suid >= @low     and suid <= @high
	and   spid >= @spidlow and spid <= @spidhigh

	end

return (0)
go



raiserror(15339,-1,-1,'sp_who2')
go
CREATE PROCEDURE sp_who2  --1995/11/03 10:16

    @loginame     varchar(30) = NULL
as

set nocount on

declare
    @retcode         int
   ,@max_suid_spid   int
   ,@int1            int

declare
    @suidlow         int
   ,@suidhigh        int
   ,@spidlow         int
   ,@spidhigh        int

declare
    @charMaxLenLoginName      varchar(6)
   ,@charMaxLenDBName         varchar(6)
   ,@charMaxLenCPUTime        varchar(10)
   ,@charMaxLenDiskIO         varchar(10)
   ,@charMaxLenHostName       varchar(10)
   ,@charMaxLenProgramName    varchar(10)
   ,@charMaxLenLastBatch      varchar(10)
   ,@charMaxLenCommand        varchar(10)

declare
    @charsuidlow              varchar(11)
   ,@charsuidhigh             varchar(11)

   ,@charspidlow              varchar(11)
   ,@charspidhigh             varchar(11)

--------

select
    @retcode         = 0      -- 0=good ,1=bad.
   ,@max_suid_spid   = 32767

--------defaults
select
    @suidlow         = 0
   ,@suidhigh        = @max_suid_spid

   ,@spidlow         = 0
   ,@spidhigh        = @max_suid_spid

--------------------------------------------------------------


IF (@loginame IS     NULL)  --Simple default to all LoginNames.
      GOTO LABEL_17PARM1EDITED

--------

select @int1 = suser_id(@loginame)

IF (@int1 IS NOT NULL)  --Parm is a recognized login name.
   begin
   select @suidlow  = suser_id(@loginame)
         ,@suidhigh = suser_id(@loginame)
   GOTO LABEL_17PARM1EDITED
   end

--------

IF (lower(@loginame) IN ('active'))  --Special action, not sleeping.
   begin
   select @loginame = lower(@loginame)
   GOTO LABEL_17PARM1EDITED
   end

--------

IF (patindex ('%[^0-9]%' , isnull(@loginame,'z')) = 0)  --Is a number.
   begin
   select
             @spidlow   = convert(int, @loginame)
            ,@spidhigh  = convert(int, @loginame)
   GOTO LABEL_17PARM1EDITED
   end

--------

RaisError(15007,-1,-1,@loginame)
select @retcode = 1
GOTO LABEL_86RETURN


LABEL_17PARM1EDITED:


--------------------  Capture consistent sysprocesses.  -------------------

SELECT

  spid
 ,kpid
 ,status
 ,suid
 ,hostname
 ,program_name
 ,hostprocess
 ,cmd
 ,cpu
 ,physical_io
 ,memusage
 ,blocked
 ,waittype
 ,dbid
 ,uid
 ,gid
 ,login_time
 ,last_batch
 ,nt_domain
 ,nt_username
 ,net_address
 ,net_library

 ,spid as 'spid_sort'

 ,  substring( convert(varchar,last_batch,111) ,6  ,5 ) + ' '
  + substring( convert(varchar,last_batch,113) ,13 ,8 )
       as 'last_batch_char'

      INTO    #tb1_sysprocesses
      from master..sysprocesses   (nolock)



--------Screen out any rows?

IF (@loginame IN ('active'))
   DELETE #tb1_sysprocesses
         where   lower(status)  = 'sleeping'
         and     upper(cmd)    IN (
                     'AWAITING COMMAND'
                    ,'MIRROR HANDLER'
                    ,'LAZY WRITER'
                    ,'CHECKPOINT SLEEP'
                    ,'RA MANAGER'
                                  )

         and     blocked       = 0



--------Prepare to dynamically optimize column widths.


Select
    @charsuidlow     = convert(varchar,@suidlow)
   ,@charsuidhigh    = convert(varchar,@suidhigh)
   ,@charspidlow     = convert(varchar,@spidlow)
   ,@charspidhigh    = convert(varchar,@spidhigh)



SELECT
             @charMaxLenLoginName =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,suser_name(suid)))) ,5)
                         )

            ,@charMaxLenDBName    =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,db_name(dbid)))) ,6)
                         )

            ,@charMaxLenCPUTime   =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,cpu))) ,7)
                         )

            ,@charMaxLenDiskIO    =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,physical_io))) ,6)
                         )

            ,@charMaxLenCommand  =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,cmd))) ,7)
                         )

            ,@charMaxLenHostName  =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,hostname))) ,8)
                         )

            ,@charMaxLenProgramName =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,program_name))) ,11)
                         )

            ,@charMaxLenLastBatch =
                  convert( varchar
                          ,isnull( max( datalength( convert(varchar,last_batch_char))) ,9)
                         )
      from
             #tb1_sysprocesses
      where
             suid >= @suidlow
      and    suid <= @suidhigh
      and
             spid >= @spidlow
      and    spid <= @spidhigh



--------Output the report.


EXECUTE(
'
SET nocount off

SELECT
             SPID          = convert(char(5),spid)

            ,Status        =
                  CASE lower(status)
                     When ''sleeping'' Then lower(status)
                     Else                   upper(status)
                  END

            ,Login         = substring(suser_name(suid),1,' + @charMaxLenLoginName + ')

            ,HostName      =
                  CASE hostname
                     When Null  Then ''  .''
                     When '' '' Then ''  .''
                     Else    substring(hostname,1,' + @charMaxLenHostName + ')
                  END

            ,BlkBy         =
                  CASE               isnull(convert(char(5),blocked),''0'')
                     When ''0'' Then ''  .''
                     Else            isnull(convert(char(5),blocked),''0'')
                  END

            ,DBName        = substring(db_name(dbid),1,' + @charMaxLenDBName + ')
            ,Command       = substring(cmd,1,' + @charMaxLenCommand + ')

            ,CPUTime       = substring(convert(varchar,cpu),1,' + @charMaxLenCPUTime + ')
            ,DiskIO        = substring(convert(varchar,physical_io),1,' + @charMaxLenDiskIO + ')

            ,LastBatch     = substring(last_batch_char,1,' + @charMaxLenLastBatch + ')

            ,ProgramName   = substring(program_name,1,' + @charMaxLenProgramName + ')
            ,SPID          = convert(char(5),spid)  --Handy extra for right-scrolling users.
      from
             #tb1_sysprocesses  --Usually DB qualification is needed in exec().
      where
             suid >= ' + @charsuidlow  + '
      and    suid <= ' + @charsuidhigh + '
      and
             spid >= ' + @charspidlow  + '
      and    spid <= ' + @charspidhigh + '

      -- (Seems always auto sorted.)   order by spid_sort

SET nocount on
'
)



LABEL_86RETURN:


if (object_id('tempdb..#tb1_sysprocesses') is not null)
            drop table #tb1_sysprocesses

return @retcode
go


---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------


/*
** Create following procs last, since they reference other procedures.
*/



raiserror(15339,-1,-1,'sp_check_removable')
go
create procedure sp_check_removable @autofix varchar(4)
as

declare @dbouid int
declare @dbname varchar(30)
declare @logdev varchar(30)

select @dbname=db_name()
	
/* Verify that SA owns the database. */

select @dbouid = suid from sysdatabases where name = @dbname
if @dbouid <> 1
	if @autofix='auto'
		begin
			print 'Setting db owner to SA.'
			update sysdatabases set suid = 1
				where name = @dbname
			update sysusers set suid = 1
				where uid = 1
		end
	else
		begin
			raiserror(15258,-1,-1)
			return(1)
		end

/* Check for any objects not owned by dbo. */
if exists (select * from sysobjects where uid <> 1)

	if @autofix='auto'
		begin
			print 'Giving ownership of all objects to dbo.'
			update sysobjects set uid = 1
		end
	else
		begin
			raiserror(15053,-1,-1)
			return(1)
		end

/* See if any non-dbo/guest users exist in db */
if exists (select * from sysusers where uid between 3 and 16382)
	if @autofix='auto'
		begin
			print 'Deleting non guest/dbo users from ''sysusers''.'
			delete from sysusers where uid between 3 and 16382
			delete from sysprotects where uid not in
				(select uid from sysusers)
			delete from sysalternates where altsuid not in
				(select suid from sysusers)
		end
	else
		begin
			raiserror(15254,-1,-1)
			return(1)
		end

/* If we made it to here, move the log segment to the system segment. */
update sysusages set segmap = 5 where dbid = db_id(@dbname) and segmap = 1
dbcc dbrepair (@dbname,remap) with no_infomsgs

/* Save the old log device's name and unmap the log segment from it. */
select @logdev = v.name from sysusages u,sysdevices v
	where u.dbid = db_id(@dbname)
		and u.segmap = 4
		and u.vstart = low

update sysusages set segmap = 0
	where dbid = db_id(@dbname) and segmap = 4
dbcc dbrepair (@dbname,remap) with no_infomsgs

/* Force first log page onto new device. */
while exists
	(select * from sysindexes where name = 'syslogs' and root not between
		(select lstart from sysusages
			where dbid = db_id(@dbname) and segmap = 5)
		and
		(select lstart+size-1 from sysusages
		 where dbid = db_id(@dbname) and segmap = 5))
or exists
	(select * from sysindexes where name = 'syslogs' and first not between
		(select lstart from sysusages
			where dbid = db_id(@dbname) and segmap = 5)
		and
		(select lstart+size-1 from sysusages
			where dbid = db_id(@dbname) and segmap = 5))

	begin
		update sysobjects set name = name	-- no_op to generate
							-- log activity

		exec('dump tran '+@dbname+' with no_log')
	end

/* Delete the old log segment and drop its device. */

delete from sysusages where dbid = db_id(@dbname) and segmap = 0
dbcc dbrepair (@dbname,remap) with no_infomsgs

exec sp_dropdevice @logdev
return(0)
go



raiserror(15339,-1,-1,'sp_certify_removable')
go
CREATE PROCEDURE sp_certify_removable  --1996/03/12 12:02

        @dbname varchar(30) = null,
        @autofix varchar(4) = null
as

set nocount on

declare @ret_value int,
        @vc1 varchar(255),
        @SQLPath varchar(255),
        @OneMb int,
        @countloop1 int,
	@char_autofix varchar(25)

declare
       @cu1PKSequence      int
      ,@cu1DeviceName      varchar( 30)
      ,@cu1SegmentType     varchar( 12)
      ,@cu1FragmentSizeMb  int
      ,@cu1DeviceFileName  varchar(127)


select  @OneMb = 1048576


if suser_id() <> 1      -- Make sure that it is the SA executing this.
        begin
                raiserror(15003,-1,-1)
                return(1)
        end


select @autofix = lower(@autofix)

if @autofix <> 'auto' and @autofix is not null
        begin
                raiserror(15255,-1,-1,@autofix)
                return(1)
        end


if @dbname is null      -- Show usage diagram if no dbname supplied.
        begin
                raiserror(15256,-1,-1)
                return(1)
        end


--See if DB exists.
if not exists (select * from sysdatabases where name = @dbname)
        begin
                raiserror(15010,-1,-1,@dbname)
                return(1)
        end


--Cannot take master, tempdb or model databases offline.
if lower(@dbname) in ('master','tempdb','model')
        begin
                raiserror(15266,-1,-1,@dbname)
                return(1)
        end


-- Will not be able to take db offline if user is in it.
if @dbname = db_name()
        begin
                raiserror(15257,-1,-1)
                return(1)
        end


------------------  validate fragment continuity  -----------------


--Coalesce any contiguous device fragments for this database.
exec sp_coalesce_fragments @dbname


--Verify that two or more noncontiguous fragments do not exist on any
--   device for the database.
if exists (select * from sysusages u1,sysdevices v
                where u1.dbid = db_id(@dbname)
                and u1.vstart between v.low and v.high
                and exists (
                            select * from sysusages u2
                                where u2.dbid=u1.dbid
                                and u2.vstart between v.low and v.high
                                and u2.vstart <> u1.vstart
                           )
          )
        begin
                raiserror(15260,-1,-1)
                return(1)
        end


--Verify that the database spans at least 3 devices (system, data and
--   log) and that segment mappings are proper.
if
        (select count(*) from sysusages where dbid = db_id(@dbname)
                and segmap = 1) <> 1    -- dedicated system device
        or (select count(*) from sysusages where dbid = db_id(@dbname)
                and segmap = 4) <> 1    -- dedicated log device
        or (select count(*) from sysusages where dbid = db_id(@dbname)
                and segmap = 2) < 1     -- dedicated data device

                begin
                        raiserror(15259,-1,-1)
                        return(1)
                end


-------------------  Ensure IRL not On for any user-tables

EXECUTE(  --13677
'
use ' +@dbname+ '

if (0 < (select count(*) from sysobjects where type=''U '' and userstat & 1 > 0))
   exec sp_tableoption ''%.%'' ,''insert row lock'' ,''false''
')


-------------  Check things that exist only in the db.  -------------------


select @char_autofix =
	CASE
	   When @autofix IS NOT Null Then '''Auto'''
	   Else                           'Null'
	END


execute(
'
use ' + @dbname + '

declare @inx_ret_value int ,@int1 int
select  @inx_ret_value = 1

exec @inx_ret_value = sp_check_removable ' + @char_autofix + '

--Use @@rowcount for a user_assignable global variable for communication.
if @inx_ret_value <> 0	--bad
	begin
	select @int1 = suid from master.dbo.syslogins where suid=1 --SA
	return
	end
else
	begin
	select @int1 = suid from master.dbo.syslogins where suid=1 and 1=2
	return
	end
'
)

if @@rowcount > 0
        return (1)  --Error was returned by other proc, so exit


-------------------  report on the db devices  ----------------------


raiserror('',0,1)
raiserror(15309,-1,-1)  --"Please write down this crucial info."
raiserror('' ,0,1)


create table #tb1_ForDBInstall
   (
    PKSequence          int            not null    identity(1,1)
   ,UG_LStart           int            not null
   ,DeviceName          varchar(30)        null
   ,SegmentType         varchar(12)        null
   ,FragmentSizeMb      int                null
   ,DeviceFileName      varchar(127)       null
   )



insert
      into #tb1_ForDBInstall
         (
          -- PKSequence,
          UG_LStart
         ,DeviceName
         ,SegmentType
         ,FragmentSizeMb
         ,DeviceFileName
         )
   select
             -- identitycol,
             u.lstart
            ,v.name

            ,case u.segmap
                when 5 then 'System + Log'
                when 2 then 'Data'
             end

            ,convert( int
                     ,round( (
                (select low
                   from master.dbo.spt_values
                   where type = 'E' and number = 1
                )
                     * convert(float, u.size)
                             ) / @OneMb
                          ,0
                           )
                    )

            ,phyname
   from
             sysdevices    v
            ,sysusages     u
   where
             u.dbid   = db_id(@dbname)
   and       u.vstart = v.low
   order by
             lstart



select
             'Sequence'    = convert(char(8),PKSequence)
            ,DeviceName
            ,SegmentType
            ,FragmentSizeMb
            ,DeviceFileName
      from
             #tb1_ForDBInstall
      order by
             UG_LStart ,PKSequence  --Should match plain PKSequence.

raiserror('',0,1) with nowait


------------  Make a ReadMe style file named Log\CertifyR_<dbname>.TXT  ------

exec master..xp_regread
       'HKEY_LOCAL_MACHINE'
      ,'SOFTWARE\Microsoft\MSSQLServer\Setup'
      ,'SQLPath'
            ,@SQLPath   OUTPUT  --example:  C:\SQL60  (missing trailing \ )

select @SQLPath = rtrim(@SQLPath) + '\Log\CertifyR_' + rtrim(@dbname) + '.TXT'



--Prime the TXT file.
select @vc1 = 'echo --sp_certify_removable, db='
            + rtrim(@dbname) + ',  ' + convert(varchar,getdate(),113)
               + '  >' + rtrim(@SQLPath)
exec master..xp_cmdshell @vc1 , 'no_output'


select @vc1 =
    'echo --Sequence,DeviceName,SegmentType,FragmentSizeMb,DeviceFileName'
               + ' >>' + rtrim(@SQLPath)
exec master..xp_cmdshell @vc1 , 'no_output'



--Loop thru temp #table rows.
declare cursor1_tb1
   insensitive
   cursor for
select
       PKSequence
      ,DeviceName
      ,SegmentType
      ,FragmentSizeMb
      ,DeviceFileName
   from
       #tb1_ForDBInstall
   order by
       PKSequence


open cursor1_tb1

select @countloop1 = 0


-----------------------
while (     1=1
      and   @@error = 0
      )
   begin

   fetch     next
      from   cursor1_tb1
      into
             @cu1PKSequence
            ,@cu1DeviceName
            ,@cu1SegmentType
            ,@cu1FragmentSizeMb
            ,@cu1DeviceFileName

   if (@@fetch_status <> 0)
      begin
      deallocate cursor1_tb1
      break
      end

   select @countloop1 = @countloop1 + 1


   select @vc1 = 'echo '

               + convert(varchar ,@cu1PKSequence)
         + ',' +                  @cu1DeviceName
         + ',' +                  @cu1SegmentType
         + ',' + convert(varchar ,@cu1FragmentSizeMb)
         + ',' +                  @cu1DeviceFileName

               + ' >>' + rtrim(@SQLPath)


   exec master..xp_cmdshell @vc1 ,'no_output'

   end --loop 1



select @vc1 = convert(varchar,@countloop1)
            + ' noncomment records were written to LOG\CertifyR*.TXT file.'

raiserror(15310,-1,-1 ,@countloop1)

-- - - -

select @vc1 = 'echo --' + @vc1
               + ' >>' + rtrim(@SQLPath)
exec master..xp_cmdshell @vc1 , 'no_output'


if object_id('tempdb..#tb1_ForDBInstall') is null
           drop table #tb1_ForDBInstall


raiserror('' ,0,1)
exec sp_dboption @dbname,'offline','true'

return(0)
go



select count(*) ,'= the number of system stored procs in master..sysobjects'
	from sysobjects where type='P ' and name like 'sp[_]%'

go

---------------------------------------------------------------
raiserror('Now done creating the general system stored procs.  Start with miscellaneous tasks like xp_ and grants.',0,1)
---------------------------------------------------------------
go

/*
** Drop extended procs. if they already exist now that sp_dropextendedproc
** has been created.
*/

print ''
print 'Dropping any existing extended stored procedures.'
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_addattach')
	exec sp_dropextendedproc 'xp_addattach'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_addmsgline')
	exec sp_dropextendedproc 'xp_addmsgline'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_cmdshell')
	exec sp_dropextendedproc 'xp_cmdshell'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cursor')
	exec sp_dropextendedproc 'sp_cursor'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cursorclose')
	exec sp_dropextendedproc 'sp_cursorclose'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cursorfetch')
	exec sp_dropextendedproc 'sp_cursorfetch'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cursoropen')
	exec sp_dropextendedproc 'sp_cursoropen'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cursoroption')
	exec sp_dropextendedproc 'sp_cursoroption'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_deletemail')
	exec sp_dropextendedproc 'xp_deletemail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_enumgroups')
	exec sp_dropextendedproc 'xp_enumgroups'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_findnextmsg')
	exec sp_dropextendedproc 'xp_findnextmsg'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_grantlogin')
	exec sp_dropextendedproc 'xp_grantlogin'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_logevent')
	exec sp_dropextendedproc 'xp_logevent'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_loginconfig')
	exec sp_dropextendedproc 'xp_loginconfig'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_logininfo')
	exec sp_dropextendedproc 'xp_logininfo'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_loginmail')
	exec sp_dropextendedproc 'xp_loginmail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_logoffmail')
	exec sp_dropextendedproc 'xp_logoffmail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_mailproclist')
	exec sp_dropextendedproc 'xp_mailproclist'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_msver')
	exec sp_dropextendedproc 'xp_msver'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_prepmsg')
	exec sp_dropextendedproc 'xp_prepmsg'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_readmail')
	exec sp_dropextendedproc 'xp_readmail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_revokelogin')
	exec sp_dropextendedproc 'xp_revokelogin'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_sendmail')
	exec sp_dropextendedproc 'xp_sendmail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_sendmsg')
	exec sp_dropextendedproc 'xp_sendmsg'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_sprintf')
	exec sp_dropextendedproc 'xp_sprintf'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_sscanf')
	exec sp_dropextendedproc 'xp_sscanf'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_startmail')
	exec sp_dropextendedproc 'xp_startmail'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_stopmail')
	exec sp_dropextendedproc 'xp_stopmail'
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'xp_unc_to_drive')
	exec sp_dropextendedproc 'xp_unc_to_drive'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_bindsession')
	exec sp_dropextendedproc 'sp_bindsession'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_getbindtoken')
	exec sp_dropextendedproc 'sp_getbindtoken'

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_sdidebug')
	exec sp_dropextendedproc 'sp_sdidebug'
go

-- Add extended stored procedures.
print ''
print 'Adding extended stored procedures.'
go

sp_addextendedproc 'xp_cmdshell','xpsql60.dll'
go

sp_addextendedproc 'xp_logevent','xpsql60.dll'
go

sp_addextendedproc 'xp_sprintf','xpsql60.dll'
go

sp_addextendedproc 'xp_sscanf','xpsql60.dll'
go

sp_addextendedproc 'xp_unc_to_drive','xpsql60.dll'
go

sp_addextendedproc 'xp_msver','xpsql60.dll'
go

sp_addextendedproc 'xp_enumgroups','xplog60.dll'
go

-- Add mail enabling extended procedures
--
sp_addextendedproc 'xp_startmail', 'sqlmap60.dll'
go
sp_addextendedproc 'xp_stopmail', 'sqlmap60.dll'
go
sp_addextendedproc 'xp_sendmail', 'sqlmap60.dll'
go
sp_addextendedproc 'xp_deletemail', 'sqlmap60.dll'
go
sp_addextendedproc 'xp_findnextmsg', 'sqlmap60.dll'
go
sp_addextendedproc 'xp_readmail', 'sqlmap60.dll'
go

--Add extended stored procedures for NT integrated login security.
--
sp_addextendedproc 'xp_loginconfig', 'xplog60.dll'
go
sp_addextendedproc 'xp_logininfo', 'xplog60.dll'
go
sp_addextendedproc 'xp_revokelogin', 'xplog60.dll'
go
sp_addextendedproc 'xp_grantlogin', 'xplog60.dll'
go

-- Add extended stored procedures for cursor support.
--
sp_addextendedproc  'sp_cursor', '(server internal)'
go
sp_addextendedproc  'sp_cursorclose', '(server internal)'
go
sp_addextendedproc  'sp_cursorfetch', '(server internal)'
go
sp_addextendedproc  'sp_cursoropen', '(server internal)'
go
sp_addextendedproc  'sp_cursoroption', '(server internal)'
go

-- Add extended stored procedures for bound session support.
--
sp_addextendedproc  'sp_bindsession', '(server internal)'
go
sp_addextendedproc  'sp_getbindtoken', '(server internal)'
go

-- This xproc will be used for SQL debugging and will be invoked either via RPC or SQL language.
--
exec sp_addextendedproc 'sp_sdidebug', '(server internal)'
go


print ''
raiserror(15339,-1,-1,'MS_sqlctrs_users')
go
create procedure MS_sqlctrs_users
as
select syslogins.name+' - '+convert(varchar(30),
		sysprocesses.spid), memusage 'Memory (2K Pages)',
		cpu 'CPU time', physical_io,
		count(syslocks.spid) 'Locks held',sysprocesses.spid
from sysprocesses, syslocks, syslogins where sysprocesses.spid *= syslocks.spid and sysprocesses.suid=syslogins.suid
group by syslogins.name,sysprocesses.spid,memusage,cpu,physical_io
go

/*
**  Add the login and user named 'probe'.  These are used for the
**  2-phased commit service.
*/
if not exists (select * from syslogins where name = 'probe')
	exec sp_addlogin 'probe'
go

if not exists (select * from sysusers where name = 'probe')
	exec sp_adduser 'probe'
go

print ''
print 'Dropping keys'
print ''
go

/*
** Drop 'old-style' common keys.
*/
if exists (select * from syskeys where type = 3 and id = object_id('syscolumns')
		and depid = object_id('syscomments'))
	execute sp_dropkey common, syscolumns, syscomments
go
if exists (select * from syskeys where type = 3 and id = object_id('syscolumns')
		and depid = object_id('syskeys'))
	execute sp_dropkey common, syscolumns, syskeys
go
if exists (select * from syskeys where type = 3 and id = object_id('syscolumns')
		and depid = object_id('sysobjects'))
	execute sp_dropkey common, syscolumns, sysobjects
go
if exists (select * from syskeys where type = 3 and id = object_id('syscolumns')
		and depid = object_id('systypes'))
	execute sp_dropkey common, syscolumns, systypes
go
if exists (select * from syskeys where type = 3 and id = object_id('syscomments')
		and depid = object_id('sysobjects'))
	execute sp_dropkey common, syscomments, sysobjects
go
if exists (select * from syskeys where type = 3 and id = object_id('sysdepends')
		and depid = object_id('sysobjects'))
	execute sp_dropkey common, sysdepends, sysobjects
go
if exists (select * from syskeys where type = 3 and id = object_id('sysindexes')
		and depid = object_id('sysobjects'))
	execute sp_dropkey common, sysindexes, sysobjects
go
if exists (select * from syskeys where type = 3 and id = object_id('sysindexes')
		and depid = object_id('syssegments'))
	execute sp_dropkey common, sysindexes, syssegments
go
if exists (select * from syskeys where type = 3 and id = object_id('syskeys')
		and depid = object_id('sysobjects'))
	execute sp_dropkey common, syskeys, sysobjects
go
if exists (select * from syskeys where type = 3 and id = object_id('sysobjects')
		and depid = object_id('sysprocedures'))
	execute sp_dropkey common, sysobjects, sysprocedures
go
if exists (select * from syskeys where type = 3 and id = object_id('sysobjects')
		and depid = object_id('sysprotects'))
	execute sp_dropkey common, sysobjects, sysprotects
go
if exists (select * from syskeys where type = 3 and id = object_id('sysobjects')
		and depid = object_id('sysusers'))
	execute sp_dropkey common, sysobjects, sysusers
go
if exists (select * from syskeys where type = 3 and id = object_id('sysprotects')
		and depid = object_id('sysusers'))
	execute sp_dropkey common, sysprotects, sysusers
go
if exists (select * from syskeys where type = 3 and id = object_id('systypes')
		and depid = object_id('sysusers'))
	execute sp_dropkey common, systypes, sysusers
go
if exists (select * from syskeys where type = 3 and id = object_id('syscurconfigs')
		and depid = object_id('sysconfigures'))
	execute sp_dropkey common, syscurconfigs, sysconfigures
go
if exists (select * from syskeys where type = 3 and id = object_id('sysdatabases')
		and depid = object_id('syslocks'))
	execute sp_dropkey common, sysdatabases, syslocks
go
if exists (select * from syskeys where type = 3 and id = object_id('sysdatabases')
		and depid = object_id('syslogins'))
	execute sp_dropkey common, sysdatabases, syslogins
go
if exists (select * from syskeys where type = 3 and id = object_id('sysdatabases')
		and depid = object_id('sysprocesses'))
  	execute sp_dropkey common, sysdatabases, sysprocesses
go
if exists (select * from syskeys where type = 3 and id = object_id('sysdatabases')
		and depid = object_id('sysusages'))
	execute sp_dropkey common, sysdatabases, sysusages
go
if exists (select * from syskeys where type = 3 and id = object_id('syslocks')
		and depid = object_id('sysprocesses'))
	execute sp_dropkey common, syslocks, sysprocesses
go
if exists (select * from syskeys where type = 3 and id = object_id('syslogins')
		and depid = object_id('sysprocesses'))
	execute sp_dropkey common, syslogins, sysprocesses
go
if exists (select * from syskeys where type = 3 and id = object_id('sysservers')
		and depid = object_id('sysremotelogins'))
	execute sp_dropkey common, sysservers, sysremotelogins
go
if exists (select * from syskeys where type = 3 and id = object_id('sysremotelogins')
		and depid = object_id('sysusers'))
	execute sp_dropkey common, sysremotelogins, sysusers
go

/*
** Drop 'old-style' foreign keys.
*/
if exists (select * from syskeys where type = 2 and id = object_id('sysalternates')
		and depid = object_id('sysusers'))
	execute sp_dropkey 'foreign', sysalternates, sysusers
go
if exists (select * from syskeys where type = 2 and id = object_id('syskeys')
		and depid = object_id('sysobjects'))
	execute sp_dropkey 'foreign', syskeys, sysobjects
go

/*
** Drop 'old-style' primary keys.
*/
if exists (select * from syskeys where type = 1 and id = object_id('sysalternates'))
	execute sp_dropkey 'primary', sysalternates
go
if exists (select * from syskeys where type = 1 and id = object_id('syscolumns'))
	execute sp_dropkey 'primary', syscolumns
go
if exists (select * from syskeys where type = 1 and id = object_id('syscomments'))
	execute sp_dropkey 'primary', syscomments
go
if exists (select * from syskeys where type = 1 and id = object_id('sysconfigures'))
	execute sp_dropkey 'primary', sysconfigures
go
if exists (select * from syskeys where type = 1 and id = object_id('sysdatabases'))
	execute sp_dropkey 'primary', sysdatabases
go
if exists (select * from syskeys where type = 1 and id = object_id('sysdepends'))
	execute sp_dropkey 'primary', sysdepends
go
if exists (select * from syskeys where type = 1 and id = object_id('sysdevices'))
	execute sp_dropkey 'primary', sysdevices
go
if exists (select * from syskeys where type = 1 and id = object_id('sysindexes'))
	execute sp_dropkey 'primary', sysindexes
go
if exists (select * from syskeys where type = 1 and id = object_id('syskeys'))
	execute sp_dropkey 'primary', syskeys
go
if exists (select * from syskeys where type = 1 and id = object_id('syslogins'))
	execute sp_dropkey 'primary', syslogins
go
if exists (select * from syskeys where type = 1 and id = object_id('sysmessages'))
	execute sp_dropkey 'primary', sysmessages
go
if exists (select * from syskeys where type = 1 and id = object_id('sysobjects'))
	execute sp_dropkey 'primary', sysobjects
go
if exists (select * from syskeys where type = 1 and id = object_id('sysprocedures'))
	execute sp_dropkey 'primary', sysprocedures
go
if exists (select * from syskeys where type = 1 and id = object_id('sysremotelogins'))
	execute sp_dropkey 'primary', sysremotelogins
go
if exists (select * from syskeys where type = 1 and id = object_id('sysprotects'))
	execute sp_dropkey 'primary', sysprotects
go
if exists (select * from syskeys where type = 1 and id = object_id('syssegments'))
	execute sp_dropkey 'primary', syssegments
go
if exists (select * from syskeys where type = 1 and id = object_id('sysservers'))
	execute sp_dropkey 'primary', sysservers
go
if exists (select * from syskeys where type = 1 and id = object_id('systypes'))
	execute sp_dropkey 'primary', systypes
go
if exists (select * from syskeys where type = 1 and id = object_id('sysusers'))
	execute sp_dropkey 'primary', sysusers
go
if exists (select * from syskeys where type = 1 and id = object_id('sysusages'))
	execute sp_dropkey 'primary', sysusages
go

print ''
print 'Granting privileges on system tables.'
go

grant select on sysalternates to public
grant select on syscharsets to public
grant select on syscolumns to public
grant select on syscomments to public
grant select on sysconfigures to public
grant select on syscurconfigs to public
grant select on sysdatabases to public
grant select on sysdepends to public
grant select on sysdevices to public
grant select on sysindexes to public
grant select on syskeys to public
grant select on syslanguages to public
grant select on syslocks to public
go
grant select on syslogins to public
revoke select (password) on syslogins from public
go
grant select on syslogs to public
grant select on sysmessages to public
grant select on sysobjects to public
grant select on sysprocedures to public
grant select on sysprocesses to public
grant select on sysprotects to public
grant select on sysremotelogins to public
grant select on syssegments to public
grant select on sysservers to public
grant select on systypes to public
grant select on sysusages to public
grant select on sysusers to public
go

print ''
print 'Granting privileges on system stored procedures'
go

grant execute on MS_sqlctrs_users to public
go

grant execute on sp_user_counter1   to probe
grant execute on sp_user_counter2   to probe
grant execute on sp_user_counter3   to probe
grant execute on sp_user_counter4   to probe
grant execute on sp_user_counter5   to probe
grant execute on sp_user_counter6   to probe
grant execute on sp_user_counter7   to probe
grant execute on sp_user_counter8   to probe
grant execute on sp_user_counter9   to probe
grant execute on sp_user_counter10  to probe
grant execute on sp_userdefcounters to probe
go

grant execute on sp_a_count_bits_on to public
grant execute on sp_abort_xact to public
grant execute on sp_addalias to public
grant execute on sp_addgroup to public
grant execute on sp_addmessage to public
grant execute on sp_addsegment to public
grant execute on sp_addtype to public
grant execute on sp_adduser to public
grant execute on sp_altermessage to public
grant execute on sp_bindefault to public
grant execute on sp_bindrule to public
grant execute on sp_change_users_login to public
grant execute on sp_changegroup to public
grant execute on sp_checknames to public
grant execute on sp_coalesce_fragments to public
grant execute on sp_commit_xact to public
grant execute on sp_commonkey to public
grant execute on sp_configure to public
grant execute on sp_cursor to public
grant execute on sp_cursorclose to public
grant execute on sp_cursorfetch to public
grant execute on sp_cursoropen to public
grant execute on sp_cursoroption to public
grant execute on sp_dboption to public
grant execute on sp_bindsession to public
grant execute on sp_getbindtoken to public
go
grant execute on sp_defaultdb to public
grant execute on sp_defaultlanguage to public
grant execute on sp_depends to public
grant execute on sp_devoption to public
grant execute on sp_dropalias to public
grant execute on sp_dropgroup to public
grant execute on sp_dropkey to public
grant execute on sp_dropmessage to public
grant execute on sp_dropsegment to public
grant execute on sp_droptype to public
grant execute on sp_dropuser to public
grant execute on sp_extendsegment to public
go
grant execute on sp_fallback_activate_svr       to public
grant execute on sp_fallback_activate_svr_db   to public
grant execute on sp_fallback_deactivate_svr     to public
grant execute on sp_fallback_deactivate_svr_db to public
grant execute on sp_fallback_enroll_svr_db     to public
grant execute on sp_fallback_help               to public
grant execute on sp_fallback_help_db_dev        to public
grant execute on sp_fallback_MS_enroll_db      to public
grant execute on sp_fallback_MS_enroll_dev      to public
grant execute on sp_fallback_MS_enroll_usg      to public
grant execute on sp_fallback_MS_sel_fb_svr      to public
grant execute on sp_fallback_MS_verify_ri       to public
grant execute on sp_fallback_permanent_svr      to public
grant execute on sp_fallback_upd_dev_drive      to public
grant execute on sp_fallback_withdraw_svr_db   to public
go
grant execute on sp_help to public
grant execute on sp_help_revdatabase to public
grant execute on sp_helpconstraint to public
grant execute on sp_helpdb to public
grant execute on sp_helpdevice to public
grant execute on sp_helpextendedproc to public
grant execute on sp_foreignkey to public
grant execute on sp_helpgroup to public
grant execute on sp_helpindex to public
grant execute on sp_helpjoins to public
grant execute on sp_helpkey to public
grant execute on sp_helplanguage to public
grant execute on sp_helplog to public
grant execute on sp_helplogins to public
grant execute on sp_helpremotelogin to public
grant execute on sp_helprotect to public
grant execute on sp_helpsegment to public
grant execute on sp_helpserver to public
grant execute on sp_helpsort to public
grant execute on sp_helptext to public
grant execute on sp_helpuser to public
grant execute on sp_lock to public
grant execute on sp_lock2 to public
grant execute on sp_lockinfo to public
grant execute on sp_logdevice to public
grant execute on sp_lookup to public
grant execute on sp_markreport to public
grant execute on sp_namecrack to public
grant execute on sp_namecrack2 to public
grant execute on sp_namecrack3 to public
go
grant execute on sp_objectsegment to public
grant execute on sp_password to public
grant execute on sp_placeobject to public
grant execute on sp_primarykey to public
grant execute on sp_processinfo to public
grant execute on sp_probe_xact to public
grant execute on sp_recompile to public
grant execute on sp_remoteoption to public
grant execute on sp_remove_xact to public
grant execute on sp_rename to public
grant execute on sp_scan_xact to public
grant execute on sp_serveroption to public
grant execute on sp_spaceused to public
grant execute on sp_sqlexec to public
grant execute on sp_start_xact to public
grant execute on sp_stat_xact to public
go

grant execute on sp_blockcnt to probe
grant execute on sp_tableoption to public
grant execute on sp_tempdbspace to probe  --Not designed for public use.
go

grant execute on sp_unbindefault to public
grant execute on sp_unbindrule to public
grant execute on sp_validname to public
grant execute on sp_validlang to public
grant execute on sp_who to public
grant execute on sp_who2 to public
go

print ''
print 'Granting privileges on extended stored procedures'
go

grant execute on xp_regread to probe  --Not documented, so not to public.
go

grant execute on xp_sprintf to public
grant execute on xp_sscanf to public
grant execute on xp_unc_to_drive to public
grant execute on xp_msver to public
go

print ''
print 'Granting privileges on objects in model database.'
go
use model
go
grant select on sysalternates to public
grant select on syscolumns to public
grant select on syscomments to public
grant select on sysconstraints to public
grant select on sysdepends to public
grant select on sysindexes to public
grant select on syskeys to public
grant select on sysobjects to public
grant select on sysprocedures to public
grant select on sysprotects to public
grant select on syssegments to public
grant select on systypes to public
grant select on sysusers to public
grant select on syslogs to public
go

use master
go

/*
** Grant privileges on SQL 6.0 system tables that exist in all databases.
*/

declare @dbname sysname
declare db_name_cursor cursor for select name from sysdatabases
open db_name_cursor
fetch db_name_cursor into @dbname

while @@fetch_status >= 0
	begin

	exec ('use ' + @dbname
		+ ' grant select on sysarticles      to public'
		+ ' grant select on sysconstraints   to public'
		+ ' grant select on syspublications  to public'
		+ ' grant select on sysreferences    to public'
		+ ' grant select on syssubscriptions to public'
	     )

	fetch db_name_cursor into @dbname

	end

deallocate db_name_cursor
go


use master
go

/*
** Set some things now that sp_configure has been created.
*/
go
print ''
print 'Making final database configuration settings.'
go

/********  sdf

raiserror('If this is a new install, shrink size of model db (helps floppy RemovableMedia).',0,1)
--go

********/

declare @i varchar(255)

exec master..xp_regread 'HKEY_LOCAL_MACHINE',
	 'SOFTWARE\Microsoft\MSSQLServer\Setup', 'SetupStatus',
	  @i out

print ''

if isnull(lower(@i),'null') not in ('upgrade','installed')	-- That key will only exist during an upgrade.
	begin -- NewInstall
		select 'Will leave database size config=111 alone at',value from sysconfigures where config=111

--		print 'Setting default database size to 1 Meg.'
--		exec sp_configure 'database size',1
	end
else
		begin
			select 'Re-Initializing free buffer setting, from....',value from sysconfigures where config=1515
			update sysconfigures set value =
				(select value/20 from sysconfigures
					where config = 104)
				where config = 1515
		end
go
print 'Forcing config for remote access to 1'
exec sp_configure 'remote access',1
go

-- Unnecessary in 6.5  --->  exec sp_check_objects 'general'

exec sp_MS_upd_sysobj_category 2  --Now do catalog updates.

go

sp_configure 'allow updates',0
go
sp_dboption 'master','trunc. log on chkpt.','true'
go
reconfigure with override
go

print ''
-- print 'Checking objects created by ProcSyst.SQL ....'
go

declare @vdt varchar(99)
select  @vdt = convert(varchar,getdate(),113)
raiserror('Finishing Install\ProcSyst.SQL at  %s',0,1,@vdt)
go

dump transaction master with no_log
go
checkpoint
go
-- - -----

