
/*
** ProcSyst.CQL		1996/03/26 16:54
**
** (From old InstProc.SQL.  See also Configur.SQL.  See also ProcSyst.HR.)
** (qtoken.exe combines .CQL & .HR to output .SQL)
**
** Copyright Microsoft, Inc. 1994, 1995, 1996
** All Rights Reserved.
** Use, duplication, or disclosure by the United States Government
** is subject to restrictions as set forth in subdivision (c) (1) (ii)
** of the Rights in Technical Data and Computer Software clause
** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA
** 98052.
*/

go
use master
go
dump transaction master with no_log
go
checkpoint
go
set nocount on
set implicit_transactions off
go

declare @vdt varchar(99)
select  @vdt = convert(varchar,getdate(),113)
raiserror('Starting Install\ProcSyst.SQL at  %s',0,1,@vdt) with nowait
go

print ''
print 'Making sure that updates to system tables are allowed.'
go

declare  @dbcc_current_version	integer
	,@int1			integer
dbcc getvalue('current_version')  --1=4.21A ,400-406=6.0 ,407-?=6.5 (See spt_values 'DBV')
select @dbcc_current_version = @@error

if (     exists (select * from sysobjects where name='sp_configure')
    AND  @dbcc_current_version = (select version from sysdatabases where name='master')
    AND  1 <> (select value from syscurconfigs where config = 102)
   )
	begin						--Query tree compatible
	exec @int1 = sp_configure 'allow updates',1
	if @@error <> 0 or @int1 <> 0
		raiserror('Bad sp_configure exec at top of ProcSyst.SQL, killing spid.'
			,22,127) with log
	reconfigure with override
	end
go

/*
** Make sure server was started in single user mode or that sp_configure was used
** to enable updates to system tables.
*/

if (select value from syscurconfigs where config = 102) <> 1
	raiserror('Cannot run ProcSyst.SQL unless updates to system tables are enabled.  Shutdown server and restart with the ''-m'' option or use sp_configure to enable updates to system tables.'
			,22,127) with log
go

exec sp_MS_upd_sysobj_category 1  --Capture now_datetime for use below.

go

select count(*) ,'= the number of system stored procs in master..sysobjects'
	from sysobjects where type='P ' and name like 'sp[_]%'

print ''
print 'Dropping procedures that will be (re)created.'
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_a_count_bits_on')
		     drop procedure sp_a_count_bits_on

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_abort_xact')
	drop procedure sp_abort_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addalias')
	drop procedure sp_addalias

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addextendedproc')
	drop procedure sp_addextendedproc

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addgroup')
	drop procedure sp_addgroup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addlanguage')
	drop procedure sp_addlanguage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addlogin')
	drop procedure sp_addlogin

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addmessage')
	drop procedure sp_addmessage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addremotelogin')
	drop procedure sp_addremotelogin

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addsegment')
	drop procedure sp_addsegment
go

dump transaction master with no_log
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addserver')
	drop procedure sp_addserver

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addtype')
	drop procedure sp_addtype

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_addumpdevice')
	drop procedure sp_addumpdevice

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_adduser')
	drop procedure sp_adduser

if exists (select * from sysobjects
                where sysstat & 0xf = 4
                        and name = 'sp_altermessage')
        drop procedure sp_altermessage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_bindefault')
	drop procedure sp_bindefault

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_bindrule')
	drop procedure sp_bindrule

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_blockcnt')
	drop procedure sp_blockcnt

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_change_users_login')
		     drop procedure sp_change_users_login

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_changedbowner')
	drop procedure sp_changedbowner

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_changegroup')
	drop procedure sp_changegroup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_checknames')
	drop procedure sp_checknames

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_chklangparam')
	drop procedure sp_chklangparam

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_commit_xact')
	drop procedure sp_commit_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_setlangalias')
	drop procedure sp_setlangalias

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_commonkey')
	drop procedure sp_commonkey
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_configure')
	drop procedure sp_configure

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_create_removable')
	drop procedure sp_create_removable

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_certify_removable')
	drop procedure sp_certify_removable

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_check_removable')
	drop procedure sp_check_removable

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_cnst_csr')
	drop procedure sp_cnst_csr

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_coalesce_fragments')
	drop procedure sp_coalesce_fragments

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dboption')
	drop procedure sp_dboption

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dbinstall')
	drop procedure sp_dbinstall

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dbremove')
	drop procedure sp_dbremove

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_defaultdb')
	drop procedure sp_defaultdb

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_defaultlanguage')
	drop procedure sp_defaultlanguage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_depends')
	drop procedure sp_depends

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_devcreate')
	drop procedure sp_devcreate

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_devoption')
	drop procedure sp_devoption

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_diskdefault')
	drop procedure sp_diskdefault
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropalias')
	drop procedure sp_dropalias

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropdevice')
	drop procedure sp_dropdevice

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropdumpdevice')
	drop procedure sp_dropdumpdevice

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropextendedproc')
	drop procedure sp_dropextendedproc
go

dump transaction master with no_log
go
if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropgroup')
	drop procedure sp_dropgroup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropkey')
	drop procedure sp_dropkey

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_droplanguage')
	drop procedure sp_droplanguage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_droplogin')
	drop procedure sp_droplogin

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropmessage')
	drop procedure sp_dropmessage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_droptype')
	drop procedure sp_droptype

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropuser')
	drop procedure sp_dropuser

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropremotelogin')
	drop procedure sp_dropremotelogin

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropsegment')
	drop procedure sp_dropsegment

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_dropserver')
	drop procedure sp_dropserver
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_extendsegment')
	drop procedure sp_extendsegment
go

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_activate_svr')
	drop procedure sp_fallback_activate_svr
if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_activate_svr_db')
	drop procedure sp_fallback_activate_svr_db

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_deactivate_svr')
	drop procedure sp_fallback_deactivate_svr
if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_deactivate_svr_db')
	drop procedure sp_fallback_deactivate_svr_db

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_enroll_svr_db')
	drop procedure sp_fallback_enroll_svr_db

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_help')
	drop procedure sp_fallback_help

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_help_db_dev')
	drop procedure sp_fallback_help_db_dev

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_MS_enroll_db')
	drop procedure sp_fallback_MS_enroll_db

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_MS_enroll_dev')
	drop procedure sp_fallback_MS_enroll_dev

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_MS_enroll_usg')
	drop procedure sp_fallback_MS_enroll_usg

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_MS_sel_fb_svr')
	drop procedure sp_fallback_MS_sel_fb_svr

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_MS_verify_ri')
	drop procedure sp_fallback_MS_verify_ri

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_permanent_svr')
	drop procedure sp_fallback_permanent_svr

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_upd_dev_drive')
	drop procedure sp_fallback_upd_dev_drive

if exists (select * from sysobjects where type='P ' and
		 name='sp_fallback_withdraw_svr_db')
	drop procedure sp_fallback_withdraw_svr_db
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_fixindex')
	drop procedure sp_fixindex

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_foreignkey')
	drop procedure sp_foreignkey
go

dump transaction master with no_log
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_help')
	drop procedure sp_help

if exists (select * from sysobjects
		where sysstat & 0x0f = 4
			and name = 'sp_help_revdatabase')
		     drop procedure sp_help_revdatabase

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpconstraint')
	drop procedure sp_helpconstraint

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpdb')
	drop procedure sp_helpdb

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpdevice')
	drop procedure sp_helpdevice

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpextendedproc')
	drop procedure sp_helpextendedproc

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpgroup')
	drop procedure sp_helpgroup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpindex')
	drop procedure sp_helpindex

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpjoins')
	drop procedure sp_helpjoins

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpkey')
	drop procedure sp_helpkey
go

dump transaction master with no_log
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helplanguage')
	drop procedure sp_helplanguage

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helplog')
	drop procedure sp_helplog

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helplogins')
		     drop procedure sp_helplogins

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helprotect')
	drop procedure sp_helprotect

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helptext')
	drop procedure sp_helptext

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpuser')
	drop procedure sp_helpuser

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpremotelogin')
	drop procedure sp_helpremotelogin

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpsegment')
	drop procedure sp_helpsegment

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpserver')
	drop procedure sp_helpserver

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpsort')
	drop procedure sp_helpsort

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_helpstartup')
	drop procedure sp_helpstartup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_lock')
	drop procedure sp_lock

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_lock2')
	drop procedure sp_lock2

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_lockinfo')
	drop procedure sp_lockinfo
go

dump transaction master with no_log
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_logdevice')
	drop procedure sp_logdevice

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_lookup')
	drop procedure sp_lookup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_makestartup')
	drop procedure sp_makestartup

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_markreport')
	drop procedure sp_markreport

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_monitor')
	drop procedure sp_monitor

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_namecrack')
	drop procedure sp_namecrack
if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_namecrack2')
	drop procedure sp_namecrack2
if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_namecrack3')
	drop procedure sp_namecrack3

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_objectsegment')
	drop procedure sp_objectsegment

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_password')
	drop procedure sp_password

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_placeobject')
	drop procedure sp_placeobject

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_primarykey')
	drop procedure sp_primarykey


if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_probe_xact')
	drop procedure sp_probe_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_processinfo')
	drop procedure sp_processinfo

if (exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_processmail'))
	drop procedure sp_processmail
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_recompile')
	drop procedure sp_recompile

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_remoteoption')
	drop procedure sp_remoteoption

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_remove_xact')
	drop procedure sp_remove_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_rename')
	drop procedure sp_rename

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_renamedb')
	drop procedure sp_renamedb

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_scan_xact')
	drop procedure sp_scan_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_setnetname')
	drop procedure sp_setnetname

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_serveroption')
	drop procedure sp_serveroption

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_spaceused')
	drop procedure sp_spaceused

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_sqlexec')
	drop procedure sp_sqlexec

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_start_xact')
	drop procedure sp_start_xact

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_stat_xact')
	drop procedure sp_stat_xact
go

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_tableoption')
	drop procedure sp_tableoption

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_tempdbspace')
	drop procedure sp_tempdbspace

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_unbindefault')
	drop procedure sp_unbindefault

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_unbindrule')
	drop procedure sp_unbindrule

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_unmakestartup')
	drop procedure sp_unmakestartup


if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter1')
        drop procedure sp_user_counter1
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter2')
        drop procedure sp_user_counter2
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter3')
        drop procedure sp_user_counter3
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter4')
        drop procedure sp_user_counter4
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter5')
        drop procedure sp_user_counter5
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter6')
        drop procedure sp_user_counter6
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter7')
        drop procedure sp_user_counter7
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter8')
        drop procedure sp_user_counter8
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter9')
        drop procedure sp_user_counter9
if exists (select * from sysobjects where type='P ' and
                 name='sp_user_counter10')
        drop procedure sp_user_counter10
go
if exists (select * from sysobjects where type='P ' and
                 name='sp_userdefcounters')
        drop procedure sp_userdefcounters
go


if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_validaltlang')
	drop procedure sp_validaltlang

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_validlang')
	drop procedure sp_validlang

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_validname')
	drop procedure sp_validname

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_who')
	drop procedure sp_who

if exists (select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'sp_who2')
	drop procedure sp_who2
go

if exists ( select * from sysobjects
		where sysstat & 0xf = 4
			and name = 'MS_sqlctrs_users' )
    drop proc MS_sqlctrs_users
go

dump transaction master with no_log
go
print ''
go


raiserror('Special command to fix up freeoff on page 24 in all databases: dbcc dbr- (m-, f-)',0,1)
go
dbcc dbrepair (master, fixsysindex) --Why located in this file ?!
go



---------------------------------------------------------------
---------------------------------------------------------------
raiserror('Creating the general purpose System Stored Procedures ....',0,1)
---------------------------------------------------------------
---------------------------------------------------------------

select count(*) ,'= the number of system stored procs in master..sysobjects'
	from sysobjects where type='P ' and name like 'sp[_]%'

raiserror(' ',0,1)
go


raiserror(15339,-1,-1,'sp_user_counter1 - N')
go

create proc sp_user_counter1 as
select 0
go
create proc sp_user_counter2 as
select 0
go
create proc sp_user_counter3 as
select 0
go
create proc sp_user_counter4 as
select 0
go
create proc sp_user_counter5 as
select 0
go
create proc sp_user_counter6 as
select 0
go
create proc sp_user_counter7 as
select 0
go
create proc sp_user_counter8 as
select 0
go
create proc sp_user_counter9 as
select 0
go
create proc sp_user_counter10 as
select 0
go

raiserror(15339,-1,-1,'sp_userdefcounters')
go
create proc sp_userdefcounters as
exec sp_user_counter1
exec sp_user_counter2
exec sp_user_counter3
exec sp_user_counter4
exec sp_user_counter5
exec sp_user_counter6
exec sp_user_counter7
exec sp_user_counter8
exec sp_user_counter9
exec sp_user_counter10
go


raiserror(15339,-1,-1,'sp_blockcnt')
go
--perfmon
create procedure sp_blockcnt as
select blockedusers=count(*) from sysprocesses where blocked <> 0
go



raiserror(15339,-1,-1,'sp_tempdbspace')
go
--new query to watch max tempdbspace from perfmon
create proc sp_tempdbspace as

declare @dbsize dec(15,0)
declare @freespace dec(15,0)
declare @spaceused dec(15,0)

select @dbsize = sum(convert(dec(15),size))
               from master..sysusages
               where dbid = db_id('tempdb')

select  database_name = 'tempdb',
               database_size = (@dbsize / 512),
	       spaceused=(@dbsize/512-(@dbsize/512 -
                                 (select sum(convert(dec(15),reserved))
                from tempdb..sysindexes
	where indid in (0, 1, 255))/512))
go



raiserror(15339,-1,-1,'sp_devoption')
go
create procedure sp_devoption
@devname varchar(30) = NULL,		-- device name to change
@optname varchar(20) = NULL,		-- option name to turn on/off
@optvalue varchar(10) = NULL,		-- true or false
@override varchar(8)=	NULL
as
declare @statvalue int
declare @optcount int

select @optname=lower(@optname)
select @optvalue=lower(@optvalue)
select @override=lower(@override)

/*
** If no parameters were supplied, list settable options.
*/
if @devname is null
 	begin
		select 'Settable device options:' = name
			from master.dbo.spt_values
			where type = 'V'
				and number in (4096,8192)
			order by name
		return (0)
	end

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

/*
** If no option was supplied, display current settings.
*/
if @optname is null
	begin
		select 'The following options are set:' = v.name
			from spt_values v, sysdevices d
			where d.name=@devname
				and v.type = 'V'
				and (v.number & d.status)=v.number
				and v.number in (4096,8192)
		return(0)
	end

/*
** Can't change settings for 'master' device.
*/
if @devname = 'master'
	begin
		raiserror(15133,-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 @statvalue = min(number), @optcount = count(*)
	from master.dbo.spt_values
	where lower(name) like '%' + @optname + '%'
		and type = 'V'
		and number in (4096,8192)

if @optcount = 0
	begin
		raiserror(15013,-1,-1,@optname)
		select 'Settable device options:' = name
			from master.dbo.spt_values
			where type = 'V'
				and number in (4096,8192)
			order by name
		return (1)
	end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
begin
	raiserror(15135,-1,-1,@optname)
	select duplicate_options = name
		from master.dbo.spt_values
		where lower(name) like '%' + @optname + '%'
			and type = 'V'
			and number in (4096,8192)
	return (1)
end

/*
**  Check optvalue.
*/
if @optvalue not in ('true', 'false') or @optvalue is null
	begin
		raiserror(15136,-1,-1)
		return (1)
	end

/*
**  Check @override.
*/
if @override <> 'override' and @override is not null
	begin
		raiserror(15281,-1,-1,@override)
		return(1)
	end

/*
**  Can only supply @override if setting 'read only' device option.
*/
if @override is not null and not exists
	(select * from spt_values where type = 'V' and
		lower(name) like '%' + @optname + '%'
		and number = 4096)
	begin
		raiserror(15282,-1,-1)
		return(1)
	end

/*
**  Only the SA can execute the update part of this procedure.
*/
if suser_id() <> 1
	begin
		raiserror(15137,-1,-1)
		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_devoption')
		return (1)
	end

/*
**  Get the number which is the bit value to set
*/
select @statvalue = number
	from master.dbo.spt_values
	where lower(name) = @optname and type = 'V'
		and number in (4096,8192)

/*
** If setting device to 'read only', make certain that all databases
** on that device have been set to 'read only' or that user specified
** override.
*/
if @statvalue = 4096 and isnull(@override,'no override') <> 'override'
	and @optvalue='true'
	and exists (select * from sysdatabases d, sysusages u, sysdevices v
					where  d.dbid = u.dbid
					and u.vstart between v.low and v.high
					and v.name = @devname
					and (d.status&1024)=0)
	begin
		raiserror(15138,-1,-1)
		select distinct 'Writable database(s)' = d.name
			from sysdatabases d, sysusages u, sysdevices v
				where  d.dbid = u.dbid
				and u.vstart between v.low and v.high
				and v.name = @devname
				and (d.status&1024)=0
		return (1)
	end

if @optvalue='true'
	update sysdevices set status=status|@statvalue where name=@devname
else if lower(@optvalue)='false'
	update sysdevices set status=status & (~@statvalue) where name=@devname

print 'Device option set.'
return (0)
go


raiserror(15339,-1,-1,'sp_dboption')
go
create procedure sp_dboption  -- 1996/03/15 12:51
@dbname varchar(30) = NULL,     /* database name to change */
@optname varchar(35) = NULL,  /* option name to turn on/off */
@optvalue varchar(10) = NULL  /* true or false */
as

set nocount    on
set ansi_nulls on

declare @dbid int         /* dbid of the database */
declare @dbuid int           /* id of the owner of the database */
declare @statvalue int     /* number of option */
declare @optcount int      /* number of options like @optname */
declare @allopts int    /* bit map off all options that can be
            ** set by sp_dboption. */
declare @devname varchar(30)
declare @cur_dbname varchar(30)
declare @pmsg varchar(255)
declare @ret_code int
declare @int1 int
 ,@opt_trunclogonchkpt integer
 ,@fulloptname varchar(35)
 ,@orig_db_status smallint
 ,@opt_bit_singleuser integer

/*
**  If no @dbname given, just list the possible dboptions.
**  Only certain status bits may be set or cleared by sp_dboption.
*/

/*
** 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'

if @dbname is null
begin
   select 'Settable database options:' = name
      from master.dbo.spt_values
      where type = 'D'
         and number & @allopts <> 0
         and number not in (-1,@allopts)  /* Eliminate non-option entries */
      order by name
   return (0)
end

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

/*
**  If @dbname not found, say so and list the databases.
*/
if @dbid is null
   begin
      raiserror(15010,-1,-1,@dbname)
      print ''
      select 'Available databases:' = name
         from sysdatabases
      return (1)
   end

/*
** If no option was supplied, display current settings.
*/
if @optname is null
   begin
      select 'The following options are set:' = v.name
         from master.dbo.spt_values v, sysdatabases d
            where d.name=@dbname
               and number & @allopts <> 0
               and number not in (-1,@allopts)  /* Eliminate non-option entries */
               and v.type = 'D'
               and ((v.number & d.status)=v.number
                  or d.category & (v.number/0x10000) <> 0)

      return(0)
   end

if lower(@optvalue) not in ('true', 'false') and @optvalue is not null
   begin
      raiserror(15241,-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 @statvalue = min(number), @optcount = count(*) ,@fulloptname = min(name)
      from master.dbo.spt_values
      where lower(name) like '%' + lower(@optname) + '%'
         and type = 'D'
         and number & @allopts <> 0
         and number not in (-1,@allopts)  /* Eliminate non-option entries */

/*
**  If no option, show the user what the options are.
*/
if @optcount = 0
   begin
      raiserror(15011,-1,-1,@optname)
      print ''

      select 'Settable database options:' = name
         from master.dbo.spt_values
         where type = 'D'
            and number & @allopts <> 0
            and number not in (-1,@allopts)  /* Eliminate non-option entries */
         order by name

      return (1)
   end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
   begin
      raiserror(15242,-1,-1,@optname)
      print ''

      select duplicate_options = name
         from master.dbo.spt_values
         where name like '%' + @optname + '%'
            and type = 'D'
            and number & @allopts <> 0
            and number not in (-1,@allopts)  /* Eliminate non-option entries */
      return (1)
   end

select @opt_trunclogonchkpt = min(number)
   from master..spt_values
   where type='D  ' and name='trunc. log on chkpt.'
/*
**  You can not change any of the options in master, except the 'trunc log on
**  checkpoint' option (8).  If the user tries to do so tell them they can't.
*/
if (@dbid = 1 and @statvalue <> @opt_trunclogonchkpt and @optvalue is not null)
   begin
      raiserror(15243,-1,-1,@optname)
      return (1)
   end

/*
**  Only the SA or the dbo of @dbname can execute the update part
**  of this procedure so check.
*/
if suser_id() <> 1 and suser_id() <> @dbuid and @optvalue is not null
   begin
      raiserror(15244,-1,-1)
      return (1)
   end

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

select @cur_dbname=db_name()  /* Keep track of where we are. */


/*
**  Just want to see current setting of specified option.
*/
if @optvalue is null
begin
      select       @int1   = min(number)
         from      master.dbo.spt_values
         where     name LIKE '%' + @optname + '%'


      select OptionName = v.name

            ,CurrentSetting =
               CASE
                  When ( (v.number & d.status) = v.number
                       or d.category & (v.number/0x10000) <> 0
                       )
                     Then 'ON'
                  When NOT
                       ( (v.number & d.status) = v.number
                       or d.category & (v.number/0x10000) <> 0
                       )
                     Then 'off'
               END

         from master.dbo.spt_values v, sysdatabases d
            where d.name=@dbname
               and v.number & @allopts <> 0
               and v.number not in (-1,@allopts)   /* Eliminate non-option entries */
               and v.type = 'D'
               and v.number = @int1 and @int1 is not null

   return (0)
end


---- Pre-detect 'single user' conflicts.
select @opt_bit_singleuser = min(number) from master..spt_values
  where type='D  ' and name='single user'
if (@fulloptname           ='single user') --13834
   begin
   select @int1 = count(*) from master..sysprocesses
      where @dbname = db_name(dbid) and spid<>@@spid
   if (@int1 > 0 and
	(@orig_db_status & @opt_bit_singleuser > 0 or
	 lower(@optvalue) = 'true')
      )
      begin
      raiserror(15089,-1,-1,@fulloptname)
      return (1)
      end
   end


/*
**  Now update sysdatabases.
*/
if lower(@optvalue) = 'true'
begin
   /*
   **  If this is the option to make the database read only
   **  or to take it offline, we need to do some checking first.
   **  Unless it's the master db, no one can be using it.
   **  If it's the master db, only the SA may be using it.
   */
   if @statvalue in (512,1024)
      and (select count(*) from sysprocesses
         where dbid = @dbid
         and suid <> 1) > 0
      begin
         raiserror(15069,-1,-1)
         return (1)
      end

   /*
   ** If we're setting the database 'offline' - use 'dbcc dbcontrol'
   ** rather than setting the status bit directly.
   */
   if @statvalue = 512  -- 512 ON means db is Offline.
   begin

      if (0 = (@statvalue & (select status from master..sysdatabases where name=@dbname)))
         begin  -- Currently db is Online.

         dbcc dbcontrol(@dbname,offline)
         if @@error>0
            begin
               raiserror(15245,-1,-1)
               return (1)
            end
         else
            print 'Database is now offline'

         end
      else
         print 'Database already is offline.'

      /*
      ** Now close all open devices that belong solely to this database
      ** or are shared only by other offline databases.
      */
      exec('declare c1 cursor for
         select distinct v.name
         from master.dbo.sysdevices v, master.dbo.sysusages u, master.dbo.sysdatabases d
         where d.name = '''+
         @dbname+
         ''' and d.dbid = u.dbid
         and u.vstart between v.low and v.high
         and v.status & 2 = 2
         and v.status & 8192 = 0  -- Not already closed/deferred.
         and not exists '+
         '(select * from master.dbo.sysdevices v2,
               master.dbo.sysusages u2,
               master.dbo.sysdatabases d2
            where v2.name = v.name
            and d2.dbid = u2.dbid
            and vstart between v2.low and v2.high
            and d2.dbid <> d.dbid
            and d2.status & 512 <> 512)')

      open c1
      fetch c1 into @devname

      while @@fetch_status >= 0
      begin
         select @pmsg='Closing device '''+@devname+''' and marking it ''deferred''.'
         print @pmsg
         dbcc devcontrol(@devname,offline)
         exec sp_devoption @devname,deferred,true
         fetch c1 into @devname
      end
      deallocate c1
      /*
      ** Don't need to continue and set status bit or 'checkpoint'
      ** the database if option was 'offline' since the dbcc
      ** command does.
      */
      return(0)   /* Don't need to continue and 'checkpoint' db for this
            ** option. */
   end

   if @statvalue = 65536   /* We're publishing the database. */
      begin
         exec ('use ' + @dbname + ' exec sp_publishdb ' + @dbname
		+ ', ''true''')
         update sysdatabases
             set category = category | 1
             where name = @dbname
             print 'Database successfully published.'
             return(0)
      end

   if @statvalue = 131072  /* Allowing subscriptions in the database. */
      begin
         /* Add repl_publisher, dbo alias */

         exec ('use ' + @dbname + '
                if not exists (select * from sysalternates where
            suid = 16382) '+ /* repl_publisher id */
            'insert into sysalternates (suid, altsuid)
               values (16382, 1)'
              )

         update sysdatabases set category = category | 2
            where name = @dbname
         print 'Database successfully enabled for subscriptions.'
         return (0)
      end

   /* All other options get handled identically. */
   update sysdatabases set status = status | @statvalue
      where dbid = @dbid
end

/*
**  We want to set the requested option off.
*/

else

begin
   if @statvalue = 512     /* We're bringing it online. */
   begin
        /*
      ** Open all closed devices that this database uses.
      */
      exec('declare c1 cursor for
         select distinct v.name
         from master.dbo.sysdevices v, master.dbo.sysusages u, master.dbo.sysdatabases d
         where d.name = '''+
         @dbname+
         ''' and d.dbid = u.dbid
         and u.vstart between v.low and v.high
         and v.status & 2 = 2
         and v.status & 8192 > 0')

      open c1
      fetch c1 into @devname

      while @@fetch_status >= 0
      begin
         select @pmsg='Opening device '''+@devname+''' and marking it as non-deferred.'
         print @pmsg
         dbcc devcontrol(@devname,online)
         if @@error not in (0,5151,5155)
            begin
                                        deallocate c1
               raiserror(15246,-1,-1,@devname)
               return (1)
            end
         exec sp_devoption @devname,deferred,false
         fetch c1 into @devname
      end
      deallocate c1


      if (0 = (@statvalue & (select status from master..sysdatabases where name=@dbname)))
         -- Currently db is Online.
         print 'Database already is online.'
      else
         begin
         dbcc dbcontrol(@dbname,online)
         if @@error>0
            begin
               return (1)
            end
         else
            print 'Database is now online.'
         end

      return(0)
   end

   if @statvalue = 65536   /* We're disabling publishing for the database. */
      begin
         exec ('use ' + @dbname + ' exec sp_publishdb ' + @dbname
		+ ', ''false''')
         update sysdatabases
		set category = category & ~1
                where name = @dbname
	 print 'Database no longer published.'
      end

   if @statvalue = 131072  /* We're disabling subscriptions to database. */
      begin
         /* Drop repl_publisher, dbo alias */

         exec ('use ' + @dbname + '
                if     exists (select * from sysalternates where
            suid = 16382) '+ /* repl_publisher id */
            'delete sysalternates where suid = 16382'
              )

         update sysdatabases set category = category & ~2
            where name = @dbname
         print 'Database no longer enabled for subscriptions.'
         return (0)
      end

   /* All other options get handled identically. */
   update sysdatabases set status = status & ~@statvalue
      where dbid = @dbid
end

/*
**  CHECKPOINT the database that was changed.
*/
print 'CHECKPOINTing database that was changed.'

exec('use ' + @dbname + ' checkpoint')
select @int1 = @@error
if (@int1 <> 0)
	begin
	update		 master..sysdatabases
		set	 status = @orig_db_status
		where	 dbid   = @dbid
	end

return (0)
go



raiserror(15339,-1,-1,'sp_coalesce_fragments')
go
create procedure sp_coalesce_fragments  --1996/02/07 18:03
	 @DBNamePattern  varchar(44) = '%'
as

set nocount                on
set cursor_close_on_commit off

declare
	@RetCode int,
	@c1_vstart int,
	@c1_size int,
	@c1_dbid smallint

declare
	@2size int,
	@2segmap int,
	@countusagesdel int,
	@_rowcount int

select	@countusagesdel = 0
	,@RetCode = 0 --Assume good (1=bad)

if suser_id() <> 1
	begin
	raiserror(15003,-1,-1)  --must be SA
	select @RetCode = 1
	goto LABEL_86RETURN
	end

if @DBNamePattern is null
	begin
	select @DBNamePattern = ' n u l l'
	end

if not exists (select * from master.dbo.sysdatabases
		where name like @DBNamePattern)
	begin
	raiserror(15329,-1,-1)
	select @RetCode = 1
	goto LABEL_86RETURN
	end

---- Cursor to find a preceding contiguous fragment.

execute('declare c1 scroll cursor for
	select u1.vstart ,u1.size ,u1.dbid
	from master.dbo.sysusages u1
	where exists (select * from master.dbo.sysusages u2
			where u2.dbid = u1.dbid
			and u2.vstart = u1.vstart+u1.size
			and u2.lstart = u1.lstart+u1.size
			and u2.vstart between
				(select d1.low
					from master.dbo.sysdevices d1
					where u1.vstart between
						d1.low and d1.high
					and d1.status&2=2)
			and
				(select d2.high
					from master.dbo.sysdevices d2
					where u1.vstart between
						d2.low and d2.high
					and d2.status&2=2)
			)
	and db_name(u1.dbid) like ''' + @DBNamePattern + '''
	and u1.vstart > 0'
	)

-- Each loop iteration finds a sysusages row for which there is a
-- contiguous fragment at a higher vstart.   Then it gathers info on that
-- higher vstart row, and uses that info to delete the higher vstart
-- row and update the first row.

while 1=1
	begin

	open  c1
	fetch c1 into @c1_vstart,@c1_size ,@c1_dbid

	if @@fetch_status <> 0
		BREAK


	select @2size=null ,@2segmap=null

	select @2size=min(size) ,@2segmap=min(segmap)
		  from  master.dbo.sysusages
		  where vstart = @c1_vstart + @c1_size
		  and   dbid   = @c1_dbid

	select @_rowcount = @@rowcount

	if (@2size is null  OR  @2segmap is null)
		begin
		raiserror(15314,-1,-1,@c1_dbid,@c1_vstart) --corrupt sysusages
		select @RetCode = 1
		BREAK
		end


	select @countusagesdel = @countusagesdel + 1


BEGIN TRANSACTION txn_1a_sp_coalesce_fragments

	delete from sysusages
		  where vstart = @c1_vstart + @c1_size
		  and   dbid   = @c1_dbid

	if @@error <> 0
		begin
		raiserror('Inside txn_1a_, Del failed, will Rollback (1a1)!',17,127)
		ROLLBACK TRANSACTION --Even a @@trancount=3 would be reduced to =0.
		select @RetCode = 1
		GOTO LABEL_85DEALLOCC1
		end

	update sysusages
		set
			size   = size   + @2size,
			segmap = segmap | @2segmap
		where current of c1

	if @@error <> 0
		begin
		raiserror('Inside txn_1a_, Upd failed, will Rollback (1a2)!',17,127)
		ROLLBACK TRANSACTION --Even a @@trancount=3 would be reduced to =0.
		select @RetCode = 1
		GOTO LABEL_85DEALLOCC1
		end

COMMIT TRANSACTION txn_1a_sp_coalesce_fragments


	close c1  --force refreshing open
		
 	end --of loop


raiserror(15315,-1,-1,@countusagesdel)

LABEL_85DEALLOCC1:

deallocate c1

LABEL_86RETURN:

return @RetCode
go


---- Top_Fallback ("Failover")


raiserror(15339,-1,-1,'sp_fallback_MS_enroll_db')
go
create procedure sp_fallback_MS_enroll_db  --1996/03/04 10:22
    @pFallbackSvrName   varchar(30)
   ,@p_db_name         varchar(30)

   ,@p_db_dbid         smallint       OUTPUT
   ,@p_db_status       smallint       OUTPUT
   ,@p_db_version      smallint       OUTPUT
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc's name contains the substring 'MS',
and thus is undocumented and should NOT be directly
executed by the SA.
      This sproc must be and will be executed on the primary server,
by an RPC issued from a fallback server.
      This sproc does not modify any data.
      This sproc contains extra nondb edits, e.g. for sysservers.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad ,<0==no_action
      ,@_error                   integer
      ,@int1                     integer
      ,@vc1                      varchar(30)
      ,@FBBit                    integer

-----------------------------------

Select
       @RetCode                  = 0


Select @FBBit = 64

--SELECT       @FBBit = min(val.number)
--      from   master..spt_values  val
--      where  val.type = 'A  '
--      and    val.name = 'fallback'


------------------------  Ensure fallback svr has been added  --------------

IF (@@servername <> @pFallbackSvrName)
   begin

   SELECT
             @int1         = count(*)
            ,@vc1          = min(syssvr.srvname)
      from
             master..sysservers     syssvr
      where
            (     syssvr.srvname   = @pFallbackSvrName
             and  syssvr.srvstatus & @FBBit > 0
             and  syssvr.srvid    <> 0
            )

   IF (     @int1 <> 1
      OR    @vc1  <> @pFallbackSvrName
      )
      begin
      RaisError(15359,-1,-1,@pFallbackSvrName)
      Select @RetCode = 1
      GOTO LABEL_86_RETURN
      end
   end


---------------------

SELECT
             @p_db_dbid      = min(sysdb.dbid)
            ,@p_db_status    = min(sysdb.status)
            ,@p_db_version   = min(sysdb.version)
      from
             master..sysdatabases   sysdb
      where
             sysdb.name      = @p_db_name


LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_MS_enroll_dev')
go
create procedure sp_fallback_MS_enroll_dev  --1996/02/28 17:02
    @p_db_dbid         smallint

   ,@p_dev_low          integer           OUTPUT
   ,@p_dev_high         integer           OUTPUT
   ,@p_dev_status       smallint          OUTPUT
   ,@p_dev_name         varchar(30)       OUTPUT
   ,@p_dev_phyname      varchar(127)      OUTPUT
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc's name contains the substring 'MS',
and thus is undocumented and should NOT be directly
executed by the SA.
      This sproc must be and will be executed on the primary server,
by an RPC issued from a fallback server.
      This sproc does not modify any data.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad ,<0==no_action
      ,@_error                   integer

-----------------------------------

Select
       @RetCode                  = 0


---------------------

SELECT
             @p_dev_low       = min(sysdev.low)
            ,@p_dev_high      = min(sysdev.high)
            ,@p_dev_status    = min(sysdev.status)
            ,@p_dev_name      = min(sysdev.name)
            ,@p_dev_phyname   = min(sysdev.phyname)
      from
             master..sysdevices     sysdev
            ,master..sysusages      sysusg
            ,master..sysdatabases   sysdb
      where
             sysdb.dbid      = @p_db_dbid
      and    sysdb.dbid      = sysusg.dbid
      and
             sysusg.vstart between sysdev.low
                           and     sysdev.high
      and
             @p_dev_name      < sysdev.name


LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_MS_enroll_usg')
go
create procedure sp_fallback_MS_enroll_usg  --1996/02/28 15:03
    @p_db_dbid         smallint

   ,@p_usg_segmap       integer        OUTPUT
   ,@p_usg_lstart       integer        OUTPUT
   ,@p_usg_size         integer        OUTPUT
   ,@p_usg_vstart       integer        OUTPUT
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc's name contains the substring 'MS',
and thus is undocumented and should NOT be directly
executed by the SA.
      This sproc must be and will be executed on the primary server,
by an RPC issued from a fallback server.
      This sproc does not modify any data.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad ,<0==no_action
      ,@_error                   integer

-----------------------------------

Select
       @RetCode                  = 0


---------------------

SELECT
             @p_usg_segmap    = min(sysusg.segmap)
            ,@p_usg_lstart    = min(sysusg.lstart)
            ,@p_usg_size      = min(sysusg.size)
            ,@p_usg_vstart    = min(sysusg.vstart)
      from
             master..sysusages      sysusg
      where
             sysusg.dbid      = @p_db_dbid
      and    @p_usg_vstart    < sysusg.vstart


LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_MS_sel_fb_svr')
go
create procedure sp_fallback_MS_sel_fb_svr  --1996/02/14 10:44
    @pFallbackSvrName    character varying(30)   OUTPUT
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the primary server.
      This sproc is used by ODBC & DBLib when first connecting.
      This sproc will assign a null to the output parm in the
beginning, but will try to fill the parm with the name of any one of
the fallback servers defined in sysservers, for this primary server.
Ideally there will be only one fallback server defined for any one
primary server which might crash.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount                   on
Set ansi_nulls                on

Declare
       @FBBit                 integer

-----------------------------------

SELECT       @FBBit = min(val.number)
      from   master..spt_values  val
      where  val.type = 'A  '
      and    name     = 'fallback'

-------------------------------------

SELECT       @pFallbackSvrName   = min(syssvr.srvnetname) -- sp_setnetname
      from
             master..sysservers  syssvr
      where
             syssvr.srvstatus    & @FBBit > 0


Return 0
go



raiserror(15339,-1,-1,'sp_fallback_MS_verify_ri')
go
create procedure sp_fallback_MS_verify_ri  --1996/02/28 14:12
    @pPrimarySvrNamePattern   character varying(44)   = '%'
   ,@pDbNamePattern          character varying(44)   = '%'
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server.  Or it
is probably called by sp_fallback_help.
      This sproc is an additional level of safety.  The sp_fallback_%
sprocs use regular transactions where appropriate, but DTC is not
being used (tho perhaps it should be used in _enroll_).
      This sproc checks the internal RefInteg correctness among the
set of tables-

sysdatabases/sysdevices/sysusages.

It also checks the internal RI among the set-

spt_fallback_db/spt_fallback_dev/spt_fallback_usg.

It also checks Active/Inactive fallback status info for consistency.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount                   on
Set ansi_nulls                on

Declare
       @RetCode                  integer -- =0 is good; >0 is bad.
      ,@Int1                     integer
      ,@BogusDBId                smallint

Declare
       @WSvrName           character varying(30)
      ,@WDBId              smallint
      ,@WLow               integer
      ,@WVstart            integer

Declare
       @PrevWSvrName       character varying(30)
      ,@PrevWDBId          smallint
      ,@PrevWLow           integer
      ,@PrevWVstart        integer

-----------------------------------

Select
       @RetCode                  = 0
      ,@BogusDBId                = -1234


-----------------------------------------------------------------------
--                sys% tables RI as a single set
-----------------------------------------------------------------------


-------- Any sysusg orphans re sysdev?


SELECT       @Int1 = min(sysusg.vstart)
      from
             master..sysusages      sysusg
      where
             not exists
               (
                SELECT   *
                  from   master..sysdevices     sysdev
                  where  sysdev.cntrltype       = 0
                  and    sysusg.vstart between sysdev.low and sysdev.high
               )

IF (@Int1 is not null)
   begin
   RaisError(15366,-1,11,'sysdevices:sysusages.vstart',@Int1)  -- Do NOT internationalize these.
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any sysusg orphans re sysdb?


SELECT       @Int1 = min(sysusg.vstart)
      from
             master..sysusages      sysusg
      where
             not exists
               (
                SELECT   *
                  from   master..sysdatabases   sysdb
                  where  sysusg.dbid            = sysdb.dbid
               )

IF (@Int1 is not null)
   begin
   RaisError(15366,-1,12,'sysdatabases:sysusages.vstart',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any sysdev parents with 0 children in sysusg?


---- Error only for sysdevices actively tied to spt_fallback_dev.

SELECT       @Int1 = min(sysdev.low)
      from
             master..sysdevices        sysdev
            ,master..spt_fallback_dev  dev
      where
             dev.xserver_name like @pPrimarySvrNamePattern
      and    sysdev.cntrltype     = 0
      and    sysdev.low           = dev.xfallback_low
      and    not exists
               (
                SELECT   *
                  from   master..sysusages         sysusg
                  where  sysusg.vstart between sysdev.low and sysdev.high
               )

IF (@Int1 is not null)
   begin
   RaisError(15366,-1,13,'sysusages:sysdevices.low',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any sysdb parents with 0 children in sysusg?


SELECT       @Int1 = min(sysdb.dbid)
      from
             master..sysdatabases      sysdb
      where
             not exists
               (
                SELECT   *
                  from   master..sysusages      sysusg
                  where  sysdb.dbid            = sysusg.dbid
               )

IF (@Int1 is not null)
   begin
   RaisError(15366,-1,14,'sysusages:sysdatabases.dbid',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end



-----------------------------------------------------------------------
--                spt_fallback_% tables RI as a single set
-----------------------------------------------------------------------


-------- Any usg orphans re dev?


SELECT       @Int1 = min(usg.vstart)
      from
             master..spt_fallback_usg     usg
      where
             usg.xserver_name like @pPrimarySvrNamePattern
      and    not exists
               (
                SELECT   *
                  from   master..spt_fallback_dev     dev
                  where
                         usg.xserver_name    = dev.xserver_name
                  and    usg.vstart between dev.low and dev.high
               )

IF (@Int1 is not null)
   begin
   RaisError(15367,-1,11,'dev:spt_fallback_usg.vstart',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any usg orphans re db?


SELECT       @Int1 = min(usg.vstart)
      from
             master..spt_fallback_usg     usg
      where
             usg.xserver_name like @pPrimarySvrNamePattern
      and    not exists
               (
                SELECT   *
                  from   master..spt_fallback_db     db
                  where  usg.dbid         = db.dbid
                  and    usg.xserver_name = db.xserver_name
               )

IF (@Int1 is not null)
   begin
   RaisError(15367,-1,12,'db:spt_fallback_usg.vstart',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any dev parents with 0 children in usg?


SELECT       @Int1 = min(dev.low)
      from
             master..spt_fallback_dev     dev
      where
             dev.xserver_name like @pPrimarySvrNamePattern
      and    not exists
               (
                SELECT   *
                  from   master..spt_fallback_usg     usg
                  where  usg.vstart between dev.low and dev.high
                  and    usg.xserver_name    = dev.xserver_name
               )

IF (@Int1 is not null)
   begin
   RaisError(15367,-1,13,'usg:spt_fallback_dev.low',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- Any db parents with 0 children in usg?


SELECT       @Int1 = min(db.dbid)
      from
             master..spt_fallback_db     db
      where
             db.xserver_name like @pPrimarySvrNamePattern
      and    not exists
               (
                SELECT   *
                  from   master..spt_fallback_usg     usg
                  where  usg.dbid         = db.dbid
                  and    usg.xserver_name = db.xserver_name
               )

IF (@Int1 is not null)
   begin
   RaisError(15367,-1,14,'usg:spt_fallback_db.dbid',@Int1)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


------------------------------------------------------------------------
--       spt_fallback_% active/inactive internally consistent as a set?
------------------------------------------------------------------------


SELECT
             @WSvrName      = min(db.xserver_name)
      from
             master..spt_fallback_db     db
      where
             db.xfallback_dbid  is NOT null  -- NOT null
      and
            (exists
               (SELECT      *
                  from      master..spt_fallback_dev  dev
                           ,master..spt_fallback_usg  usg
                  where     dev.xserver_name       = db.xserver_name
                  and       usg.vstart between dev.low and dev.high
                  and       usg.dbid               = db.dbid
                  and       dev.xfallback_low      IS null
               )
            OR
             exists
               (SELECT      *
                  from      master..spt_fallback_usg  usg
                  where     usg.xserver_name       = db.xserver_name
                  and       usg.dbid               = db.dbid
                  and       usg.xfallback_vstart   IS null
               )
            )

IF (@WSvrName is not null)
   begin
   RaisError(15368,-1,11,@WSvrName)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end

--------------------------------------- NullNess

SELECT
             @WSvrName      = min(db.xserver_name)
      from
             master..spt_fallback_db     db
      where
             db.xfallback_dbid  IS null  -- IS null
      and
            (exists
               (SELECT      *
                  from      master..spt_fallback_usg  usg
                  where     usg.xserver_name       = db.xserver_name
                  and       usg.dbid               = db.dbid
                  and       usg.xfallback_vstart   is NOT null
               )
            )

IF (@WSvrName is not null)
   begin
   RaisError(15368,-1,12,@WSvrName)
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-----------------------------------------------------------------------
--       spt_fallback_% active entries present in sys% tables?
-----------------------------------------------------------------------


-------- db/sysdb

SELECT
             @WSvrName      = min(db.xserver_name)
      from
             master..spt_fallback_db     db
      where
             db.xfallback_dbid     is not null
      and    db.xfallback_dbid     not in
               (
                SELECT      sysdb.dbid
                  from      master..sysdatabases      sysdb
               )

IF (@WSvrName is not null)
   begin
   RaisError(15369,-1,11,@WSvrName,'db')
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- usg/sysusg

SELECT
             @WSvrName      = min(usg.xserver_name)
      from
             master..spt_fallback_usg     usg
      where
             usg.xfallback_vstart   is not null
      and    usg.xfallback_vstart   not in
               (
                SELECT      sysusg.vstart
                  from      master..sysusages      sysusg
               )

IF (@WSvrName is not null)
   begin
   RaisError(15369,-1,12,@WSvrName,'usg')
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-------- dev/sysdev

SELECT
             @WSvrName      = min(dev.xserver_name)
      from
             master..spt_fallback_dev     dev
      where
             dev.xfallback_low      is not null
      and    dev.xfallback_low      not in
               (
                SELECT      sysdev.low
                  from      master..sysdevices     sysdev
               )

IF (@WSvrName is not null)
   begin
   RaisError(15369,-1,13,@WSvrName,'dev')
   Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


-----------------------------------------------------------------------
--       spt_fallback_% illegal PK duplicates / unique violations?
-----------------------------------------------------------------------

---- Even Clus idx's add 16 Kb each minimum.


-------- db dupl?

Declare csr_33_db insensitive cursor for
   SELECT       db.xserver_name
               ,db.dbid
      from      master..spt_fallback_db  db
      order by  db.xserver_name
               ,db.dbid

OPEN csr_33_db


Select
       @WSvrName     = char(0x00)  -- < 0x20 blank
      ,@WDBId        = -1

Select
       @PrevWSvrName = @WSvrName
      ,@PrevWDBId    = @WDBId


WHILE (33=33)
   begin

   FETCH     next
      from   csr_33_db
      into   @WSvrName
            ,@WDBId

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

   IF (     @PrevWSvrName  = @WSvrName
      AND   @PrevWDBId     = @WDBId
      )
      begin
      RaisError(15381,-1,-1,@WSvrName,@WDBId)
      Select @RetCode = @@error
      end

   Select
       @PrevWSvrName = @WSvrName
      ,@PrevWDBId    = @WDBId

   end -- loop 33 db dupl


-------- dev dupl?

Declare csr_34_dev insensitive cursor for
   SELECT       dev.xserver_name
               ,dev.low
      from      master..spt_fallback_dev  dev
      order by  dev.xserver_name
               ,dev.low

OPEN csr_34_dev


Select
       @WSvrName     = char(0x00)
      ,@WLow         = -1

Select
       @PrevWSvrName = @WSvrName
      ,@PrevWLow     = @WLow


WHILE (34=34)
   begin

   FETCH     next
      from   csr_34_dev
      into   @WSvrName
            ,@WLow

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

   IF (     @PrevWSvrName  = @WSvrName
      AND   @PrevWLow      = @WLow
      )
      begin
      RaisError(15382,-1,-1,@WSvrName,@WLow)
      Select @RetCode = @@error
      end

   Select
       @PrevWSvrName = @WSvrName
      ,@PrevWLow     = @WLow

   end -- loop 34 dev dupl


-------- usg dupl?

Declare csr_35_usg insensitive cursor for
   SELECT       usg.xserver_name
               ,usg.vstart
      from      master..spt_fallback_usg  usg
      order by  usg.xserver_name
               ,usg.vstart

OPEN csr_35_usg


Select
       @WSvrName     = char(0x00)
      ,@WVstart      = -1

Select
       @PrevWSvrName = @WSvrName
      ,@PrevWVstart  = @WVstart


WHILE (35=35)
   begin

   FETCH     next
      from   csr_35_usg
      into   @WSvrName
            ,@WVstart

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

   IF (     @PrevWSvrName  = @WSvrName
      AND   @PrevWVstart   = @WVstart
      )
      begin
      RaisError(15383,-1,-1,@WSvrName,@WVstart)
      Select @RetCode = @@error
      end

   Select
       @PrevWSvrName = @WSvrName
      ,@PrevWVstart  = @WVstart

   end -- loop 35 usg dupl



--LABEL_86_RETURN:


---------------------------------------------
--    Attempt corrective actions
---------------------------------------------


IF (@RetCode > 0)
   begin

---- Make nonActive any spt_fallback_ rows lacking sys-tables link.

   Select @Int1 = 0

   UPDATE       master..spt_fallback_db
         set    xfallback_dbid   = null
         where  xfallback_dbid   is not null
         and    xfallback_dbid   not in
                  (
                  SELECT sysdb.dbid from master..sysdatabases sysdb
                  )
   Select @Int1 = @Int1 + @@rowcount

   UPDATE       master..spt_fallback_usg
         set    xfallback_vstart = null
         where  xfallback_vstart is not null
         and    xfallback_vstart not in
                  (
                  SELECT sysusg.vstart from master..sysusages sysusg
                  )
   Select @Int1 = @Int1 + @@rowcount

   UPDATE       master..spt_fallback_dev
         set    xfallback_low    = null
         where  xfallback_low    is not null
         and    xfallback_low    not in
                  (
                  SELECT sysdev.low from master..sysdevices sysdev
                  )
   Select @Int1 = @Int1 + @@rowcount

   IF (@Int1 > 0)
      Raiserror(15357,0,1,@Int1)
   end

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_help')
go
create procedure sp_fallback_help  --1996/02/17 22:02
    @pPrimarySvrName character varying(30)   = '%'
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer
      ,@ExecRC                   integer
      ,@AllIntegGoodRC           integer
      ,@charMaxLenPhyname        character varying(12)

--------------------------------------

Select
       @RetCode                  = 0
      ,@AllIntegGoodRC           = 0

--------------------------- Integrities?

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   Select @AllIntegGoodRC = @ExecRC
   Select @RetCode        = @ExecRC
   end

------------------------------------------ db

EXECUTE(
'
Set nocount off

SELECT
             ''Databases''          as ''InfoType ''
            ,CASE
               When db.xfallback_dbid is not null Then ''YES''
               When db.xfallback_dbid is     null Then ''no''
             END
                                    as ''Active''
            ,db.xserver_name       as ''PrimaryServerName''
            ,db.name               as ''DatabaseName''
            ,db.xdttm_ins          as ''DateEnrolled''
            ,db.xdttm_last_ins_upd as ''DateLastUpd''
            ,db.xfallback_dbid     as ''FallbackDBId''
            ,db.dbid               as ''PrimaryDBId''
      from
             master..spt_fallback_db  db
      where
             db.xserver_name   LIKE ''' + @pPrimarySvrName + '''
      order by
             db.xserver_name
            ,db.name
')


----------------------------------------- dev

SELECT
             @charMaxLenPhyname
                  = isnull(convert(varchar,max(datalength(dev.phyname))),'0')
      from
             master..spt_fallback_dev   dev


IF convert(integer,@charMaxLenPhyname) <
                       Datalength('PhynameOnPrimaryServer')
   Select          @charMaxLenPhyname  =
       convert(varchar,Datalength('PhynameOnPrimaryServer'))



EXECUTE(
'
Set nocount off

SELECT
             ''Devices''            as ''InfoType ''
            ,CASE
               When dev.xfallback_low is not null Then ''YES''
               When dev.xfallback_low is     null Then ''no''
             END
                                    as ''Active''
            ,dev.xserver_name       as ''PrimaryServerName''
            ,dev.name               as ''LogicalDeviceName''
            ,dev.xdttm_ins          as ''DateEnrolled''
            ,dev.xdttm_last_ins_upd as ''DateLastUpd''
            ,dev.xfallback_drive    as ''FBDrive''
            ,substring(dev.phyname,1,' + @charMaxLenPhyname + ')
                                    as ''PhynameOnPrimaryServer''
            ,dev.xfallback_low      as ''FallbackLow''
      from
             master..spt_fallback_dev  dev
      where
             dev.xserver_name   LIKE ''' + @pPrimarySvrName + '''
      order by
             dev.xserver_name
            ,dev.name
')


-----------------------------------------  usg

IF (@AllIntegGoodRC = 0)
   begin

   EXECUTE(
   '
   Set nocount off

   SELECT
             ''Usages''             as ''InfoType ''
            ,CASE
               When usg.xfallback_vstart is not null Then ''YES''
               When usg.xfallback_vstart is     null Then ''no''
             END
                                    as ''Active''
            ,usg.xserver_name       as ''PrimaryServerName''
            ,db.name               as ''DatabaseName''
            ,dev.name               as ''LogicalDeviceName''
            ,usg.xfallback_vstart   as ''FallbackVstart''
            ,usg.xdttm_ins          as ''DateEnrolled''
            ,usg.xdttm_last_ins_upd as ''DateLastUpd''
            ,usg.dbid               as ''DBIdOnPrimaryServer''
            ,usg.vstart             as ''VstartOnPrimaryServer''
      from
             master..spt_fallback_usg  usg
            ,master..spt_fallback_db  db
            ,master..spt_fallback_dev  dev
      where
             usg.xserver_name   LIKE ''' + @pPrimarySvrName + '''
      and    usg.dbid = db.dbid
      and    usg.vstart between dev.low and dev.high
      order by
             usg.xserver_name
            ,usg.vstart
   ')
   end
ELSE  ---- Integrity problem, play report generation safe.
   begin

   EXECUTE(
   '
   Set nocount off

   SELECT
             ''Usages''             as ''InfoType ''
            ,CASE
               When usg.xfallback_vstart is not null Then ''YES''
               When usg.xfallback_vstart is     null Then ''no''
             END
                                    as ''Active''
            ,usg.xserver_name       as ''PrimaryServerName''
            ,usg.xfallback_vstart   as ''FallbackVstart''
            ,usg.xdttm_ins          as ''DateEnrolled''
            ,usg.xdttm_last_ins_upd as ''DateLastUpd''
            ,usg.dbid               as ''DBIdOnPrimaryServer''
            ,usg.vstart             as ''VstartOnPrimaryServer''
      from
             master..spt_fallback_usg  usg
      where
             usg.xserver_name   LIKE ''' + @pPrimarySvrName + '''
      order by
             usg.xserver_name
            ,usg.vstart
   ')
   end


IF (@RetCode > 0)
   begin
   SELECT 'sysdb',dbid,name     from master..sysdatabases  order by dbid
   SELECT 'sysusg',dbid,vstart   from master..sysusages     order by dbid,vstart
   SELECT 'sysdev',low,high,name from master..sysdevices
            where cntrltype=0 and status & 2 > 0            order by low
   end


Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_help_db_dev')
go
create procedure sp_fallback_help_db_dev  --1996/03/26 16:04
    @pPrimarySvrName    varchar(30) = null
   ,@pFallbackDrive     varchar( 2) = null
   ,@pDbName            varchar(30) = null
as
/********1*********2*********3*********4*********5*********6*********7**
   Sometimes necessary to run sp_fallback_upd_dev_drive before
running this, to set values matching @pFallbackDrive.

EXAMPLES (too late for 6.5 BooksOnline):
   exec sp_fallback_help_db_dev 'PriSvr2' ,'G:'
   exec sp_fallback_help_db_dev 'PriSvr2' ,'G:' ,null
   exec sp_fallback_help_db_dev 'PriSvr2' ,null ,'DbSaucer'
   exec sp_fallback_help_db_dev 'PriSvr2' ,'G:' ,'DbSaucer' --Two independent reports.
   exec sp_fallback_help_db_dev '%'       ,'%'  ,'%'
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad
      ,@_error                   integer
      ,@int1                     integer
      ,@vc1                      varchar(30)

-----------------------------------

Select
       @RetCode                  = 0

--------------------  Edit parms  --------------------

IF (           @pPrimarySvrName  is null
   OR    (     @pFallbackDrive   is null
         AND   @pDbName          is null
         )
   )
   begin
   RaisError(15393,11,1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


IF (@pFallbackDrive is not null)
   begin

   SELECT
                db.xserver_name     as 'PrimarySvrName'
               ,dev.xfallback_drive as 'FallbackDrive'
               ,db.name             as 'DbName'
               ,dev.name            as 'DevName'
         from
                master..spt_fallback_db      db
               ,master..spt_fallback_dev     dev
               ,master..spt_fallback_usg     usg
         where
                usg.dbid            = db.dbid
         and    usg.vstart between dev.low and dev.high
         and    db.xserver_name     = usg.xserver_name
         and    db.xserver_name     = dev.xserver_name
         and    db.xserver_name     like @pPrimarySvrName
         and    dev.xfallback_drive like @pFallbackDrive
         order by
                db.xserver_name
               ,dev.xfallback_drive
               ,db.name
               ,dev.name
   end


IF (@pDbName is not null)
   begin

   SELECT
                db.xserver_name     as 'PrimarySvrName'
               ,db.name             as 'DbName'
               ,dev.name            as 'DevName'
         from
                master..spt_fallback_db      db
               ,master..spt_fallback_dev     dev
               ,master..spt_fallback_usg     usg
         where
                usg.dbid            = db.dbid
         and    usg.vstart between dev.low and dev.high
         and    db.xserver_name     = usg.xserver_name
         and    db.xserver_name     = dev.xserver_name
         and    db.xserver_name  like @pPrimarySvrName
         and    db.name          like db.name
         order by
                db.xserver_name
               ,db.name
               ,dev.name
   end


LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_activate_svr_db')
go
create procedure sp_fallback_activate_svr_db  --1996/02/20 12:45
    @pPrimarySvrName    character varying(30)   = null
   ,@pDbNamePattern    character varying(44)   = '%'
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server
directly (no RPC).
      This sproc copies info from spt_fallback_% tables into
system tables, for db/dev/usg.
*********1*********2*********3*********4*********5*********6*********7*/

-- Declares will not cause "set implicit_transactions on"
--    to increment @@trancount from 0 to 1.
Declare
       @RetCode                  integer

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_fallback_activate_svr_db')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Set implicit_transactions     off

IF (@@trancount > 0)
   begin
   COMMIT TRANSACTION   -- Decrements @@trancount by 1.
   end

Set nocount        on
Set xact_abort     off
Set ansi_defaults  off
Set ansi_nulls     on
Set dateformat     ymd

Declare
       @ExecRC                   integer
      ,@_error                   integer
      ,@Int1                     integer

Declare
       @ProcStartDtTm            datetime
      ,@CountDbActivated        integer

Declare
       @Fallback_dbid            smallint
      ,@FallbackVdevno           smallint
      ,@Fallback_vstart          integer
      ,@Fallback_low             integer
      ,@Fallback_high            integer
      ,@VdevnoFactor             integer
      ,@OfflineBit               smallint  -- sysdatabases.status
      ,@BitDevDeferred           smallint  -- sysdevices.status
      ,@sysdb_name              character varying(30)

Declare
       @xfallback_dbid           smallint

      ,@db_name                 character varying(30)
      ,@db_dbid                 smallint
      ,@db_status               smallint
      ,@db_version              smallint

Declare
       @xfallback_drive          character(2)

      ,@dev_low                  integer
      ,@dev_high                 integer
      ,@dev_status               smallint
      ,@dev_name                 character varying(30)
      ,@dev_phyname              character varying(127)

Declare
       @usg_dbid                 smallint
      ,@usg_segmap               integer
      ,@usg_lstart               integer
      ,@usg_size                 integer
      ,@usg_vstart               integer

      ,@csr5_dev_name            character varying(30)


-----------------------------------

Select
       @RetCode                  = 0
      ,@VdevnoFactor             = 0x01000000  -- 16777216 2Kb pages is max per dev
      ,@OfflineBit               = 512
      ,@BitDevDeferred           = 8192
      ,@ProcStartDtTm            = getdate()


----------------------  only SA  --------------------------------


IF (suser_id() <> 1)  -- must be SA
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

----------------------  Need to lookup one primary svr?  --------------


IF (@pPrimarySvrName is null)
   begin

   SELECT    @Int1   = count(distinct db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is null

   IF (@Int1 <> 1)
      begin
      RaisError(15344,-1,-1,@Int1)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end

   SELECT    @pPrimarySvrName = min(db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is null

   end


IF (@pDbNamePattern is null)
   Select @pDbNamePattern = '%'


-------------- Verify at least one db from primary svr is enrolled.  ------------


IF not exists
   (
   SELECT       *
      from      master..spt_fallback_db  db
      where     db.xserver_name = @pPrimarySvrName
      and       db.name      like @pDbNamePattern
   )
   begin
   RaisError(15345,-1,-1,@@servername,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


------  Fallback already currently activated for the primary svr/db?  ------
--IF exists (SELECT * from  master..spt_fallback_db db
--                    where db.xfallback_dbid is not null
--                    and   db.xserver_name = @pPrimarySvrName
--                    and   db.name      like @pDbNamePattern
--          )
--   begin
--   RaisError(15346,-1,-1,@@servername,@pPrimarySvrName)
--   Select @RetCode = @@error
--   GOTO LABEL_86_RETURN
--   end


------------------------  Verify db version is a match  ---------------


SELECT
             @Int1            = min(db.version)
      from
             master..spt_fallback_db  db
      where
             db.xserver_name = @pPrimarySvrName
      and    db.name      like @pDbNamePattern

IF exists
   (
   SELECT       *
      from      master..spt_fallback_db  db
      where     db.xserver_name =  @pPrimarySvrName
      and       db.name       like @pDbNamePattern
      and       db.version      <> @Int1
   )
   begin
   RaisError(15347,-1,-1,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


DBCC getvalue('current_version')
Select @_error = @@error

IF (@_error <> @Int1)
   begin
   RaisError(15348,-1,-1,@pPrimarySvrName,@Int1,@@servername,@_error)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


---------------  Look for foreseeable conflicts  --------------

--------

IF exists
      (
      SELECT          *
         from
                      master..spt_fallback_dev     dev
                     ,master..spt_fallback_usg     usg
                     ,master..spt_fallback_db     db
         where
                      dev.xfallback_drive is null             -- Drive info required.
         and          db.xfallback_dbid  is null
         and          db.xserver_name    = @pPrimarySvrName
         and          dev.xserver_name    = @pPrimarySvrName
         and          usg.xserver_name    = @pPrimarySvrName
         and          db.name         like @pDbNamePattern
         and          db.dbid            = usg.dbid
         and          usg.vstart between dev.low and dev.high
      )
   begin
   RaisError(15350,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

--------

IF exists
      (
      SELECT          *
         from
                      master..spt_fallback_dev     dev
                     ,master..spt_fallback_usg     usg
                     ,master..spt_fallback_db     db
                     ,master..sysdevices           sysdev
         where
                      dev.name            = sysdev.name        -- Unique?
         and          db.xserver_name    = @pPrimarySvrName
         and          dev.xserver_name    = @pPrimarySvrName
         and          usg.xserver_name    = @pPrimarySvrName
         and          db.name         like @pDbNamePattern
         and          dev.xfallback_low   is null
         and          db.xfallback_dbid  is null
         and          db.dbid            = usg.dbid
         and          usg.vstart between dev.low and dev.high
          )
   begin
   RaisError(15349,-1,-1,@@servername,@pPrimarySvrName,'logical device')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

--------

IF exists
      (
      SELECT          *
         from
                      master..spt_fallback_dev     dev
                     ,master..spt_fallback_usg     usg
                     ,master..spt_fallback_db     db
                     ,master..sysdevices           sysdev
         where
                      dev.xfallback_drive + rtrim(substring(dev.phyname,3,127))
                                          = sysdev.phyname     -- Unique?
         and          db.xserver_name    = @pPrimarySvrName
         and          dev.xserver_name    = @pPrimarySvrName
         and          usg.xserver_name    = @pPrimarySvrName
         and          db.name         like @pDbNamePattern
         and          dev.xfallback_low   is null
         and          db.xfallback_dbid  is null
         and          db.dbid            = usg.dbid
         and          usg.vstart between dev.low and dev.high
          )
   begin
   RaisError(15349,-1,-1,@@servername,@pPrimarySvrName,'physical device')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end



---------------------------  Establish cursors  -----------------------


-------- csr db

DECLARE
                csr_3_db
                insensitive
            cursor for
   SELECT
                db.name
               ,db.dbid
               ,db.status
               ,db.version
      from
                master..spt_fallback_db     db
      where
                db.xserver_name    = @pPrimarySvrName
      and       db.name         like @pDbNamePattern
      and       db.xfallback_dbid  is null
   FOR read only

Open csr_3_db


-------- csr dev

DECLARE
                csr_4_dev
                insensitive
            cursor for
   SELECT
      distinct
                dev.xfallback_drive

               ,dev.low
               ,dev.high
               ,dev.status
               ,dev.name
               ,dev.phyname
      from
                master..spt_fallback_dev     dev
               ,master..spt_fallback_db     db
               ,master..spt_fallback_usg     usg
      where
                dev.xfallback_low   is null
      and       usg.xserver_name    = @pPrimarySvrName
      and       dev.xserver_name    = @pPrimarySvrName
      and       db.xserver_name    = @pPrimarySvrName
      and       db.dbid            = usg.dbid
      and       db.name         like @pDbNamePattern
      and       db.xfallback_dbid  is null
      and       usg.vstart between dev.low and dev.high
   FOR read only

Open csr_4_dev


-------- csr usg (w/dev)

DECLARE
                csr_5_usg
                insensitive
            cursor for
   SELECT
                usg.dbid
               ,usg.segmap
               ,usg.lstart
               ,usg.sizepg
               ,usg.vstart

               ,dev.name
      from
                master..spt_fallback_dev     dev
               ,master..spt_fallback_db     db
               ,master..spt_fallback_usg     usg
      where
                usg.xserver_name    = @pPrimarySvrName
      and       dev.xserver_name    = @pPrimarySvrName
      and       db.xserver_name    = @pPrimarySvrName
      and       db.dbid            = usg.dbid
      and       db.name         like @pDbNamePattern
      and       db.xfallback_dbid  is null
      and       usg.vstart between dev.low and dev.high
   FOR read only

Open csr_5_usg  --Cannot delay this.


-------- Online/db

DECLARE
                csr_6_online
                insensitive
            cursor for
   SELECT
                db.xfallback_dbid
               ,sysdb.name
      from
                master..spt_fallback_db     db
               ,master..sysdatabases         sysdb
      where
                db.xfallback_dbid  = sysdb.dbid
      and       db.xserver_name    = @pPrimarySvrName
      and       db.name         like @pDbNamePattern
      and       db.xdttm_last_ins_upd = @ProcStartDtTm
   FOR read only


---------------------  Work temp # tab for dynamic exec  ---------------

CREATE table #tab1_fb_act_exec (int1 integer not null)


-----------------------  Verify integrity, before txn  ---------------

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC > 0)
   Execute sp_fallback_help

-------------------------------------------------------  Txn


BEGIN TRANSACTION   -- Increments @@trancount by 1.


---------------------  Populate system with  db  info  ---------------------

WHILE (3=3)
   begin


   FETCH
                next
      from
                csr_3_db
      into
                @db_name
               ,@db_dbid
               ,@db_status
               ,@db_version

   IF (@@fetch_status <> 0)
      begin
      Close csr_3_db

      IF (@@fetch_status = -1)
         begin
         BREAK
         end

      RaisError(15351,-1,31,@@fetch_status,'csr_3_')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN

      end


----------  Calculate next available dbid on fallback svr.


   Select @Fallback_dbid = null

   SELECT
                @Fallback_dbid            = min(a_sysdb.dbid) + 1
         from
                master..sysdatabases      a_sysdb
         where
                a_sysdb.dbid             < 32767
         and    not exists
                  (
                   SELECT * from  master..sysdatabases b_sysdb
                            where b_sysdb.dbid = a_sysdb.dbid + 1
                  )


   UPDATE       master..spt_fallback_db
         set
                xdttm_last_ins_upd  = @ProcStartDtTm
               ,xfallback_dbid      = @Fallback_dbid
         where
                xserver_name        = @pPrimarySvrName
         and    dbid                = @db_dbid
         and    name                = @db_name


   INSERT    into   master..sysdatabases
            (
             name
            ,dbid
            ,suid
            ,mode

            ,status
            ,version
            ,logptr
            ,crdate

            ,dumptrdate
            ,category
            )
      values
            (
             @db_name
            ,@Fallback_dbid
            ,1
            ,0

            ,(@db_status | @OfflineBit)  -- Will turn off offline below.
            ,@db_version
            ,0
            ,getdate()

            ,'1944/12/28'
            ,null
            )

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      RaisError(15352,-1,-1,'db ins 1')
      Select @RetCode = @_error  -- More meaningful than @@error.
      Rollback Transaction   -- Resets @@trancount = 0.
      GOTO LABEL_86_RETURN
      end

   end  -- loop 3=3 db



---------------------  Populate system with  dev  info  ---------------------

WHILE (4=4)
   begin


   FETCH
                next
      from
                csr_4_dev
      into
                @xfallback_drive

               ,@dev_low
               ,@dev_high
               ,@dev_status
               ,@dev_name
               ,@dev_phyname

   IF (@@fetch_status <> 0)
      begin
      Close csr_4_dev

      IF (@@fetch_status = -1)
         begin
         BREAK
         end

      RaisError(15351,-1,41,@@fetch_status,'csr_4_')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN

      end


----------  Calculate next available vdevno/low on fallback svr.


   Select @FallbackVdevno = null

   SELECT
                @FallbackVdevno           =
                              (min(a_sysdev.low) / @VdevnoFactor) + 1
         from
                master..sysdevices        a_sysdev
         where
               (a_sysdev.low / @VdevnoFactor) between 0 and 254
         and    not exists
                  (SELECT * from  master..sysdevices b_sysdev
                            where (b_sysdev.low / @VdevnoFactor) =
                                  (a_sysdev.low / @VdevnoFactor) + 1
                  )


-------- Now can calculate adjusted low & high.
--------    (Later usg.vstart must be adjusted to match!)
--------    Works for vdevno between 128 and 255 too (negative low).

   Select @Fallback_low  = @VdevnoFactor * @FallbackVdevno
   Select @Fallback_high = @Fallback_low + (@dev_high - @dev_low)


   UPDATE       master..spt_fallback_dev
         set
                xdttm_last_ins_upd  = @ProcStartDtTm
               ,xfallback_low       = @Fallback_low
         where
                xserver_name        = @pPrimarySvrName
         and    low                 = @dev_low
         and    name                = @dev_name


   INSERT    into   master..sysdevices
            (
             low
            ,high
            ,status
            ,cntrltype

            ,name
            ,phyname
            ,mirrorname
            ,stripeset
            )
      values
            (
             @Fallback_low
            ,@Fallback_high
            ,(2 + @BitDevDeferred)  -- Physical disk ,Deferred
            ,0

            ,@dev_name
            ,(@xfallback_drive + substring(@dev_phyname,3,125))
            ,null
            ,null
            )

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      RaisError(15352,-1,-1,'dev ins 1')
      Select @RetCode = @_error  -- More meaningful than @@error.
      Rollback Transaction   -- Resets @@trancount = 0.
      GOTO LABEL_86_RETURN
      end

   end  -- loop 4=4 dev



---------------------  Populate system with  usg  info  ---------------------

WHILE (5=5)
   begin


   FETCH
                next
      from
                csr_5_usg
      into
                @usg_dbid
               ,@usg_segmap
               ,@usg_lstart
               ,@usg_size
               ,@usg_vstart

               ,@csr5_dev_name

   IF (@@fetch_status <> 0)
      begin
      Close csr_5_usg

      IF (@@fetch_status = -1)
         begin
         BREAK
         end

      RaisError(15351,-1,51,@@fetch_status,'csr_5_')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN

      end


-------------------  Lookup fallback dbid  -----------------------


   Select @Fallback_dbid = null

   SELECT
                @Fallback_dbid            = sysdb.dbid
         from
                master..sysdatabases      sysdb
               ,master..spt_fallback_db  db
               ,master..spt_fallback_usg  usg
         where
                usg.vstart                = @usg_vstart
         and    usg.xserver_name          = @pPrimarySvrName
         and    db.xserver_name          = @pPrimarySvrName
         and    db.name               like @pDbNamePattern
         and    db.dbid                  = usg.dbid
         and    db.name                  = sysdb.name


----------  Calculate vstart to match dev.low on fallback svr.


   Select @Fallback_vstart = null

   SELECT
                @Fallback_vstart          =
                           usg.vstart + (sysdev.low - dev.low)
         from
                master..sysdevices        sysdev

               ,master..spt_fallback_usg  usg
               ,master..spt_fallback_dev  dev
         where
                dev.xserver_name          = @pPrimarySvrName
         and    usg.vstart                = @usg_vstart
         and    usg.xserver_name          = @pPrimarySvrName
         and
                sysdev.name               = dev.name
         and    usg.vstart between dev.low and dev.high


   UPDATE       master..spt_fallback_usg
         set
                xdttm_last_ins_upd  = @ProcStartDtTm
               ,xfallback_vstart    = @Fallback_vstart
         where
                xserver_name        = @pPrimarySvrName
         and    vstart              = @usg_vstart


   INSERT    into   master..sysusages
            (
             dbid
            ,segmap
            ,lstart
            ,size
            ,vstart
            )
      values
            (
             @Fallback_dbid
            ,@usg_segmap
            ,@usg_lstart
            ,@usg_size
            ,@Fallback_vstart
            )

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      RaisError(15352,-1,-1,'usg ins 1')
      Select @RetCode = @_error  -- More meaningful than @@error.
      Rollback Transaction   -- Resets @@trancount = 0.
      GOTO LABEL_86_RETURN
      end

   end  -- loop 5=5 usg


-----------------------  Online & Prepare sysdb's  ------------------


COMMIT TRANSACTION   -- Decrements @@trancount by 1.


Select @CountDbActivated = 0

OPEN csr_6_online  --This open must wait until now.


WHILE ('6a'='6a')
   begin


   FETCH
                next
      from
                csr_6_online
      into
                @xfallback_dbid
               ,@sysdb_name

   IF (@@fetch_status <> 0)
      begin
      Close csr_6_online

      IF (@@fetch_status = -1)
         begin
         BREAK
         end

      RaisError(15351,-1,61,@@fetch_status,'csr_6_ a')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN

      end

   Select @CountDbActivated = @CountDbActivated + 1


   Execute @ExecRC = sp_dboption @sysdb_name ,'offline' ,'false'


   DELETE from #tab1_fb_act_exec

   ---- Fix sysdatabases.logptr
   EXECUTE(
   '
   Use ' + @sysdb_name + '

   Declare @ex_logptr integer

   Select          @ex_logptr    = min(idx.first)
         from      sysindexes    idx
                  ,sysobjects    obj
         where     obj.type      = ''S ''
         and       obj.name      = ''syslogs''
         and       idx.id        = obj.id
         and       idx.indid     in (0,1) -- Should be 0 in 4.2-6.5

   INSERT into #tab1_fb_act_exec (int1) values (@ex_logptr)

   --Use master  -- Unnecessary in 6.5, should automatically revert (unlike 6.0).
   ')

   SELECT @Int1 = min(tab1.int1) from #tab1_fb_act_exec tab1

   UPDATE          master..sysdatabases
         set       logptr  = @Int1
         where     name    = @sysdb_name

   end  -- loop 6a=6a online & prepare/db


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


-------- Re-Verify integrity, before commit

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'activate s d 2')  -- Do NOT internationalize these.
   Select @RetCode = @ExecRC
   Execute sp_fallback_help
   GOTO LABEL_86_RETURN
   end


Raiserror(15374,-1,-1,@CountDbActivated,@pPrimarySvrName)


LABEL_86_RETURN:

IF (object_id('tempdb..#tab1_fb_act_exec') is not null)
            drop table #tab1_fb_act_exec

Deallocate csr_3_db
Deallocate csr_4_dev
Deallocate csr_5_usg
Deallocate csr_6_online

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_activate_svr')
go
create procedure sp_fallback_activate_svr  --1996/02/14 12:22
    @pPrimarySvrName    character varying(30)   = null
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc is a mere shell for the newer _db extension version.
      This 6.5_beta name is still in shipped version only to
assist Compaq who was shown this name.  DEC & WinNT fallback
offerings will be shown only the _db extension version.  This mere
shell sproc will likely be discontinued in post 6.5 release.

      This sproc should be executed on the fallback server
directly (no RPC).
*********1*********2*********3*********4*********5*********6*********7*/

-- Declares will not cause "set implicit_transactions on"
--    to increment @@trancount from 0 to 1.
Declare
       @RetCode                  integer

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_fallback_activate_svr')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Set implicit_transactions     off

IF (@@trancount > 0)
   begin
   COMMIT TRANSACTION   -- Decrements @@trancount by 1.
   end

Set nocount        on
Set xact_abort     off
Set ansi_defaults  off
Set ansi_nulls     on
Set dateformat     ymd

Declare
       @ExecRC                   integer

Execute @ExecRC = sp_fallback_activate_svr_db @pPrimarySvrName ,'%'

Select @RetCode = @ExecRC

LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_deactivate_svr_db')
go
create procedure sp_fallback_deactivate_svr_db  --1996/02/29 11:06
    @pPrimarySvrName    character varying(30)   = null
   ,@pDbNamePattern    character varying(44)   = '%'
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server
(no RPC).
      This sproc will delete rows from system tables, and make
a will update the spt_fallback_% tables.
      As far as possible, this sproc is designed to overcome
small activation discrepancies and achieve the intended result.
*********1*********2*********3*********4*********5*********6*********7*/

Declare
       @RetCode                  integer

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_fallback_deactivate_svr_db')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Set implicit_transactions     off

IF (@@trancount > 0)
   begin
   COMMIT TRANSACTION   -- Decrements @@trancount by 1.
   end

Set nocount                   on
Set ansi_nulls                on
Set cursor_close_on_commit    off
Set xact_abort                off

Declare
       @ExecRC                   integer
      ,@_error                   integer
      ,@ProcStartDtTm            datetime
      ,@Int1                     integer
      ,@BitDbOffline            integer

Declare
       @xfallback_dbid           smallint

      ,@db_name                 character varying(30)
      ,@db_dbid                 smallint

-----------------------------------

Select
       @RetCode                  = 0
      ,@ProcStartDtTm            = getdate()
      ,@BitDbOffline            = 512


----------------------  only SA  --------------------------------


IF (suser_id() <> 1)  -- must be SA
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

----------------------  Need to lookup one primary svr?  --------------


IF (@pPrimarySvrName is null)
   begin

   SELECT    @Int1   = count(distinct db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is not null

   IF (@Int1 <> 1)
      begin
      RaisError(15344,-1,-1,@Int1)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end

   SELECT    @pPrimarySvrName = min(db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is not null

   end

------------------  Handle db parm  ------------------------

IF (@pDbNamePattern is null)
   Select @pDbNamePattern = '%'


------  Fallback already currently deactivated for the primary server?

IF not exists (SELECT * from  master..spt_fallback_db db
                    where db.xfallback_dbid is not null
                    and   db.xserver_name = @pPrimarySvrName
                    and   db.name      like @pDbNamePattern
              )
   begin
   RaisError(15353,-1,-1,@@servername,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


---------------  Calculate a list of possible sysdev's to delete  -----------


---- Capture devs containing to-be-deact dbs.
Create table #1dev_deact
   (low             integer     not null
   ,xfallback_low   integer     not null
   ,name            varchar(30) not null
   )

INSERT into #1dev_deact
               (low ,xfallback_low ,name)
   SELECT
         distinct
                dev.low ,dev.xfallback_low ,dev.name
         from   master..spt_fallback_dev  dev
               ,master..spt_fallback_usg  usg
               ,master..spt_fallback_db  db
         where  db.dbid           = usg.dbid
         and    usg.vstart between dev.low and dev.high
         and    db.xserver_name = usg.xserver_name
         and    db.xserver_name = dev.xserver_name
         and
                db.xserver_name = @pPrimarySvrName
         and    db.name      like @pDbNamePattern
         and    db.xfallback_dbid   is not null
         and    usg.xfallback_vstart is not null
         and    dev.xfallback_low    is not null


---- Capture devs containing dbs other than dbs to-be-deact.
Create table #2sysdev_othersuse
   (low        integer     not null
   ,name       varchar(30) not null
   )

INSERT into #2sysdev_othersuse
               (low ,name)
   SELECT
         distinct
                sysdev.low ,sysdev.name
         from   master..sysdevices        sysdev
               ,master..sysusages         sysusg
               ,master..sysdatabases      sysdb
         where  sysdb.dbid      = sysusg.dbid
         and    sysusg.vstart between sysdev.low and sysdev.high
         and    not exists
                  (SELECT      *
                     from      master..spt_fallback_db  db
                     where     db.xserver_name    = @pPrimarySvrName
                     and       db.name      like    @pDbNamePattern
                     and       db.xfallback_dbid  is not null
                     and       db.xfallback_dbid  = sysdb.dbid
                  )


---- Remove some devs from the list of devs to-be-deact.
DELETE          #1dev_deact
      where     xfallback_low in
                  (SELECT low from #2sysdev_othersuse
                  )

---------------------------  Establish cursors  -----------------------


-------- csr sysdb

DECLARE
                csr_11_db
                insensitive
            cursor for
   SELECT
                db.xfallback_dbid
               ,db.dbid
               ,db.name
      from
                master..spt_fallback_db     db
      where
                db.xserver_name    = @pPrimarySvrName
      and       db.name         like @pDbNamePattern
      and       db.xfallback_dbid  is not null
   FOR read only


---------------------  Take each relevant db offline  ------------------


OPEN csr_11_db


WHILE ('11a'='11a')
   begin


   FETCH
                next
      from
                csr_11_db
      into
                @xfallback_dbid
               ,@db_dbid
               ,@db_name

   IF (@@fetch_status <> 0)
      begin
      Close csr_11_db  -- Will use this again.
      BREAK
      end

----------

   IF not exists   (
         SELECT       *
            from      master..sysdatabases   sysdb
            where     sysdb.dbid = @db_dbid
            and       sysdb.status & @BitDbOffline = 0  --currently is online
                  )
      begin

      CONTINUE

      end


   Execute @ExecRC = sp_dboption @db_name ,'offline' ,'true' --Also defers unshared sysdev.

   IF (@ExecRC <> 0)
      begin
      RaisError(15355,-1,-1,@db_name)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end

   end -- loop 11a db

---------------------------------------------- txn

BEGIN TRANSACTION  -- @@trancount++;


---------------------  Delete sys% tables rows  ---------------


OPEN csr_11_db


WHILE ('11b'='11b')
   begin


   FETCH
                next
      from
                csr_11_db
      into
                @xfallback_dbid
               ,@db_dbid
               ,@db_name

   IF (@@fetch_status <> 0)
      begin
      Close csr_11_db
      BREAK
      end


-------- Handle usg.

   DELETE       master..sysusages
         where
                dbid    = @xfallback_dbid


   UPDATE       master..spt_fallback_usg
         set
                xdttm_last_ins_upd  = @ProcStartDtTm
               ,xfallback_vstart    = null
         where
                xserver_name        = @pPrimarySvrName
         and    dbid                = @db_dbid


-------- Handle db.

   DELETE       master..sysdatabases
         where
                dbid    = @xfallback_dbid


   UPDATE       master..spt_fallback_db
         set
                xdttm_last_ins_upd  = @ProcStartDtTm
               ,xfallback_dbid      = null
         where
                xfallback_dbid      = @xfallback_dbid

   end -- loop 11b db


--------------------  Del all corresponding dev  ---------------------


---- Del sysdevs whose children were all just deactivated.

DELETE       master..sysdevices
      where
             name in
               (SELECT name from #1dev_deact)
      and    low  in
               (SELECT xfallback_low from #1dev_deact)
      and    not exists
               (SELECT      *
                  from      master..sysusages   sysusg
                  where     sysusg.vstart between
                              master..sysdevices.low  and
                              master..sysdevices.high
               )

UPDATE       master..spt_fallback_dev
      set
             xdttm_last_ins_upd  = @ProcStartDtTm
            ,xfallback_low       = null
      where
             xserver_name        = @pPrimarySvrName
      and    xfallback_low  is not null
      and
             low in (SELECT low from #1dev_deact)


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


----------  Re-Verify integrity, before commit

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'deactivate s d 2')  -- Do NOT internationalize these.
   Select @RetCode = @ExecRC
   Execute sp_fallback_help
   Rollback Transaction
   GOTO LABEL_86_RETURN
   end


COMMIT TRANSACTION


Raiserror(15356,-1,-1,@pPrimarySvrName)


LABEL_86_RETURN:

Deallocate csr_11_db

IF (object_id('tempdb..#1dev_deact') is not null)
            drop table #1dev_deact
IF (object_id('tempdb..#2sysdev_othersuse') is not null)
            drop table #2sysdev_othersuse

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_deactivate_svr')
go
create procedure sp_fallback_deactivate_svr  --1996/02/14 12:12
    @pPrimarySvrName    character varying(30)   = null
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc is a mere shell for the newer _db extension version.
      This 6.5_beta name is still in shipped version only to
assist Compaq who was shown this name.  DEC & WinNT fallback
offerings will be shown only the _db extension version.  This mere
shell sproc will likely be discontinued in post 6.5 release.

      This sproc should be executed on the fallback server
directly (no RPC).
*********1*********2*********3*********4*********5*********6*********7*/

Declare
       @RetCode                  integer

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_fallback_deactivate_svr')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Set implicit_transactions     off

IF (@@trancount > 0)
   begin
   COMMIT TRANSACTION   -- Decrements @@trancount by 1.
   end

Set nocount                   on
Set ansi_nulls                on
Set cursor_close_on_commit    off
Set xact_abort                off

Declare
       @ExecRC                   integer


Execute @ExecRC = sp_fallback_deactivate_svr_db @pPrimarySvrName ,'%'

Select @RetCode = @ExecRC

LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_enroll_svr_db')
go
create procedure sp_fallback_enroll_svr_db  --1996/02/29 11:02
    @pPrimarySvrName  character varying(30)  -- Name of any one primary svr.
   ,@pDbName         character varying(30)  -- Local db, on primary svr.
as
/********1*********2*********3*********4*********5*********6*********7**
Fallback/Failover:
      This sproc must be executed on the fallback server,
as it will issue RPCs to the primary server to
execute some other sprocs there.
*********1*********2*********3*********4*********5*********6*********7*/

-- Declares will not cause "set implicit_transactions on"
--    to increment @@trancount from 0 to 1.
Declare
       @RetCode                  integer

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_fallback_enroll_svr_db')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Set implicit_transactions     off

IF (@@trancount > 0)
   begin
   COMMIT TRANSACTION   -- Decrements @@trancount by 1.
   end

Set nocount        on
Set xact_abort     off
Set ansi_defaults  off
Set ansi_nulls     on
Set dateformat     ymd

Declare
       @ExecRC                   integer
      ,@_error                   integer
      ,@_rowcount                integer
      ,@int1                     integer
      ,@vc1                      character varying(100)
      ,@ProcStartDtTm            datetime

Declare
       @db_dbid                 smallint
      ,@db_status               smallint
      ,@db_version              smallint

      ,@usg_segmap               integer
      ,@usg_lstart               integer
      ,@usg_size                 integer
      ,@usg_vstart               integer

      ,@dev_low                  integer
      ,@dev_high                 integer
      ,@dev_status               smallint
      ,@dev_name                 character varying(30)
      ,@dev_phyname              character varying(127)


--------

Select
       @RetCode                  = 0
      ,@ProcStartDtTm            = getdate()


----------------------  only SA  --------------------------------

IF (suser_id() <> 1)  -- must be SA
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


--------------------  Edit primary svr parm  ---------------

IF (@pPrimarySvrName is null)
   begin
   RaisError(15344,-1,-1,0)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

-----------------------  Ensure db not already enrolled  --------------

IF exists
      (SELECT * from  master..spt_fallback_db
                where xserver_name = @pPrimarySvrName
                and   name         = @pDbName
      )
   begin
   RaisError(15380,-1,-1,@pDbName,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


-----------------------  Exclude special db's  ---------------------

IF (lower(@pDbName) in ('master','model','tempdb','msdb'))
   begin
   RaisError(15385,-1,-1,@pDbName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end



-------------------  Ensure integrity is clean to start  ----------------

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'enroll verify 1')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


-------------------  Simplify usages  ------------------------------

Execute sp_coalesce_fragments '%'


Select @vc1 = @pPrimarySvrName + '...sp_coalesce_fragments'  -- RPC

Execute @ExecRC = @vc1 '%'

Select @_error = @@error

IF (     @ExecRC  <> 0
   OR    @@error  <> 0
   )
   begin
   RaisError(15360,-1,-1,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


-------------------  RPC to gather db info from primary  ----------------


Select @vc1 = @pPrimarySvrName + '...sp_fallback_MS_enroll_db'

Execute @ExecRC = @vc1
             @@servername
            ,@pDbName
               ,@db_dbid     OUTPUT
               ,@db_status   OUTPUT
               ,@db_version  OUTPUT

Select @_error = @@error

IF (     @ExecRC  <> 0
   OR    @@error  <> 0
   )
   begin
   RaisError(15362,-1,-1,'database')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

IF (@db_dbid is null)
   begin
   RaisError(15361,-1,-1,@pDbName,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


------------------  Get internal db version number  ------------------

DBCC getvalue('current_version')
Select @_error = @@error

IF (@_error <> @db_version)
   begin
   RaisError(15364,-1,-1,@pPrimarySvrName,@pDbName
                        ,@db_version,@@servername,@_error)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

---------------------------------------------- txn


BEGIN TRANSACTION


------------------------  Store db info  ------------------------


INSERT       into   master..spt_fallback_db
            (
             xserver_name
            ,xdttm_ins
            ,xdttm_last_ins_upd
            ,xfallback_dbid

            ,name
            ,dbid
            ,status
            ,version
            )
      values
            (
             @pPrimarySvrName
            ,@ProcStartDtTm
            ,@ProcStartDtTm
            ,null

            ,@pDbName
            ,@db_dbid
            ,@db_status
            ,@db_version
            )

Select @_error = @@error

IF (@_error <> 0)
   begin
   Select @RetCode = @_error
   Rollback Transaction
   GOTO LABEL_86_RETURN
   end


---------  Handle self-enrollment db.

IF (@pPrimarySvrName = @@servername)
   begin

   UPDATE       master..spt_fallback_db
      set       xfallback_dbid   = dbid
      where     xdttm_ins        = xdttm_last_ins_upd
      and       xdttm_ins        = @ProcStartDtTm

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      Select @RetCode = @_error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end
   end


----------------  RPC to get usg info  --------------------------------


Select @vc1 = @pPrimarySvrName + '...sp_fallback_MS_enroll_usg'

Select @usg_vstart = -1

WHILE ('usg1'='usg1')
   begin

   Execute @ExecRC = @vc1
                @db_dbid
                  ,@usg_segmap  OUTPUT
                  ,@usg_lstart  OUTPUT
                  ,@usg_size    OUTPUT
                  ,@usg_vstart  OUTPUT

   Select @_error = @@error

   IF (     @ExecRC   > 0
      OR    @_error  <> 0
      )
      begin
      RaisError(15362,-1,-1,'usages')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end

   IF (@usg_lstart is null)
      begin
      BREAK
      end


   INSERT    into   master..spt_fallback_usg
            (
             xserver_name
            ,xdttm_ins
            ,xdttm_last_ins_upd
            ,xfallback_vstart

            ,dbid
            ,segmap
            ,lstart
            ,sizepg
            ,vstart
            )
      values
            (
             @pPrimarySvrName
            ,@ProcStartDtTm
            ,@ProcStartDtTm
            ,null

            ,@db_dbid
            ,@usg_segmap
            ,@usg_lstart
            ,@usg_size
            ,@usg_vstart
            )

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      Select @RetCode = @_error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end

   end  --loop usg1


---------  Handle self-enrollment usg.

IF (@pPrimarySvrName = @@servername)
   begin

   UPDATE       master..spt_fallback_usg
      set       xfallback_vstart = vstart
      where     xdttm_ins        = xdttm_last_ins_upd
      and       xdttm_ins        = @ProcStartDtTm

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      Select @RetCode = @_error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end
   end


----------------  RPC to get dev info  --------------------------------


Select @vc1 = @pPrimarySvrName + '...sp_fallback_MS_enroll_dev'

Select @dev_name = char(0x00)

WHILE ('dev2'='dev2')
   begin

   Execute @ExecRC = @vc1
                @db_dbid
                  ,@dev_low      OUTPUT
                  ,@dev_high     OUTPUT
                  ,@dev_status   OUTPUT
                  ,@dev_name     OUTPUT
                  ,@dev_phyname  OUTPUT

   Select @_error = @@error

   IF (     @ExecRC   > 0
      OR    @_error  <> 0
      )
      begin
      RaisError(15362,-1,-1,'devices')
      Select @RetCode = @@error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end

   IF (@dev_high is null)
      begin
      BREAK
      end


   IF exists
         (SELECT      *
            from      master..spt_fallback_dev  dev
            where     dev.xserver_name    = @pPrimarySvrName
            and       dev.low             = @dev_low
         )
      begin
      CONTINUE
      end


   INSERT    into   master..spt_fallback_dev
            (
             xserver_name
            ,xdttm_ins
            ,xdttm_last_ins_upd
            ,xfallback_drive

            ,low
            ,high
            ,status
            ,name
            ,phyname
            )
      values
            (
             @pPrimarySvrName
            ,@ProcStartDtTm
            ,@ProcStartDtTm
            ,null

            ,@dev_low
            ,@dev_high
            ,@dev_status
            ,@dev_name
            ,@dev_phyname
            )

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      Select @RetCode = @_error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end

   end  --loop dev2


---------  Handle self-enrollment dev.

IF (@pPrimarySvrName = @@servername)
   begin

   UPDATE       master..spt_fallback_dev
      set       xfallback_low    = low
               ,xfallback_drive  = substring(phyname,1,2)
      where     xdttm_ins        = xdttm_last_ins_upd
      and       xdttm_ins        = @ProcStartDtTm

   Select @_error = @@error

   IF (@_error <> 0)
      begin
      Select @RetCode = @_error
      Rollback Transaction
      GOTO LABEL_86_RETURN
      end
   end


------------------  Re-ensure integrity  --------------------

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   Select @RetCode = 1
   Rollback Transaction
   GOTO LABEL_86_RETURN
   end


--------------------

COMMIT TRANSACTION

Raiserror(15375,-1,-1,@pDbName,@pPrimarySvrName)

LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_permanent_svr')
go
create procedure sp_fallback_permanent_svr  --1996/01/27 15:12
    @pPrimarySvrName character varying(30)   = null
   ,@pGeneralOptions integer                 = 0
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer
      ,@ExecRC                   integer
      ,@_error                   integer
      ,@Int1                     integer
---------
Select
       @RetCode                  = 0

-------------------------  Edit override parm  --------------------

IF (@pGeneralOptions is null)
   Select @pGeneralOptions = 0

IF (@pGeneralOptions & 1 = 0)  -- Bit 1 ON means "Yes I really want to do this."
   begin
   RaisError(15376,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


----------------------  Need to lookup one primary svr?  --------------


IF (@pPrimarySvrName is null)
   begin

   SELECT    @Int1   = count(distinct db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is null

   IF (@Int1 <> 1)
      begin
      RaisError(15344,-1,-1,@Int1)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end

   SELECT    @pPrimarySvrName = min(db.xserver_name)
      from   master..spt_fallback_db  db
      where  db.xfallback_dbid        is null

   end


-----------------  Verify the one svr is active  -----------------


IF not exists
   (
   SELECT       *
      from      master..spt_fallback_db  db
      where     db.xserver_name    = @pPrimarySvrName
      and       db.xfallback_dbid  is not null
   )
   begin
   RaisError(15370,-1,-1,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

IF exists
   (
   SELECT       *
      from      master..spt_fallback_db  db
      where     db.xserver_name    = @pPrimarySvrName
      and       db.xfallback_dbid  is     null
   )
   begin
   RaisError(15384,-1,-1,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


-----------------------  Verify integrity, before txn  ---------------


Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'permanent 1')  -- Do NOT internationalize these.
   Select @RetCode = @ExecRC
   Execute sp_fallback_help
   GOTO LABEL_86_RETURN
   end


-----------------  Simply delete from the spt_fallback_% tables  ------------

BEGIN TRANSACTION


DELETE       master..spt_fallback_usg
      where  xserver_name     = @pPrimarySvrName


DELETE       master..spt_fallback_db
      where  xserver_name     = @pPrimarySvrName


DELETE       master..spt_fallback_dev
      where  xserver_name     = @pPrimarySvrName


-----------------------  Verify integrity, before commit  ---------------


Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'permanent 2')  -- Do NOT internationalize these.
   Select @RetCode = @ExecRC
   Execute sp_fallback_help
   Rollback Transaction
   GOTO LABEL_86_RETURN
   end


COMMIT TRANSACTION

Raiserror(15377,-1,-1,@pPrimarySvrName,@@servername)

LABEL_86_RETURN:

Return @RetCode
go



raiserror(15339,-1,-1,'sp_fallback_upd_dev_drive')
go
create procedure sp_fallback_upd_dev_drive  --1996/03/20 16:14
    @pPrimarySvrName    character varying(30)
   ,@pPrimaryDrive      character(2)
   ,@pFallbackDrive     character(2)
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad
      ,@_error                   integer
      ,@_rowcount                integer
      ,@ProcStartDtTm            datetime

-------------------------------------

Select
       @RetCode                  = 0
      ,@ProcStartDtTm            = getdate()


----------------------  only SA  --------------------------------


IF (suser_id() <> 1)  -- must be SA
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


--------------------  Foresee name conflicts  --------------------

IF exists
   (
   SELECT       *
      from      master..sysdevices        sysdev
               ,master..spt_fallback_dev  dev
      where     dev.xserver_name          = @pPrimarySvrName
      and       dev.xfallback_low        is null
      and       lower(substring(dev.phyname,1,2)) =
                lower(@pPrimaryDrive)

      and      (@pFallbackDrive + substring(dev.phyname,3,125))
                                          = sysdev.phyname
   )
   begin
   RaisError(15371,-1,-1,@pFallbackDrive,@@servername)
   --Select @RetCode = @@error
   --GOTO LABEL_86_RETURN
   end


------------------------  Upd to new drive  ------------------------


UPDATE       master..spt_fallback_dev
      set
             xdttm_last_ins_upd        = @ProcStartDtTm
            ,xfallback_drive           = @pFallbackDrive
      where
             xserver_name              = @pPrimarySvrName
      and    substring(phyname,1,2)    = @pPrimaryDrive
      and    xfallback_low            is null


Select @_error = @@error ,@_rowcount = @@rowcount

IF (@_error <> 0)
   begin
   RaisError(15352,-1,-1,'sp_fallback_upd_dev_drive 1')
   Select @RetCode = @_error
   GOTO LABEL_86_RETURN
   end

Raiserror(15372,-1,-1,@_rowcount)


LABEL_86_RETURN:

Return @RetCode

go



raiserror(15339,-1,-1,'sp_fallback_withdraw_svr_db')
go
create procedure sp_fallback_withdraw_svr_db  --1996/02/21 14:44
    @pPrimarySvrName    character varying(30)
   ,@pDbNamePattern    character varying(44)   = '%'
as
/********1*********2*********3*********4*********5*********6*********7**
      This sproc should be executed on the fallback server.
*********1*********2*********3*********4*********5*********6*********7*/

Set nocount    on
Set ansi_nulls on

Declare
       @RetCode                  integer  -- 0==good ,>0==bad
      ,@ExecRC                   integer
      ,@_error                   integer
      ,@_rowcount                integer

Declare
       @CountDbWithdrawn        integer
      ,@CountDbStillEnrolled    integer

Declare
       @db_name                 character varying(30)
      ,@db_dbid                 smallint

-----------------------------------

Select
       @RetCode                  = 0
      ,@CountDbWithdrawn        = 0
      ,@CountDbStillEnrolled    = 0


----------------------  only SA  --------------------------------


IF (suser_id() <> 1)  -- must be SA
   begin
   RaisError(15003,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

-----------------------  Verify integrity, before txn  ---------------

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC > 0)
   Execute sp_fallback_help

----------------  Verify fallback is inactive for this primary  --------------


IF exists
      (SELECT * from  master..spt_fallback_db  db
                where db.xserver_name    = @pPrimarySvrName
                and   db.xfallback_dbid  is not null
                and   db.name         like @pDbNamePattern
      )
   begin
   RaisError(15346,-1,-1,@@servername,@pPrimarySvrName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end



BEGIN TRANSACTION


----------------  Capture list of relevant dev's  ------------------

Create table #dev36
   (low        integer     not null
   ,name       varchar(30) not null
   )

INSERT into #dev36
               (    low     ,name)
   SELECT
         distinct
                dev.low ,dev.name
         from   master..spt_fallback_db  db
               ,master..spt_fallback_usg  usg
               ,master..spt_fallback_dev  dev
         where  db.dbid         = usg.dbid
         and    usg.vstart between dev.low and dev.high
         and    db.xserver_name = usg.xserver_name
         and    db.xserver_name = dev.xserver_name
         and    db.xserver_name = @pPrimarySvrName
         and    db.name like @pDbNamePattern
         and    db.xfallback_dbid  is     null
         and    dev.xfallback_low   is     null


------------------------  Del db, governs the loop  ----------------------

----------  Cursor, thru db's

DECLARE
             csr_7_db
             insensitive
         cursor for
   SELECT
             db.name
            ,db.dbid
      from
             master..spt_fallback_db     db
      where
             db.xserver_name    =    @pPrimarySvrName
      and    db.name            like @pDbNamePattern
      and    db.xfallback_dbid is null
   FOR read only

OPEN csr_7_db


WHILE (7=7)
   begin


   FETCH
                next
      from
                csr_7_db
      into
                @db_name
               ,@db_dbid

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


---- Del usg.

   DELETE       master..spt_fallback_usg
         where
                xserver_name   = @pPrimarySvrName
         and    dbid           = @db_dbid


---- Del db.

   DELETE       master..spt_fallback_db
         where
                xserver_name   = @pPrimarySvrName
         and    dbid           = @db_dbid


   Select @CountDbWithdrawn = @CountDbWithdrawn + 1

   end -- loop 7=7 db


---------------------  Clean up dev  ---------------------


---- Del appropriate dev's.

DELETE          master..spt_fallback_dev
         where
                xserver_name        = @pPrimarySvrName
         and    low not in
                  (
                   SELECT      b_dev.low
                     from      master..spt_fallback_dev  b_dev
                              ,master..spt_fallback_usg  b_usg
                     where     b_usg.vstart between b_dev.low and b_dev.high
                     and       b_dev.xserver_name  = b_usg.xserver_name
                     and       b_dev.xserver_name  = @pPrimarySvrName
                  )
         and    low     in
                  (SELECT #dev36.low from #dev36)


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


----------  Verify integrity, before commit

Execute @ExecRC = sp_fallback_MS_verify_ri

IF (@ExecRC <> 0)
   begin
   RaisError(15352,-1,-1,'withdraw 2')  -- Do NOT internationalize these.
   Select @RetCode = @ExecRC
   Execute sp_fallback_help
   Rollback Transaction
   GOTO LABEL_86_RETURN
   end


COMMIT TRANSACTION


--------  FYI How many remain enrolled?


SELECT
             @CountDbStillEnrolled    = count(*)
      from
             master..spt_fallback_db  db
      where
             db.xserver_name          = @pPrimarySvrName


Raiserror(15373,-1,-1,@pPrimarySvrName,@CountDbWithdrawn
                     ,@CountDbStillEnrolled)


LABEL_86_RETURN:

IF (object_id('tempdb..#dev36') is not null)
            drop table #dev36

Return @RetCode
go


---- Bottom_Fallback ("Failover")


raiserror(15339,-1,-1,'sp_validname')
go
CREATE PROCEDURE sp_validname --1996/03/04 13:02
    @name   varchar(30)
AS
/***********************************************************
      This SP can screen out some bad names for things
like syslogins.name.

      This SP cannot aggressively challenge names
values, due to the lack of a code page for the Japanese
(1995/09/11).   Thus all bytes >0x7F will be treated
as DBCS lead bytes (trail byte values not checked).

      Datalength:    Returns number of 8-bit bytes,
not number of characters.

      Substring:     Parm number 2 (of 3) represents the
Nth character (DBCS and/or SBCS), not the Nth 8-bit
byte.   Parm 3 is the number of characters to return,
not the number of bytes to return.

      MS SQL 6.0 identifiers must not exceed 30
8-bit bytes.
***********************************************************/

Set nocount on

--------  This sproc verifies the name is a legal identifier, DBCS or SBCS.

Declare
    @current               int
   ,@last                  int

Declare
    @curchar               tinyint
   ,@atsign                tinyint
   ,@underscore            tinyint
   ,@poundsign             tinyint
   ,@dollarsign            tinyint
   ,@big_A                 tinyint
   ,@small_a               tinyint
   ,@big_Z                 tinyint
   ,@small_z               tinyint
   ,@digit_0               tinyint
   ,@digit_9               tinyint

Declare
    @alpha_s_1             tinyint
   ,@alpha_s_2             tinyint
   ,@alpha_s_3             tinyint

   ,@alpha_2_start         tinyint
   ,@alpha_2_end           tinyint

   ,@alpha_3_start         tinyint
   ,@alpha_3_end           tinyint
   ,@alpha_4_start         tinyint
   ,@alpha_4_end           tinyint
   ,@alpha_5_start         tinyint
   ,@alpha_5_end           tinyint
   ,@alpha_6_start         tinyint
   ,@alpha_6_end           tinyint
   ,@alpha_7_start         tinyint
   ,@alpha_7_end           tinyint

Declare
    @binname               varbinary(30)
   ,@recognized_cp_yn      char(1)
   ,@charset_name          varchar(30)


----------------------------------------


--------  Ensure that the name specified is non-null.


IF (@name is null)
   begin
   raiserror (15004,-1,-1)
   return (1)
   end

Select  @binname = convert(varbinary,@name)


--------  Assign ANSI char ranges.


Select
    @atsign       = ascii('@')
   ,@underscore   = ascii('_')
   ,@poundsign    = ascii('#')
   ,@dollarsign   = ascii('$')
   ,@big_A        = ascii('A')
   ,@small_a      = ascii('a')
   ,@big_Z        = ascii('Z')
   ,@small_z      = ascii('z')
   ,@digit_0      = ascii('0')
   ,@digit_9      = ascii('9')


--------  Get the Character Set ID (csid).


SELECT
             @charset_name    = Min(cs1.name)
      from
             master..syscharsets    cs1  --static row
            ,master..syscharsets    cs2  --row genned by install
      where
             cs1.id           = cs2.csid
      and
             cs1.type         = 1001
      and    cs2.type         = 2001
      and
             cs2.id           =
                  (SELECT      value
                     from      master..sysconfigures
                     where     config  = 1123  --default sortorder id
                  )



--------  Define character hex ranges ("codepoints")  ---------------


----  SBCS values >=0x80 are just for looks, will be treated as DBCS later.


Select @recognized_cp_yn    = 'N'


IF @charset_name = 'iso_1'
   begin
   Select @recognized_cp_yn = 'Y'

   Select
          @alpha_2_start = 0xC0, @alpha_2_end = 0xD6
         ,@alpha_3_start = 0xD8, @alpha_3_end = 0xF6
         ,@alpha_4_start = 0xF8, @alpha_4_end = 0xFF
         ,@alpha_5_start = 0x41, @alpha_5_end = 0x5A
         ,@alpha_6_start = 0x61, @alpha_6_end = 0x7A
         ,@alpha_7_start = 0x61, @alpha_7_end = 0x7A
         ,@alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp850'
   begin
   Select @recognized_cp_yn = 'Y'

   Select
          @alpha_2_start = 0x80, @alpha_2_end = 0x9D
         ,@alpha_3_start = 0xA0, @alpha_3_end = 0xA5
         ,@alpha_4_start = 0xB5, @alpha_4_end = 0xB7
         ,@alpha_5_start = 0xC6, @alpha_5_end = 0xC7
         ,@alpha_6_start = 0xD0, @alpha_6_end = 0xD8
         ,@alpha_7_start = 0xE0, @alpha_7_end = 0xED
         ,@alpha_s_1 = 0xDE, @alpha_s_2 = 0xF4, @alpha_s_3 = 0xF5
   end



IF @charset_name = 'cp437'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x80, @alpha_2_end = 0x9A,
                   @alpha_3_start = 0xA0, @alpha_3_end = 0xA5,
                   @alpha_4_start = 0xE0, @alpha_4_end = 0xEE,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0x61, @alpha_7_end = 0x7A,
                   @alpha_s_1 = 0x9E, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1250'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
                   @alpha_3_start = 0xBE, @alpha_3_end = 0xFF,
                   @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0x8C, @alpha_7_end = 0x8F,
                   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1251'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
                   @alpha_3_start = 0xA1, @alpha_3_end = 0xA3,
                   @alpha_4_start = 0xB2, @alpha_4_end = 0xFF,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0x8C, @alpha_7_end = 0x90,
                   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1253'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0xBE, @alpha_2_end = 0xD1,
                   @alpha_3_start = 0xD3, @alpha_3_end = 0xFE,
                   @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0xB8, @alpha_7_end = 0xBA,
                   @alpha_s_1 = 0xA2, @alpha_s_2 = 0xBC, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1254'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0xD8, @alpha_2_end = 0xFF,
                   @alpha_3_start = 0x9F, @alpha_3_end = 0x9F,
                   @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0xC0, @alpha_7_end = 0xD6,
                   @alpha_s_1 = 0x83, @alpha_s_2 = 0x8A, @alpha_s_3 = 0x9A
   end


IF @charset_name = 'cp1255'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x41, @alpha_2_end = 0x5A,
                   @alpha_3_start = 0x41, @alpha_3_end = 0x5A,
                   @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0xE0, @alpha_7_end = 0xFA,
                   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1256'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x80, @alpha_2_end = 0x9A,
                   @alpha_3_start = 0xA0, @alpha_3_end = 0xA5,
                   @alpha_4_start = 0xE0, @alpha_4_end = 0xEE,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0x61, @alpha_7_end = 0x7A,
                   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end


IF @charset_name = 'cp1257'
   begin
   Select @recognized_cp_yn = 'Y'

   select @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
                   @alpha_3_start = 0xC0, @alpha_3_end = 0xFE,
                   @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
                   @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
                   @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
                   @alpha_7_start = 0x8C, @alpha_7_end = 0x8F,
                   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end



--------  If no code page?


IF (@recognized_cp_yn = 'N')  --Allow anything.
   begin

   Select
          @alpha_2_start = 0x00, @alpha_2_end = 0xFF
         ,@alpha_3_start = 0x00, @alpha_3_end = 0xFF
         ,@alpha_4_start = 0x00, @alpha_4_end = 0xFF
         ,@alpha_5_start = 0x00, @alpha_5_end = 0xFF
         ,@alpha_6_start = 0x00, @alpha_6_end = 0xFF
         ,@alpha_7_start = 0x00, @alpha_7_end = 0xFF
         ,@alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41
   end



----------------------------------------------------------------------
--             Validate the first byte (not first character).
----------------------------------------------------------------------


Select @curchar = convert(tinyint,substring(@binname, 1, 1))


IF (not (   (@curchar between @alpha_2_start and @alpha_2_end)
         or (@curchar between @alpha_3_start and @alpha_3_end)
         or (@curchar between @alpha_4_start and @alpha_4_end)
         or (@curchar between @alpha_5_start and @alpha_5_end)
         or (@curchar between @alpha_6_start and @alpha_6_end)
         or (@curchar between @alpha_7_start and @alpha_7_end)

         or (@curchar >= @big_A    and  @curchar <= @big_Z)
         or (@curchar >= @small_a  and  @curchar <= @small_z)

         or  @curchar  = @alpha_s_1
         or  @curchar  = @alpha_s_2
         or  @curchar  = @alpha_s_3
         or  @curchar  = @poundsign
         or  @curchar  = @underscore

         or  @curchar >= 0x80  --DBCS lead byte a possibility.
        )
   )
   begin
   raiserror(15005,-1,-1,@name)
   return (1)
   end



----------------------------------------------------------------------
--          Now validate remaining bytes (DBCS lead byte sensitive).
----------------------------------------------------------------------


Select
    @current   = 1
   ,@last      = datalength(@name)


-- Now check the rest of the characters.

-------------------------
WHILE (@current <= @last)
   begin

   select @curchar = convert(tinyint,substring(@binname, @current, 1))


   if (    @current > 1
       AND
            (not (  (@curchar between @alpha_2_start and @alpha_2_end)
                 or (@curchar between @alpha_3_start and @alpha_3_end)
                 or (@curchar between @alpha_4_start and @alpha_4_end)
                 or (@curchar between @alpha_5_start and @alpha_5_end)
                 or (@curchar between @alpha_6_start and @alpha_6_end)
                 or (@curchar between @alpha_7_start and @alpha_7_end)

                 or (@curchar >= @big_A    and  @curchar <= @big_Z)
                 or (@curchar >= @small_a  and  @curchar <= @small_z)

                 or  @curchar  = @alpha_s_1
                 or  @curchar  = @alpha_s_2
                 or  @curchar  = @alpha_s_3
                 or  @curchar  = @poundsign
                 or  @curchar  = @underscore

                 or  @curchar >= 0x80  --DBCS

                 or  @curchar  = @atsign
                 or  @curchar  = @dollarsign
                 or (@curchar >= @digit_0  and  @curchar <= @digit_9)
                 )
            )
      )
      begin
      raiserror(15006,-1,-1,@name)
      return (1)
      end


   IF (convert(varbinary(1),@curchar) >= 0x80)  --Admit could be SBCS Greek >=0x80, but...
      Select @current = @current + 2
   ELSE
      Select @current = @current + 1

   end  --loop

Return (0)
go



raiserror(15339,-1,-1,'sp_validlang')
go
create procedure sp_validlang
@name	varchar(30)
as

/* Check to see if this language is in Syslanguages. */
if exists (select * from syslanguages where name = @name)
	or @name = 'us_english'		/* us_english is always valid. */
	return(0)

raiserror(15033,-1,-1,@name)
return (1)
go


raiserror(15339,-1,-1,'sp_chklangparam')
go
create procedure sp_chklangparam
@namelist varchar(251),		/* month or day name list */
@msgparam varchar(30),		/* name of list, for error messages */
@numnames int,			/* correct number of names in the list */
@maxnamelen int			/* maximum length of any name in list */
as

	/*
	** sp_chklangparam is called by sp_addlanguage to check the lists of
	** full month names, short month names, and day names.  It returns a status
	** indicating whether any errors were found:
	**	0 - name list is valid
	**	1 - spaces were found, which are not allowed
	**	2 - not enough names in the list (must be exactly @numnames of them)
	**	3 - too many names in the list (must be exactly @numnames of them)
	**	4 - some name(s) are too long
	**	5 - some name(s) have non-aphabetic characters
	*/

	declare @totallen		int
	declare @mthlen			int
	declare @mthname		varchar(251)
	declare @msg			varchar(255)
	declare @csid			tinyint
	declare @csname			varchar(30)
	declare @alpha_0_start		tinyint
	declare @alpha_0_end		tinyint
	declare @alpha_1_start		tinyint
	declare @alpha_1_end		tinyint
	declare @alpha_2_start		tinyint
	declare @alpha_2_end		tinyint
	declare @alpha_3_start		tinyint
	declare @alpha_3_end		tinyint
	declare @alpha_4_start		tinyint
	declare @alpha_4_end		tinyint
	declare @alpha_5_start		tinyint
	declare @alpha_5_end		tinyint
	declare @alpha_6_start		tinyint
	declare @alpha_6_end		tinyint
	declare @alpha_7_start		tinyint
	declare @alpha_7_end		tinyint
	declare @alpha_s_1		tinyint
	declare @alpha_s_2		tinyint
	declare @alpha_s_3		tinyint
	declare @alpha_s_4		tinyint
	declare @curchar		tinyint
	declare @next			int

	/* Get the Character Set id (csid) */
	select @csid = csid from master..syscharsets
		where id = (select value from master..sysconfigures
			where config = 1123)

	/* Get the Character Set Name (csname) */
	select @csname = name from master..syscharsets
		where id = @csid and type < 2000

	/* Make sure the list has no blanks. */
	if ( charindex( ' ', @namelist ) <> 0 )
	begin
		raiserror(15057,-1,-1,@msgparam)
		return (1)
	end

	if @csid = 1
	    /* Set up the alphabetic codepoint ranges for iso_1. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
		   @alpha_2_start = 0xC0, @alpha_2_end = 0xD6,
		   @alpha_3_start = 0xD8, @alpha_3_end = 0xF6,
	           @alpha_4_start = 0xF8, @alpha_4_end = 0xFF,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x61, @alpha_7_end = 0x7A,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x2D

	if @csid = 2
	    /* Set up the alphabetic codepoint ranges for cp850. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
		   @alpha_2_start = 0x80, @alpha_2_end = 0x9D,
		   @alpha_3_start = 0xA0, @alpha_3_end = 0xA5,
	           @alpha_4_start = 0xB5, @alpha_4_end = 0xB7,
	           @alpha_5_start = 0xC6, @alpha_5_end = 0xC7,
	           @alpha_6_start = 0xD0, @alpha_6_end = 0xD8,
	           @alpha_7_start = 0xE0, @alpha_7_end = 0xED,
		   @alpha_s_1 = 0xDE, @alpha_s_2 = 0xF4, @alpha_s_3 = 0xF5,
		   @alpha_s_4 = 0x2D

	if @csid = 3
	    /* Set up the alphabetic codepoint ranges for cp437. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
		   @alpha_2_start = 0x80, @alpha_2_end = 0x9A,
		   @alpha_3_start = 0xA0, @alpha_3_end = 0xA5,
	           @alpha_4_start = 0xE0, @alpha_4_end = 0xEE,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x61, @alpha_7_end = 0x7A,
		   @alpha_s_1 = 0x9E, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x2D

	if @csid = 4
	    /* Set up the alphabetic codepoint ranges for cp1250. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
	       @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
		   @alpha_3_start = 0xBE, @alpha_3_end = 0xFF,
	           @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x8C, @alpha_7_end = 0x8F,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	if @csid = 5
	    /* Set up the alphabetic codepoint ranges for cp1251. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
	       @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
		   @alpha_3_start = 0xA1, @alpha_3_end = 0xA3,
	           @alpha_4_start = 0xB2, @alpha_4_end = 0xFF,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x8C, @alpha_7_end = 0x90,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	if @csid = 6
	    /* Set up the alphabetic codepoint ranges for cp1253. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
           @alpha_2_start = 0xBE, @alpha_2_end = 0xD1,
		   @alpha_3_start = 0xD3, @alpha_3_end = 0xFE,
	           @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0xB8, @alpha_7_end = 0xBA,
		   @alpha_s_1 = 0xA2, @alpha_s_2 = 0xBC, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	if @csid = 7
	    /* Set up the alphabetic codepoint ranges for cp1254. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
	       @alpha_2_start = 0xD8, @alpha_2_end = 0xFF,
		   @alpha_3_start = 0x9F, @alpha_3_end = 0x9F,
	           @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0xC0, @alpha_7_end = 0xD6,
		   @alpha_s_1 = 0x83, @alpha_s_2 = 0x8A, @alpha_s_3 = 0x9A,
		   @alpha_s_4 = 0x41

	if @csid = 8
	    /* Set up the alphabetic codepoint ranges for cp1255. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
           @alpha_2_start = 0x41, @alpha_2_end = 0x5A,
		   @alpha_3_start = 0x41, @alpha_3_end = 0x5A,
	           @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0xE0, @alpha_7_end = 0xFA,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	if @csid = 9
	    /* Set up the alphabetic codepoint ranges for cp1256. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
	      @alpha_2_start = 0x80, @alpha_2_end = 0x9A,
		   @alpha_3_start = 0xA0, @alpha_3_end = 0xA5,
	           @alpha_4_start = 0xE0, @alpha_4_end = 0xEE,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x61, @alpha_7_end = 0x7A,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	if @csid = 10
	    /* Set up the alphabetic codepoint ranges for cp1257. */
	    select @alpha_0_start = 0x41, @alpha_0_end = 0x5A,
		   @alpha_1_start = 0x61, @alpha_1_end = 0x7A,
	       @alpha_2_start = 0x9C, @alpha_2_end = 0x9F,
		   @alpha_3_start = 0xC0, @alpha_3_end = 0xFE,
	           @alpha_4_start = 0x41, @alpha_4_end = 0x5A,
	           @alpha_5_start = 0x41, @alpha_5_end = 0x5A,
	           @alpha_6_start = 0x61, @alpha_6_end = 0x7A,
	           @alpha_7_start = 0x8C, @alpha_7_end = 0x8F,
		   @alpha_s_1 = 0x41, @alpha_s_2 = 0x41, @alpha_s_3 = 0x41,
		   @alpha_s_4 = 0x41

	select @totallen = datalength( @namelist )
	while ( @totallen > 0 )
	begin
		/* Move to the next name in the list. */
		select @namelist = right( @namelist, @totallen )

		/* If this is not the last name in the list then there must
		** be another comma.
		*/
		if ( @numnames > 1 )
		begin
			select @mthlen = charindex( ',', @namelist ) - 1
			if ( @mthlen < 0 )
			begin
				raiserror(15058,-1,-1,@msgparam)
				return(2)
			end
		end

		/* This is the last name in the list, so there cannot be
		** another comma.  This name is all remaining characters
		** in the list.
		*/
		else
		begin
			if ( charindex( ',', @namelist ) <> 0 )
			begin
				raiserror(15059,-1,-1,@msgparam)
				return(3)
			end
			select @mthlen = @totallen
		end

		/* Check the name length. */
		if ( @mthlen > @maxnamelen )
		begin
			raiserror(15283,-1,-1,@msgparam)
			return(4)
		end

		/*
		** Check to see that the names contain only true
		** Alphabetic characters; not even DIGITs are allowed.
		*/
		select @next = 1
		while @next <= @mthlen
		begin
		    select @curchar = convert(binary(1),
			substring(@namelist, @next, 1))
		    if (not
		    (
		       (@curchar between @alpha_0_start and @alpha_0_end)
		    or (@curchar between @alpha_1_start and @alpha_1_end)
		    or (@curchar between @alpha_2_start and @alpha_2_end)
		    or (@curchar between @alpha_3_start and @alpha_3_end)
		    or (@curchar between @alpha_4_start and @alpha_4_end)
		    or (@curchar between @alpha_5_start and @alpha_5_end)
		    or (@curchar between @alpha_6_start and @alpha_6_end)
		    or (@curchar between @alpha_7_start and @alpha_7_end)
		    or @curchar = @alpha_s_1
		    or @curchar = @alpha_s_2
		    or @curchar = @alpha_s_3
		    or @curchar = @alpha_s_4
		    )
		    )
		    begin
    			raiserror(15060,-1,-1,@msgparam,@csname)
			return(5)
		    end

		    select @next = @next + 1
		end

		/* Move to the next name in the list. */
		select @numnames = @numnames - 1
		select @totallen = @totallen - @mthlen - 1
	end

	/* No problems were found with the name list. */
	return (0)
go



raiserror(15339,-1,-1,'sp_namecrack')
go
create procedure sp_namecrack
@name	varchar(123),
@site	varchar(30) = null output,
@db	varchar(30) = null output,
@owner	varchar(30) = null output,
@object	varchar(30) = null output
as
--Used in InstRepl.SQL

select @site = null, @db = null, @owner = null, @object = null

/*
**  Is there a site name?
*/
if @name like '%.%.%.%'
begin
	select @site = substring(@name, 1, charindex('.', @name) - 1)
	select @name = substring(@name, charindex('.', @name) + 1, 125)
end

/*
**  Is there a database name?
*/
if @name like '%.%.%'
begin
	select @db = substring(@name, 1, charindex('.', @name) - 1)
	select @name = substring(@name, charindex('.', @name) + 1, 125)
end

/*
**  Is there a owner?
*/
if @name like '%.%'
begin
	select @owner = substring(@name, 1, charindex('.', @name) - 1)
	select @name = substring(@name, charindex('.', @name) + 1, 125)
end

select @object = @name

return (0)
go



raiserror(15339,-1,-1,'sp_namecrack2')
go
go
CREATE PROCEDURE sp_namecrack2    -- 1996/01/12 10:45 b
       @QualName     varchar(175)
      ,@NamePart1    varchar( 30)          Output  -- svr (possible ultimate scenario)
      ,@NamePart2    varchar( 30)   = null Output  -- db
      ,@NamePart3    varchar( 30)   = null Output  -- own
      ,@NamePart4    varchar( 30)   = null Output  -- tab
      ,@NamePart5    varchar( 30)   = null Output  -- col
      ,@NamePart6    varchar( 30)   = null Output  -- Problem?
as

Set nocount on

Declare
       @RetCode            integer
      ,@MaxLenQualName     smallint
      ,@CountNodes         smallint

Select
       @RetCode            = 0  -- 0=good ,1=bad
      ,@MaxLenQualName     = 175
      ,@CountNodes         = 0
Select
       @NamePart1    = null
      ,@NamePart2    = null
      ,@NamePart3    = null
      ,@NamePart4    = null
      ,@NamePart5    = null
      ,@NamePart6    = null


IF (@QualName like '%.%')
   begin
   Select @CountNodes = @CountNodes + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart1  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end

IF (@QualName like '%.%')
   begin
   Select @CountNodes = @CountNodes + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart2  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountNodes = @CountNodes + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart3  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountNodes = @CountNodes + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart4  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountNodes = @CountNodes + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart5  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end


IF (@QualName NOT LIKE '%.%')
   begin

   IF (@NamePart1 IS null  AND  @QualName IS NOT null  AND  @CountNodes=0)
      begin
      Select @NamePart1 = @QualName
      Select @QualName  = null
      end

   IF (@NamePart2 IS null  AND  @QualName IS NOT null  AND  @CountNodes=1)
      begin
      Select @NamePart2 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart3 IS null  AND  @QualName IS NOT null  AND  @CountNodes=2)
      begin
      Select @NamePart3 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart4 IS null  AND  @QualName IS NOT null  AND  @CountNodes=3)
      begin
      Select @NamePart4 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart5 IS null  AND  @QualName IS NOT null  AND  @CountNodes=4)
      begin
      Select @NamePart5 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart6 IS null  AND  @QualName IS NOT null  AND  @CountNodes=5)
      begin
      Select @NamePart6 = @QualName
      Select @QualName  = null
      end
   end
ELSE
   begin  -- Problem: Cannot fully break apart at all dots.
   Select @RetCode   = 1
   Select @NamePart6 = @QualName  -- Provide resultant string regardless.
   end

Return @RetCode --sp_namecrack2
go



raiserror(15339,-1,-1,'sp_namecrack3')
go
CREATE PROCEDURE sp_namecrack3    -- 1996/03/05 13:02
       @QualName     varchar(188)

      ,@CountDots    integer             OUTPUT
      ,@UnqualName   varchar( 30)        OUTPUT

      ,@QualName1    varchar( 30) = null OUTPUT  -- rightmost qualifier.
      ,@QualName2    varchar( 30) = null OUTPUT
      ,@QualName3    varchar( 30) = null OUTPUT
      ,@QualName4    varchar( 30) = null OUTPUT
      ,@QualName5    varchar( 30) = null OUTPUT
as

Set nocount on

Declare
       @RetCode            integer
      ,@PosDot             integer
      ,@MaxLenQualName     smallint
Declare
       @NamePart1    varchar( 30)  -- leftmost qualifier.
      ,@NamePart2    varchar( 30)
      ,@NamePart3    varchar( 30)
      ,@NamePart4    varchar( 30)
      ,@NamePart5    varchar( 30)
      ,@NamePart6    varchar( 30)

-----------------------------------

Select
       @RetCode            = 0  -- 0=good ,1=bad
      ,@MaxLenQualName     = 188
Select
       @NamePart1    = null
      ,@NamePart2    = null
      ,@NamePart3    = null
      ,@NamePart4    = null
      ,@NamePart5    = null
      ,@NamePart6    = null
Select
       @CountDots    = 0
      ,@UnqualName   = null
      ,@QualName1    = null
      ,@QualName2    = null
      ,@QualName3    = null
      ,@QualName4    = null
      ,@QualName5    = null


--------  Since CHARINDEX works left-to-right, isolate actual obj name last.

IF (@QualName like '%.%')
   begin
   Select @CountDots = @CountDots + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart1  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end

IF (@QualName like '%.%')
   begin
   Select @CountDots = @CountDots + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart2  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountDots = @CountDots + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart3  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountDots = @CountDots + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart4  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end
IF (@QualName like '%.%')
   begin
   Select @CountDots = @CountDots + 1
   IF (charindex('.', @QualName) > 1)
      Select @NamePart5  = substring(@QualName ,1 ,charindex('.', @QualName) - 1)
   Select @QualName   = substring(@QualName ,charindex('.', @QualName) + 1 ,@MaxLenQualName)
   end


IF (@QualName NOT LIKE '%.%')
   begin

   IF (@NamePart1 IS null  AND  @QualName IS NOT null  AND  @CountDots=0)
      begin
      Select @NamePart1 = @QualName
      Select @QualName  = null
      end

   IF (@NamePart2 IS null  AND  @QualName IS NOT null  AND  @CountDots=1)
      begin
      Select @NamePart2 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart3 IS null  AND  @QualName IS NOT null  AND  @CountDots=2)
      begin
      Select @NamePart3 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart4 IS null  AND  @QualName IS NOT null  AND  @CountDots=3)
      begin
      Select @NamePart4 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart5 IS null  AND  @QualName IS NOT null  AND  @CountDots=4)
      begin
      Select @NamePart5 = @QualName
      Select @QualName  = null
      end
   IF (@NamePart6 IS null  AND  @QualName IS NOT null  AND  @CountDots=5)
      begin
      Select @NamePart6 = @QualName
      Select @QualName  = null
      end
   end
ELSE
   begin  -- Problem: Cannot fully break apart so many dots.
   Select @RetCode   = 1
   Select @NamePart6 = @QualName  -- Provide resultant string regardless.
   end


--------  Now reverse order, so caller has easier logic,
--------  knowing which output parm contains the rightmost unqual name.

IF      (@NamePart6 IS NOT null)
           begin
           Select @UnqualName    = @NamePart6
                 ,@QualName1     = @NamePart5 -- Right-most qualifier possible.
                 ,@QualName2     = @NamePart4
                 ,@QualName3     = @NamePart3
                 ,@QualName4     = @NamePart2
                 ,@QualName5     = @NamePart1
           end
ELSE IF (@NamePart5 IS NOT null)
           begin
           Select @UnqualName    = @NamePart5
                 ,@QualName1     = @NamePart4
                 ,@QualName2     = @NamePart3
                 ,@QualName3     = @NamePart2
                 ,@QualName4     = @NamePart1
           end
ELSE IF (@NamePart4 IS NOT null)
           begin
           Select @UnqualName    = @NamePart4
                 ,@QualName1     = @NamePart3
                 ,@QualName2     = @NamePart2
                 ,@QualName3     = @NamePart1
           end
ELSE IF (@NamePart3 IS NOT null)
           begin
           Select @UnqualName    = @NamePart3
                 ,@QualName1     = @NamePart2
                 ,@QualName2     = @NamePart1
           end
ELSE IF (@NamePart2 IS NOT null)
           begin
           Select @UnqualName    = @NamePart2
                 ,@QualName1     = @NamePart1
           end
ELSE IF (@NamePart1 IS NOT null)
           begin
           Select @UnqualName    = @NamePart1
           end

Return @RetCode --sp_namecrack3
go



raiserror(15339,-1,-1,'sp_tableoption')
go
create procedure sp_tableoption  --1996/03/14 09:34
    @TableNamePattern      character varying(150)

   ,@OptionName            character varying(35)   = null
   ,@OptionValue           character varying(12)   = null
as

Set nocount       on
Set ansi_nulls    on
Set ansi_warnings on

Declare
       @RetCode            integer
      ,@ExecRC             integer
      ,@int1               integer
Declare
       @CurrentDBName      varchar(30)
      ,@CurrentDBId        integer
      ,@CountMatchedObj    integer
      ,@CountExpectUpd     integer
      ,@CountUpdRows1      integer
      ,@CountUpdRows2      integer
      ,@IRLString          varchar(35)
      ,@PinTabString       varchar(35)
      ,@Status_csr_11      integer
      ,@TabId              integer
      ,@BitLogic           varchar(9)
Declare
       @WOptionName        character varying(35)  -- spt_values.name
      ,@WOptionNum         integer                -- 1 in 6.5
      ,@charWOptionNum     varchar(12)
      ,@WOptionValue       character varying( 6)  -- T/F
      ,@intOptionValue     integer
Declare
       @UnqualName         varchar(30)
      ,@QualName1          varchar(30)    -- own
      ,@QualName2          varchar(30)    -- db
      ,@QualName3          varchar(30)    -- svr
      ,@QualName4          varchar(30)    -- (Extra)
      ,@QualName5          varchar(30)    -- (Extra)

      ,@WQualName1         varchar(30)
      ,@WQualName2         varchar(30)

-----------------------------

Select
       @RetCode            = 0   --  =0 is good,  >0 is bad.
      ,@CurrentDBName      = db_name()
      ,@CurrentDBId        = db_id()
      ,@CountMatchedObj    = 0
      ,@CountExpectUpd     = 0
      ,@CountUpdRows1      = 0
      ,@CountUpdRows2      = 0
      ,@IRLString          = 'insert row lock'
      ,@PinTabString       = 'pintable'
      ,@Status_csr_11      = 0  -- 0x01 bit =Declared; 0x02 bit =Open.
      ,@TabId              = null
Select
       @UnqualName         = null
      ,@QualName1          = null
      ,@QualName2          = null
      ,@QualName3          = null
      ,@QualName4          = null
      ,@QualName5          = null

      ,@WQualName1         = null  -- own
      ,@WQualName2         = null  -- db


--------------------- Basic parm edits  -------------------

IF (@TableNamePattern IS null)
   begin
   RaisError(15113,-1,-1,'@TableNamePattern')
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

IF (@OptionName is null)
   begin
   ------- Report, then bye.

   SELECT
                   val.name   as 'Available Table Options'
                  ,val.status as 'Default Value'
         from      master..spt_values  val
         where     val.type   = 'TBO'
         and       val.number > 0
         order by  val.name

   GOTO LABEL_86_RETURN

   end


--------  Gather spt_values info (only tab opts with 'TBO' rows are docu).


SELECT
             @WOptionName  = min(val.name)
            ,@WOptionNum   = min(val.number)
            ,@int1         = count(*)
      from   master..spt_values  val
      where  val.type      = 'TBO'
      and    val.number    > 0
      and    lower(val.name) like (lower(@OptionName) + '%')

IF (@int1 <> 1)
   begin
   RaisError(15386,-1,-1,@OptionName)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Select @charWOptionNum = convert(varchar,@WOptionNum)


-------- Parse apart the perhaps dots-qualified name.  ---------------


Execute @ExecRC = sp_namecrack3 @TableNamePattern
      ,@int1         OUTPUT  -- count of node dots in input name.
      ,@UnqualName   OUTPUT
      ,@QualName1    OUTPUT  -- rightmost qualifier (presumably owner).
      ,@QualName2    OUTPUT
      ,@QualName3    OUTPUT
      ,@QualName4    OUTPUT
      ,@QualName5    OUTPUT


IF (@ExecRC <> 0)
   begin
   RaisError(15253,-1,-1,@TableNamePattern,@QualName5)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


------------------  Verify database.


Select @WQualName2 = @QualName2

IF (@WQualName2 is null)
   begin
   Select @WQualName2 = @CurrentDBName
   end

IF (@WQualName2 <> @CurrentDBName)
   begin
   RaisError(15387,-1,-1)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


------------------  Settle owner.


Select @WQualName1 = @QualName1

IF (@WQualName1 is null)  -- Owner not part of any qualification.
   begin
   Select @WQualName1 = user_name()  -- '%' might not be intuitive.
   end


------------------  Are zero objects matched?


SELECT          @CountMatchedObj = count(*)
      from      sysobjects       sysobj
      where     sysobj.type      = 'U '
      and       user_name(sysobj.uid) like @WQualName1
      and       sysobj.name           like @UnqualName

IF (@CountMatchedObj = 0)
   begin
   RaisError(15388,-1,-1,@TableNamePattern)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end


-----------------  Was option value parm specified?  ---------------


Select @WOptionValue = lower(@OptionValue)


IF (@OptionValue is null)
   begin
   --    Report current option settings, then bye.

   SELECT
                CASE
                  When sysobj.userstat & @WOptionNum > 0 Then 'True '
                  When sysobj.userstat & @WOptionNum = 0 Then 'False'
                END
                              as 'Option Status'
               ,sysobj.name   as 'Table Name'
               ,user_name(sysobj.uid)
                              as 'Owner Name'
         from
                sysobjects    sysobj
         where  sysobj.type   = 'U '
         and    user_name(sysobj.uid) like @WQualName1
         and    sysobj.name           like @UnqualName
         order by
                1 ,2 ,3

   GOTO LABEL_86_RETURN

   end


IF (@WOptionValue = 'on')
   begin
   Select @WOptionValue  = 'true'
   end

IF (@WOptionValue = 'off')
   begin
   Select @WOptionValue  = 'false'
   end


IF (@WOptionValue not in ('true','false'))
   begin
   RaisError(15389,-1,-1,@OptionValue)
   Select @RetCode = @@error
   GOTO LABEL_86_RETURN
   end

Select @intOptionValue =
            CASE @WOptionValue
               When 'true'  Then 1
               When 'false' Then 0
            END


----  Count, for reporting.

IF (@WOptionValue = 'true')
   begin
   SELECT       @CountExpectUpd = count(*)
      from      sysobjects       sysobj
      where     sysobj.type      = 'U '
      and       user_name(sysobj.uid) like @WQualName1
      and       sysobj.name           like @UnqualName
      and       sysobj.userstat & @WOptionNum = 0  --Currently False.
   end
ELSE
   begin
   SELECT       @CountExpectUpd = count(*)
      from      sysobjects       sysobj
      where     sysobj.type      = 'U '
      and       user_name(sysobj.uid) like @WQualName1
      and       sysobj.name           like @UnqualName
      and       sysobj.userstat & @WOptionNum > 0  --Currently True.
   end


--------------------------  Security  ------------------


IF (@WOptionName = @PinTabString)
   begin

   IF (suser_id() <> 1)
      begin
      RaisError(15392,-1,-1,@WOptionName)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end
   end


IF (     user_id()   <> 1  --SA & DBO generally have no security restrictions.
   AND   suser_id()  <> 1
   )
   begin

   SELECT
             @int1      = count(*)  --Num of users matching pattern.
      from   sysusers   sysusr
      where  user_name(sysusr.uid) like @WQualName1

   IF (    ---- nonSA/nonDBO users can only affect their own tables.
           (@int1        > 1)
      OR
           (@int1        = 1  AND
            @WQualName1 <> user_name()
           )
      )
      begin
      RaisError(15390,-1,-1,@WOptionName)
      Select @RetCode = @@error
      GOTO LABEL_86_RETURN
      end
   end


------------------  Special cases  -------------------------


IF (@WOptionName in (@IRLString,@PinTabString))
   begin

   IF (@intOptionValue = 0)    --Want it False,
      begin
      Select @BitLogic = ' > '   --but is True  currently.
      end
   ELSE                        --Want it True,
      begin
      Select @BitLogic = ' = '   --but is False currently.
      end


   EXECUTE(
   '
   DECLARE         csr_11_tabid
                   insensitive
               cursor for
      SELECT
                   sysobj.id
            from   sysobjects    sysobj
            where  sysobj.type   = ''U ''
            and    user_name(sysobj.uid) like ''' +@WQualName1+ '''
            and    sysobj.name           like ''' +@UnqualName+ '''
            and
                   sysobj.userstat & ' +@charWOptionNum+ ' ' +@BitLogic+ ' 0
   ')


   Select @Status_csr_11 = 1

   Open csr_11_tabid

   Select @Status_csr_11 = @Status_csr_11 | 2


   WHILE (11=11)
      begin

      FETCH    next from csr_11_tabid
            into
                   @TabId

      IF (@@fetch_status <> 0)
         begin
         Deallocate csr_11_tabid
         Select @Status_csr_11 = 0
         BREAK
         end

      Select @CountUpdRows2 = @CountUpdRows2 + 1


      ---- This dbcc rowlock toggles sysobjects.userstat 0x01 bit,
      ----    and internally makes the option take effect
      ----    immediately/dynamically without needed MS SQL stop/restart.

      IF (@WOptionName in (@IRLString))
         begin
         DBCC rowlock(@CurrentDBId,@TabId,@intOptionValue)
         end


      IF (@WOptionName in (@PinTabString))
         begin
         IF (@intOptionValue = 0)
            begin
            DBCC unpintable(@CurrentDBId,@TabId)
            end
         ELSE
            begin
            DBCC   pintable(@CurrentDBId,@TabId)
            end
         end

      end --loop 11


   IF (@WOptionName in (@IRLString))  --This dbcc toggles bit.
      begin

      GOTO LABEL_75_FINAL

      end
   end


----------------  General case - Upd the settings  ----------------------


IF (@WOptionValue = 'true')
   begin

   UPDATE          sysobjects
         set       userstat = userstat | @WOptionNum
         where     type     = 'U '
         and       user_name(uid) like @WQualName1
         and       name           like @UnqualName
         and       userstat & @WOptionNum = 0

   Select @CountUpdRows1 = @@rowcount
   end
ELSE
   begin

   UPDATE          sysobjects
         set       userstat = userstat & (~@WOptionNum)
         where     type     = 'U '
         and       user_name(uid) like @WQualName1
         and       name           like @UnqualName
         and       userstat & @WOptionNum > 0

   Select @CountUpdRows1 = @@rowcount
   end


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


LABEL_75_FINAL:

Raiserror(15391,-1,-1,@CountMatchedObj,@WOptionName,@OptionValue,@CountExpectUpd)

LABEL_86_RETURN:

IF (@Status_csr_11 > 0)
   Deallocate csr_11

Return @RetCode  -- sp_tableoption
go



raiserror(15339,-1,-1,'sp_addalias')
go
create procedure sp_addalias
@loginame varchar(30),		/* the name of the pretender */
@name_in_db varchar(30)		/* who the pretender wants to pretend to be */
as

declare @suid	int		/* the suid of the pretender */
declare @asuid	int		/* the suid of the person to impersonate */
declare	@name	varchar(30)
declare @dbname sysname

/*
**  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

/*
**  Make sure that the pretender has an account.
*/
select @suid = suid from syslogins where name = @loginame

if @suid is NULL
	begin
		raiserror(15007,-1,-1,@loginame)
		return (1)
	end

/*
**  Get the suid of the person we want to pretend to be.
**  All user ids are <= 16383 and group ids are > 16383.
*/
select @asuid = suid from sysusers where name = @name_in_db and uid <= 16383

/*
**  Does the user to be impersonated exist in the current database?
*/
if @asuid is NULL
	begin
		raiserror(15008,-1,-1,@name_in_db)
		return (1)
	end

/*
**  Is the login to be aliased already a user in the current db?
*/
if exists (select * from sysusers where suid = @suid)
	begin
		select @name = name,@dbname = db_name() from sysusers
			where suid = @suid
		raiserror(15278,-1,-1,@loginame,@name,@dbname)
		return (1)
	end

/*
**  Is the person already aliased to a user?
*/
if exists (select * from sysalternates where suid = @suid)
	begin
		raiserror(15022,-1,-1)
		return (1)
	end

/*
**  Add the alias.
*/
insert into sysalternates (suid, altsuid)
	values (@suid, @asuid)

raiserror(15340,-1,-1)

return (0)
go


raiserror(15339,-1,-1,'sp_addextendedproc')
go
create procedure sp_addextendedproc
@functname varchar(62),		/* (owner.)name of function to call */
@dllname varchar(255)		/* name of DLL containing function */
as
/*
**  If we're in a transaction, disallow the addition of the
**  extended stored procedure.
*/
if @@trancount > 0
begin
	raiserror(15002,-1,-1,'sp_addextendedproc')
	return (1)
end

/*
** Create the extended procedure mapping.
*/
dbcc addextendedproc( @functname, @dllname)
return (0)
go


raiserror(15339,-1,-1,'sp_addgroup')
go
create procedure sp_addgroup
@grpname varchar(30)			/* new group name */
as

declare @gid int			/* group id */

/*
**  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 that the @grpname is valid.
*/
declare @returncode	int
execute @returncode = sp_validname @grpname
if @returncode <> 0
	return(1)

/*
**  See if the new group name is already being used as a user or group name.
*/
select @gid = uid from sysusers where name = @grpname

/*
**  User ids are > 0 and  <= 16383 and group ids are > 16383.
*/
if @gid is not null
begin
	if @gid > 0 and @gid <= 16383
		raiserror(15023,-1,-1,@grpname)
	else
		raiserror(15024,-1,-1,@grpname)

	return (1)
end

/*
**  Now get the group id for the new group.  Look for the first available
**  hole > 16383.
*/
select @gid = min(s1.uid)+1 from sysusers s1
	where uid < 32767	/* Don't cause arithmetic overflow. */
	and uid >= 16383
	and not exists
		(select * from sysusers s2
			where s2.uid = s1.uid+1)

/*
**  This is the first group.
*/
if @gid is null
	select @gid = 16384

/*
**  Create the group.
*/
insert into sysusers (uid, suid, gid, name, environ)
values (@gid, -@gid, @gid, @grpname, '')

raiserror(15341,-1,-1)

return (0)
go



raiserror(15339,-1,-1,'sp_addlogin')
go
CREATE PROCEDURE sp_addlogin  -- 1996/03/06 14:04

    @loginame         varchar(30)
   ,@passwd          varchar(30) = Null
   ,@defdb         varchar(30) = 'master'
   ,@deflanguage   varchar(30) = Null
   ,@loginsuid         smallint    = Null
AS

Set nocount on

Declare
    @RetCode               int
   ,@IntA                  int

   ,@High2Int              smallint
   ,@NewSUID               smallint
   ,@LowRegSUID            smallint

   ,@charLowRegSUID        varchar(12)
   ,@WorkName              varchar(30)


--------  Initial values.

Select
    @RetCode               = 1   -- 0=Good ,1=Bad.
   ,@NewSUID               = Null
   ,@High2Int              = 32767
   ,@LowRegSUID            = 10

Select
    @charLowRegSUID        = convert(varchar,@LowRegSUID)


----------------------------------------------------------------------
----------------------------------------------------------------------
--*         Simple validations of input parms.
----------------------------------------------------------------------
----------------------------------------------------------------------


--------  An open txn risks improper recovery.

IF (@@trancount > 0)
   begin
   RaisError(15002,-1,-1,'sp_addlogin')
   GOTO LABEL_86RETURN
   end


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

IF (suser_id() <> 1)
   begin
   RaisError(15003,-1,-1)
   GOTO LABEL_86RETURN
   end


--------  Verify login name is valid.

Execute @IntA = sp_validname @loginame

IF (@IntA <> 0)
   begin
   --msg handle by called sproc.
   GOTO LABEL_86RETURN
   end


--------  Validate default language.

IF (@deflanguage IS NOT Null)
   begin
   Execute @IntA = sp_validlang @deflanguage

   IF (@IntA <> 0)
      begin
      --msg handle by called sproc.
      GOTO LABEL_86RETURN
      end
   end

--------  Verify login name is new.

IF (exists (select * from syslogins where name = @loginame))
   begin
   RaisError(15025,-1,-1,@loginame)
   GOTO LABEL_86RETURN
   end


--------  Verify the default database name is known.

IF NOT (exists (select * from sysdatabases where name = @defdb))
   begin
   RaisError(15010,-1,-1,@defdb)
   GOTO LABEL_86RETURN
   end


----------------------------------------------------------------------
----------------------------------------------------------------------
--*         Parms are valid, try to add login.
----------------------------------------------------------------------
----------------------------------------------------------------------


--------  Did the executioner supply an suid value?  -----------

IF (@loginsuid IS NOT Null)
   begin

   IF (@loginsuid <= 1)
      begin
      RaisError(15301,-1,-1 ,@loginsuid)
      GOTO LABEL_86RETURN
      end


   Select    @IntA      = min(suid)
            ,@WorkName  = min(name)
      from   syslogins
      where  suid       = @loginsuid

   IF (@IntA IS NOT Null)
      begin
      RaisError(15296,-1,-1 ,@loginsuid ,@WorkName)
      GOTO LABEL_86RETURN
      end


   Select @NewSUID = @loginsuid

   GOTO LABEL_07INSERT

   end


--------  Try the faster way of generating a new suid.  --------------

-- 16382=repl_publisher  ,16383=repl_subscriber


SELECT
             @IntA      = Max(suid)
      from
             syslogins
      where
      suid       < 16299  --avoids repl_%


IF     EXISTS (
               SELECT   *
                 from   syslogins
                 where  suid=(@IntA+1)
              )
   Select @IntA = @High2Int  --Acts as a defeating switch.


IF (@IntA < @High2Int)  --True almost always.
   begin

   Select @NewSUID = @IntA + 1

   IF (      @NewSUID < @LowRegSUID)
      Select @NewSUID = @LowRegSUID

   GOTO LABEL_07INSERT

   end


--------  Instead, scan for an available new suid number.  ------------

SELECT     --Find lowest in-use suid where the next number is available.
                @NewSUID = min(log1.suid)
      from
                syslogins  log1
      where
                log1.suid  < @High2Int  --Avoid arithmetic overflow.
      and       log1.suid >= @LowRegSUID
      and
                NOT exists    --Faster than plain cursor loop.
                  (
                   SELECT  log2.*
                     from  syslogins   log2
                     where log2.suid   = log1.suid + 1
                  )



IF (@NewSUID IS Null)
   begin
   RaisError(15297,-1,-1 ,@loginame)
   GOTO LABEL_86RETURN
   end
ELSE
   begin
   Select   @NewSUID = @NewSUID + 1

   GOTO LABEL_07INSERT

   end


----------------------------------------------------------------------
--*            We have a good new suid number.
----------------------------------------------------------------------

--------  Yes, a good suid number is in hand, add login.


   --Logic can never hit this raiserror/goto, precautionary.
RaisError('Bad logic in sp_addlogin, should never hit this statement (a1).' ,16,127)
GOTO LABEL_86RETURN



LABEL_07INSERT:   --@NewSUID must be set properly by now.



INSERT
         into
                syslogins
            (
             suid
            ,status
            ,accdate

            ,totcpu ,totio ,spacelimit ,timelimit ,resultlimit

            ,dbname
            ,name
            ,password
            ,language
            )
         Values
            (
             @NewSUID
            ,8          -- 0x08 bit means pw encrypt new alogorithm
            ,getdate()

            ,0 ,0 ,0 ,0 ,0

            ,@defdb
            ,@loginame
            ,pwdencrypt(@passwd)
            ,@deflanguage
            )


IF (@@error = 0)
   begin
   Raiserror(15298,-1,-1)
   Select @RetCode   = 0
   end


----------------------------------------------------------------------
--*               Finalization.
----------------------------------------------------------------------


LABEL_86RETURN:


Return @RetCode
go



raiserror(15339,-1,-1,'sp_change_users_login')
go
CREATE PROCEDURE sp_change_users_login -- 1995/12/22 13:52

    @Action               varchar(10)  = Null

   ,@UserNamePattern      varchar(40)  = Null
   ,@LoginName            varchar(30)  = Null
AS

Set nocount on

Declare
    @RetCode               integer
   ,@exspRetCode           integer
   ,@FixMode               character(5)
   ,@IntA                  integer
   ,@IntB                  integer
   ,@CountFixesByUpd       integer
   ,@CountFixesByAddLogin  integer

   ,@DBName                varchar(30)

Declare
    @110Name               varchar(30)
   ,@110UID                smallint
   ,@110SUID               smallint
   ,@LoginSUID             smallint


---------------  Initial values.


Select
    @DBName                = db_name()
   ,@CountFixesByUpd       = 0
   ,@CountFixesByAddLogin  = 0
   ,@RetCode               = 0  -- 0=Good ,1=Bad.


---------------  Validate the action  -----------------------


IF (          @Action            IS     Null
    OR
        (     @Action            IS NOT Null
         AND  Upper(@Action) NOT IN ('REPORT','UPDATE_ONE','AUTO_FIX')
        )
   )
   begin
   RaisError(15286,-1,-1,@Action)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end

Select @Action = Upper(@Action)


---------------  Exclude certain special logins  ------------------


IF (     lower(@LoginName) IN
      ('sa' ,'probe' ,'repl_publisher' ,'repl_subscriber')
    AND        @LoginName  IS NOT Null
   )
   begin
   RaisError(15287,-1,-1,@LoginName)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


---------------  Only the SA can run certain actions  -----------------


IF (     suser_id() <> 1
    AND  @Action   IN ('AUTO_FIX')
   )
   begin
   RaisError(15288,-1,-1,'SA',@Action)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


---------------  Only SA or DBO can run certain actions  -------------


IF (     (suser_id() <> 1  AND  user_id() <> 1)
    AND  @Action   IN ('UPDATE_ONE')
   )
   begin
   RaisError(15288,-1,-1,'SA or DBO',@Action)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


-----------  Pre-existing open txn not allowed (recovery problemmatic) ----------


IF (@@trancount > 0)
   begin
   RaisError(15289,-1,-1)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


---------------- Validate parm value combinations  -----------------


IF (@Action   = 'REPORT')
   begin

   IF (     @UserNamePattern IS NOT Null
       OR   @LoginName       IS NOT Null
      )
      begin
      RaisError(15290,-1,-1,@Action,@UserNamePattern,@LoginName)
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end
   end


IF (@Action   = 'UPDATE_ONE')
   begin

   IF (     @UserNamePattern IS     Null
       OR   @LoginName       IS     Null
      )
      begin
      RaisError(15290,-1,-1,@Action,@UserNamePattern,@LoginName)
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end
   end


IF (@Action   = 'AUTO_FIX')
   begin

   IF (     @UserNamePattern IS     Null
       OR   @LoginName       IS NOT Null
      )
      begin
      RaisError(15290,-1,-1,@Action,@UserNamePattern,@LoginName)
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end
   end



----------------------------------------------------------------------
----------------------------------------------------------------------
--                      ACTIONS
----------------------------------------------------------------------
----------------------------------------------------------------------


IF (@Action   =    'UPDATE_ONE')
   GOTO LABEL_ACTION_UPDATE_ONE

IF (@Action   =    'AUTO_FIX')
   GOTO LABEL_ACTION_AUTO_FIX

IF (@Action   =    'REPORT')
   GOTO LABEL_ACTION_REPORT


----------------------------------------------------------------------
--                      Action = REPORT
----------------------------------------------------------------------


LABEL_ACTION_REPORT:



SELECT
             UserName   = u1.name
            ,UserSUID   = u1.suid
      from
             sysusers   u1
      where
             u1.suid    > 0
      and
             NOT EXISTS
               (
                SELECT     l1.*
                  from     master.dbo.syslogins   l1
                  where    l1.suid     = u1.suid
               )
      order by
             u1.name



GOTO LABEL_77FINALIZATION



----------------------------------------------------------------------
--                      Action = UPDATE_ONE
----------------------------------------------------------------------


LABEL_ACTION_UPDATE_ONE:



IF (NOT EXISTS (SELECT * from sysusers where name = @UserNamePattern))
   begin
   RaisError(15291,-1,-1,'User',@UserNamePattern)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


SELECT
             @LoginSUID    = Min(suid)
      from
             master.dbo.syslogins
      where
             name          = @LoginName
      and    name     NOT IN
                        ('sa' ,'probe'
                        ,'repl_publisher' ,'repl_subscriber'
                        )
      and    suid          > 0


IF (@LoginSUID IS Null)
   begin
   RaisError(15291,-1,-1,'Login',@LoginName)
   Select @RetCode = 1
   GOTO LABEL_86RETURN
   end


UPDATE
             sysusers
      set
             suid    = @LoginSUID
      where
             name    = @UserNamePattern
      and    uid     > 0
      and    suid    > 0
      and    suid   <> @LoginSUID



IF (@@error = 0  AND  @@rowcount = 1)
   Select @CountFixesByUpd = 1

Raiserror(15295,-1,-1,@CountFixesByUpd)


GOTO LABEL_77FINALIZATION



----------------------------------------------------------------------
--                      Action = AUTO_FIX
----------------------------------------------------------------------


LABEL_ACTION_AUTO_FIX:



---------------  Cursor 110  -----------------


EXECUTE(
'
DECLARE Cursor110_Users Cursor
   -- Insensitive Scroll
   For
SELECT
             u1.name
            ,u1.uid
            ,u1.suid
      from
             sysusers               u1
      where
             name    LIKE ''' + @UserNamePattern + '''
      and
             suid     > 0  --Bypass Groups, Public, Guest etc.
      and
             name  NOT IN
                     (''sa'' ,''probe''
                     ,''repl_publisher'' ,''repl_subscriber''
                     )
      and
             NOT Exists
               (
                SELECT     *
                  from     master.dbo.syslogins   l1
                  where    l1.suid  = u1.suid
               )
'
)


OPEN Cursor110_Users



---------------
WHILE (110=110)         ---------  LOOP 110: thru Orphan Users  -----------
   begin


   FETCH
                Next
         from
                Cursor110_Users
         into
                @110Name
               ,@110UID
               ,@110SUID


   IF (@@fetch_status <> 0)
      begin
      DEALLOCATE Cursor110_Users
      BREAK  --loop 110
      end


-----------  Handle case where Name already in use.

   SELECT
                @LoginSUID    = Min(suid)
         from
                master.dbo.syslogins   l1
         where
                l1.name    = @110Name



   IF (@LoginSUID IS Null)
      begin

      ---- Simple sp_addlogin, to get a common L/U name.

      SELECT
                @IntA = isnull( (max(suid) + 1) ,11)
         from
                sysusers
         where
                suid between 2 and 15999

      SELECT
                @IntB = max(suid) + 1
         from
                syslogins
         where
                suid between 2 and 15999
         and    suid >= @IntA

      IF (@IntB IS Null)
         Select @IntB = @IntA


      Execute @exspRetCode = sp_addlogin
                                 @110Name ,Null ,@DBName ,default ,@IntB


      SELECT
                   @LoginSUID = min(suid)
            from
                   master.dbo.syslogins
            where
                   name=@110Name


      IF @LoginSUID IS Null
         begin
         RaisError('Very odd failure of sp_addlogin (user=%s), aborting.',16,1,@110Name)
         Deallocate Cursor110_Users
         Select @RetCode = 1
         GOTO LABEL_86RETURN
         end


      Select @FixMode = '1AddL'
      Raiserror(15293,-1,-1,@110Name)
      end
   ELSE
      begin
      Select @FixMode = '2UpdU'
      Raiserror(15292,-1,-1,@110Name)
      end



   IF EXISTS (SELECT * from sysusers where suid=@LoginSUID)
      begin
      RaisError(15331,-1,-1,@110Name,@LoginSUID)
      Select @RetCode = 1
      -- GOTO LABEL_86RETURN

      CONTINUE  -- loop 110
      end



-------------  Upd Users & Alternates.


   BEGIN TRANSACTION txn_1a_sp_change_users_login


   UPDATE
                sysusers
         set
                suid       = @LoginSUID
         where
                name       = @110Name

   IF @@error <> 0
      begin
      RaisError('Inside txn_1a_, Upd failed, will Rollback (1a1)!',17,127)
      ROLLBACK TRANSACTION --Name not specified.
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end


   UPDATE
                sysalternates
         set
                suid       = @LoginSUID
         where
                suid       = @110SUID

   IF @@error <> 0
      begin
      RaisError('Inside txn_1a_, Upd failed, will Rollback (1a2)!',17,127)
      ROLLBACK TRANSACTION --Name not specified.
      Select @RetCode = 1
      GOTO LABEL_86RETURN
      end


   COMMIT TRANSACTION txn_1a_sp_change_users_login



   IF (@FixMode = '1AddL')
      begin
      Select @CountFixesByAddLogin = @CountFixesByAddLogin + 1
      end
   IF (@FixMode = '2UpdU')
      begin
      Select @CountFixesByUpd = @CountFixesByUpd + 1
      end



   end  --loop 110



Raiserror(15295,-1,-1,@CountFixesByUpd)
Raiserror(15294,-1,-1,@CountFixesByAddLogin)


GOTO LABEL_77FINALIZATION



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


LABEL_77FINALIZATION:


LABEL_86RETURN:


Return @RetCode
go



raiserror(15339,-1,-1,'sp_addmessage')
go
create procedure sp_addmessage
@msgnum int = null,		-- Number of new message.
@severity smallint = null,	-- Severity of new message.
@msgtext varchar(255) = null,	-- Text of new message.
@lang varchar(30) = null,       -- language (name) of new message
@with_log varchar(5) = 'FALSE', -- Whether the message will ALWAYS go to the NT event log
@replace varchar(7) = null	-- Optional parameter to specify that
				-- existing message with same number
				-- should be overwritten.
as
declare @retcode int
declare @langid smallint
declare @dlevel smallint

if @msgnum is null or @severity is null or @msgtext is null
	begin
		raiserror(15071,-1,-1)
		return(1)
	end

/*
** User defined messages must be > 50000.
*/
if @msgnum <= 50000
	begin
		raiserror(15040,-1,-1)
		return(1)
	end

/*
** Valid severity range for user defined messges is 1 to 25.
*/
if @severity not between 1 and 25
	begin
		raiserror(15041,-1,-1)
		return(1)
	end

/*
** Only the SA may add messages with severity > 18 or which set the WITH_LOG option to 'true'
*/
if suser_id() <> 1 and ((@severity > 18) or (rtrim(upper(@with_log)) = 'TRUE'))
	begin
		raiserror(15042,-1,-1)
		return (1)
	end

/*
** Verify the language
*/
if @lang is not null
	begin
		exec @retcode = sp_validlang @lang
		if @retcode <>  0
			return(1)
	end
else
	select @lang = @@language

/*
** Get langid from syslanguages; us_english won't exist, so use 0.
*/
select @langid = isnull((select langid from syslanguages where name = @lang),0)

/*
** @with_log must be 'TRUE' or 'FALSE'
*/
if (upper(@with_log) not in ('TRUE', 'FALSE'))
	begin
		raiserror(15271,-1,-1)
		return (1)
	end

/*
** Set the dlevel bit accordingly
*/
if (rtrim(upper(@with_log)) = 'TRUE')
        select @dlevel = 0x80
else
        select @dlevel = 0x0

/*
** If we're adding a non-us_english message, make sure the us_english version already exists.
*/
if (@langid not in (0, null)) and not exists (select * from sysmessages where error=@msgnum and langid in (0, null))
	begin
		raiserror(15279,-1,-1,@lang)
		return(1)
	end

/*
** If we're adding a non-us_english message, make sure that the severity matches that of the us_english version 
*/
if (@langid not in (0, null)) and not exists (select * from sysmessages where error=@msgnum and severity=@severity and langid in (0, null))
	begin
		declare @us_english_severity smallint
		select @us_english_severity = severity from sysmessages where error=@msgnum and langid in (0, null)
		raiserror(15304,-1,-1,@lang,@us_english_severity)
		return(1)
	end

/*
**  Does this message already exist, and if so are we REPLACEing it?
*/
if (select count(*) from sysmessages where error=@msgnum and langid=@langid) > 0
	if lower(@replace) = 'replace'
		begin
			raiserror(15342,-1,-1)
			delete from sysmessages where error = @msgnum and langid = @langid
			/*
			** If we're REPLACEing a us_english message, make sure any non-us_english messages get updated with the same severity
			*/
			if (@langid in (0, null))
				begin
					update sysmessages set severity = @severity
					where error = @msgnum and langid not in (0, null)
				end
		end
	else
		begin
			/*
			** The 'replace' option wasn't specified and a
			** msg. with the number already exists.
			*/
			raiserror(15043,-1,-1)
			return(1)
		end

/*
**  Create the message.
*/
insert into sysmessages(error,severity,description,dlevel,langid)
	values (@msgnum,@severity,@msgtext,@dlevel,@langid)

if (@@error = 0)
   raiserror(15343,-1,-1)

return (0)
go



raiserror(15339,-1,-1,'sp_addumpdevice')
go
create procedure sp_addumpdevice -- 1995/09/07 12:01
@devtype varchar(10),      /* disk, tape, or diskette */
@logicalname   varchar(30),      /* logical name of the device */
@physicalname  varchar(127),     /* physical name of the device */
@cntrltype  smallint = null,  /* controller type - ignored. */
@devstatus  varchar(40) = 'noskip'  /* device characteristics */
as

declare @status smallint      /* status bits for device */
declare @returncode int

/*
**  An open txn might jeopardize a recovery.
*/
if @@trancount > 0
   begin
      raiserror(15002,-1,-1,'sp_addumpdevice')
      return (1)
   end

/*
**  You must be SA to execute this sproc.
*/
if suser_id() <> 1
   begin
      raiserror(15003,-1,-1)
      return (1)
   end

/*
**  Check to see that the @logicalname is valid.
*/
exec @returncode = sp_validname @logicalname
if @returncode <> 0
   return(1)

select @devtype=lower(@devtype)

/*
**  Check out the @devtype.
*/
if @devtype not in ('disk', 'tape', 'diskette', 'pipe')
   begin
      raiserror(15044,-1,-1,@devtype)
      return (1)
   end

/*
**  Check the args are not NULL.
*/
if @logicalname is null
   begin
      raiserror(15045,-1,-1)
      return(1)
   end

if @physicalname is null
   begin
      raiserror(15046,-1,-1)
      return(1)
   end

/*
**  Make sure physical file name would be unique among devices.
*/
if exists (select * from sysdevices where phyname = @physicalname)
   begin
      raiserror(15061,-1,-1,@physicalname)
      return (1)
   end

/*
**  Prohibit certain special english words from being logical names.
*/
if (@logicalname IN ('disk' ,'diskette' ,'tape' ,'floppy'))
   begin
      raiserror(15285,-1,-1,@logicalname)
      return (1)
   end

/*
**  Make sure that a device with @logicalname doesn't already exist.
*/
if exists (select * from sysdevices where name = @logicalname)
   begin
      raiserror(15026,-1,-1,@logicalname)
      return (1)
   end

/*
**  Always turn on the dump status bit.
*/
select @status = 16

/*
**  If @devtype is a tape then check to see if devstatus is 'skip'.
*/
if @devtype = 'tape'
   begin
      if @devstatus not in ('noskip','skip')
         begin
            raiserror(15047,-1,-1)
            return (1)
         end

      if @devstatus = 'skip' select @status = @status | 8
   end

/*
**  If a disk then the cntrltype = 2
*/
if @devtype = 'disk'
   begin
      insert into sysdevices
         (low, high, status, cntrltype, name, phyname)
         values
         (0, 0, @status, 2, @logicalname, @physicalname)
      print '''Disk'' device added.'
   end

/*
**  If a diskette then the cntrltype in (3,4)
*/
if @devtype = 'diskette'
   begin
      insert into sysdevices
         (low, high, status, cntrltype, name, phyname)
         values
         (0, 0, @status, 3, @logicalname, @physicalname)
      print '''Diskette'' device added.'
   end

/*
**  Tape device.
*/
if @devtype = 'tape'
   begin
      insert into sysdevices
         (low, high, status, cntrltype, name, phyname)
         values
         (0, 0, @status, 5, @logicalname,@physicalname)
      print '''Tape'' device added.'
   end

/*
** Pipe.
*/
if @devtype = 'pipe'
   begin
      insert into sysdevices
         (low, high, status, cntrltype, name, phyname)
         values
         (0, 0, @status, 6, @logicalname,@physicalname)
      print '''Pipe'' device added.'
   end

return (0)
go



raiserror(15339,-1,-1,'sp_adduser')
go
create procedure sp_adduser
@loginame varchar(30),			-- user's login name in syslogins
@name_in_db varchar(30) = NULL,		-- user's name to add to current db
@grpname varchar(30) = NULL		-- group to put new user in
as

declare @suid		int		-- user's system id
declare @grpid		int		-- group id of group to put user in
declare @uid		int		-- new user's id
declare @returncode	int

/*
**  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

/*
**  If no new user name is given, use the login name.
*/
if @name_in_db is null
	select @name_in_db = @loginame

/*
**  Check to see that the @name_in_db is valid.
*/
exec @returncode = sp_validname @name_in_db
if @returncode <> 0
	return(1)

/*
**  Check to see if the user already exists in the database.
*/
if exists (select * from sysusers where name = @name_in_db)
	begin
		raiserror(15023,-1,-1,@name_in_db)
		return (1)
	end

/*
** The repl_subscriber user can only be mapped to the repl_subscriber
** login.
*/
if (@loginame='repl_subscriber' or @name_in_db='repl_subscriber')
	and @loginame<>@name_in_db
		begin
			raiserror(15070,-1,-1)
			return(1)
		end

/*
**  Check to see that the user has a login name.
**  We'll also initialize @grpid to 0 while we're here.
*/
select @suid = suid, @grpid = 0 from syslogins where name = @loginame

/*
** If the login doesn't exist and it isn't the special case
** where user was specified as 'guest', return an error.
*/
if @suid is null and (@name_in_db <> 'guest' or @loginame <> 'guest')
	begin
		raiserror(15007,-1,-1,@loginame)
		return (1)
	end

/*
** Can't map guest user to a real login.
*/
if @suid is not null and @name_in_db = 'guest' and @loginame <> 'guest'
	begin
		raiserror(15062,-1,-1)
		return (1)
	end

/*
**  If they specified 'guest' and we got to here, add the guest user.
*/
if @name_in_db = 'guest' and @loginame = 'guest'
	begin
		/*
		**  Add the guest user and return.
		*/
		insert into sysusers (uid, suid, gid, name)
			values (2, -1, 0, 'guest')
		print 'The ''guest'' user has been added.'
		return (0)
	end

/*
**  See if the login already has an account under a different user name.
**  That is, is the user's suid already in the sysusers table.
*/
if exists (select * from sysusers where suid = @suid)
	begin
		raiserror(15063,-1,-1)
		return (1)
	end

/*
**  See if the user is known in the database already with an alias.
**  That is, does the user's suid appear in the sysalternates table.
*/
if exists (select * from sysalternates where suid = @suid)
	begin
		raiserror(15022,-1,-1)
		return (1)
	end

/*
**  If a group name is given, check to see that it is valid.
**  User ids are > 0 and <= 16383 and group ids are > 16383.
*/
if @grpname IS NOT NULL
begin
	select @grpid = -1
	select @grpid = gid from sysusers
	where name = @grpname and (uid > 16383 or uid = 0)

	if @grpid = -1
	begin
		raiserror(15014,-1,-1,@grpname)
		return (1)
	end
end

/*
**  Calculate the first available uid.
*/
if @name_in_db='repl_subscriber'
	select @uid=16383
else
	if (select count(*) from sysusers where uid between 3 and 16382) = 0
		select @uid=3
	else
		select @uid=min(s1.uid)+1 from sysusers s1
		where uid < 16382	/* Don't go into uid range of groups. */
		and uid > 1
		and not exists
			(select * from sysusers s2
			where s2.uid = s1.uid+1)

/* Error if no more user id's available */
if @uid is null
	begin
		raiserror(15065,-1,-1)
		return (1)
	end


insert into sysusers (uid, suid, gid, name)
	values (@uid, @suid, @grpid, @name_in_db)

print 'New user added.'

return (0)
go


raiserror(15339,-1,-1,'sp_addremotelogin')
go
create procedure sp_addremotelogin
@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

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

/*
**  Check that the server name is valid.
*/
if not exists (select * from sysservers
		where srvname = @remoteserver)
	begin
		raiserror(15015,-1,-1,@remoteserver)
		return (1)
	end

/*
**  There are three cases to handle.
**
**	1) if only @remoteserver is given then a entry is made in
**		sysremotelogins that means anyone that doesn't have
**		an exact of mapped match in sysremotelogins will use
**		their remotename as their local name and it will be looked
**		up in syslogins.
**
**	2) if @remotename is omitted then it means that anyone from the
**		remote server logging in that doesn't have a complete
**		match in sysremotelogins will be mapped to @loginame.
**
**	3) if @remotename and @loginame are given then it is a straight
**		remote login for sysremotelogins.
*/

/*
**  Case 1:  Only @remoteserver given.
*/
if @loginame is null and @remotename is null
begin
	/*
	**  Check that there is not already an entry for local mapping.
	*/
	if exists (select *
		from sysremotelogins l, sysservers s
			where l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.remoteusername is null)
	begin
		raiserror(15066,-1,-1,@remoteserver)
		return (1)
	end

	/*
	**  Add the entry.
	*/
	insert into sysremotelogins
		(remoteserverid, remoteusername, suid, status)
	select srvid, null, -1, 0
		from sysservers
			where srvname = @remoteserver
	print 'New remote login created.'
	return (0)

end

/*
**  Check that the @loginame is valid.  These is needed for both
**  case 2 and 3.
*/
if not exists (select * from syslogins where name = @loginame)
	begin
		raiserror(15067,-1,-1,@loginame)
		return (1)
	end

/*
**  Check to make sure that there is not already a @remotename for
**  the @remoteserver.
*/
if exists (select *
		from sysremotelogins l, sysservers s
			where l.remoteserverid = s.srvid
			and s.srvname = @remoteserver
			and l.remoteusername = @remotename)
	begin
		select @remotename = isnull(@remotename,'NULL')
		raiserror(15068,-1,-1,@remotename,@remoteserver)
		return (1)
	end

/*
**  Case 2: We want to make an entry into sysremotelogins that will map
**	any non-exact matches to a particular local user.
*/
if @remotename is null
begin
	/*
	**  Check that there is not already an entry for local mapping.
	*/
	if exists (select *
		from sysremotelogins l, sysservers s
			where l.remoteserverid = s.srvid
			and s.srvname = @remoteserver
			and l.remoteusername is null)
		begin
			raiserror(15066,-1,-1,@remoteserver)
			return (1)
		end

	/*
	**  Go ahead and make the entry.
	*/
	insert into sysremotelogins
		(remoteserverid, remoteusername, suid, status)
	select srvid, null, suser_id(@loginame), 0
		from sysservers
				where srvname = @remoteserver

	print 'New remote login created.'
	return (0)
end

/*
**  Case 3:  All the parameters have been supplied.  All we need to check
**	is that the entry isn't already in sysremotelogins.
**	We've verified the @remoteserver and @loginame above.
*/
if @loginame IS NOT NULL and @remotename IS NOT NULL
begin
	/*
	**  Make sure that the @loginame and @remotename are a
	**  unique combination.
	*/
	if exists (select *
		from sysremotelogins l, sysservers s
			where l.remoteusername = @remotename
				and l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.suid = suser_id(@loginame))
	begin
		raiserror(15068,-1,-1,@remotename,@remoteserver)
		return (1)
	end

	/*
	**  Go ahead the do the insert.
	*/
	insert into sysremotelogins
		(remoteserverid, remoteusername, suid, status)
	select srvid, @remotename, suser_id(@loginame), 0
		from sysservers
			where srvname = @remoteserver
	print 'New remote login created.'
	return (0)
end

/*
**  We got here because the syntax was incorrect.
*/
raiserror(15072,-1,-1)
return (1)
go


raiserror(15339,-1,-1,'sp_addsegment')
go
create procedure sp_addsegment
@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 @retcode	int
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_addsegment')
		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

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

/*
**	Check that the device is a database device.
*/

if not exists (select * from sysdevices
		where name like @devname
			and cntrltype in (0,7))
	begin
		raiserror(15035,-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, return 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.
*/

/*
**  Check that @segname doesn't already exist.
*/
if exists (select * from syssegments holdlock where name = @segname)
begin
	raiserror(15027,-1,-1,@segname)
	return (1)
end

/*
**  Figure out the next segment number to use.
**  Segment number may be 0-31.
*/
select @segbit = 3
while @segbit < 32
begin
	/*
	**  Did we find one?
	*/
	if exists (select *
			from syssegments
				where segment = @segbit)
	begin
		select @segbit = @segbit + 1
	end

	/*
	**  We found an opening so break out.
	*/
	else break

end

if @segbit >= 32
begin
	raiserror(15075,-1,-1)
	return (1)
end

/*
**  Add the new segment.
*/
insert into syssegments (segment, name, status)
	values (@segbit, @segname, 0)

/*
**  Now set the segments on @devname sysusages.
*/
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
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()

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

return (0)
go


raiserror(15339,-1,-1,'sp_addserver')
go
create procedure sp_addserver  --1996/02/28 10:45
    @server          varchar(30)          --server name
   ,@local           varchar(10) = NULL   --local server, or fallback
   ,@duplicate_ok    varchar(13) = NULL   --duplicate_ok
as

declare @srvid          smallint
       ,@fallback_bit   integer

---- If we are in a transaction, disallow this since it might make
----   recovery impossible.

if @@trancount > 0
   begin
      raiserror(15002,-1,-1,'sp_addserver')
      return (1)
   end

---- Server names must be unique so check.

if exists (select * from sysservers where srvname = @server)
   begin
      if @duplicate_ok = 'duplicate_ok'
         return (0)
      raiserror(15028,-1,-1,@server)
      return (1)
   end

---- Check to see that the @server is valid.

declare @returncode   int
execute @returncode = sp_validname @server
if @returncode <> 0
   return(1)


if (@local is not null)
   select @local = lower(@local)

---- If this is the not the local server, then get the first available srvid.

if (@local is null)
   begin
      ---- If no servers are found, use #1.
      select @srvid = isnull(min(srvid)+1,1)
         from sysservers s1
         where srvid < 32767   -- Avoid arithmetic overflow.
         and not exists
            (select * from sysservers s2
            where s2.srvid = s1.srvid+1)

      insert into sysservers
         (srvid, srvstatus, srvname, srvnetname)
         values
         (@srvid, 1, @server, @server)

   GOTO LABEL_75_DONE
   end

---- Handle fallback server.

if (@local='fallback')
   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 exists (select * from master..sysservers
                where srvstatus & @fallback_bit > 0)
      begin
      RaisError(15378,-1,-1)
      return(1)
      end

   select @srvid = isnull(min(srvid)+1,1)
      from sysservers s1
      where srvid < 32767  -- Avoid arithmetic overflow.
      and not exists
         (select * from sysservers s2
         where s2.srvid = s1.srvid+1)

   insert into sysservers
      (srvid, srvstatus, srvname, srvnetname)
      values
      (@srvid, (1+ @fallback_bit), @server, @server)

   GOTO LABEL_75_DONE
   end

---- If @local = 'local' then this is the local server and its srvid = 0.

if (@local = 'local')
   begin
      if exists (select * from sysservers where srvid = 0)
         begin
            raiserror(15090,-1,-1)
            return (1)
         end

      insert into sysservers
         (srvid, srvstatus, srvname, srvnetname)
         values (0, 0, @server, @server)

   GOTO LABEL_75_DONE
   end

RaisError(15379,-1,-1,@local)  -- error, unrecognized.

LABEL_75_DONE:

print 'Server added.'
return (0)
go


dump transaction master with no_log
go


raiserror(15339,-1,-1,'sp_addtype')
go
create procedure sp_addtype
@typename varchar(30),		-- name of user-defined type
@phystype varchar(30),		-- physical system type of user-defined type
@nulltype varchar(8) = null	-- nullability of new type
as

declare @len int		-- length of user type
declare @type tinyint		-- typeid of physical type
declare @tlen tinyint		-- length of physical type
declare @typeid smallint	-- user typeid of physical type
declare @var bit		-- is physical type variable length?
declare @nonull bit		-- default is getansinull()
declare @nullegal bit		-- does physical type allow NULLs?
declare @prec int		-- precision of the datatype
declare @scale int		-- scale of the datatype
declare @tprec tinyint		-- precision of the datatype read from systypes
declare @tscale tinyint		-- scale of the datatype read from systypes

select @nulltype = lower(@nulltype)

/*
**  Types based on 'bit' cannot be nullable.
*/
if lower(@phystype) = 'bit'
	if @nulltype is null	-- If user didn't specify nullability,
				-- make sure it doesn't get set to nullable
				-- by getansinull()
		select @nulltype = 'not null'
	else			-- Also make sure that user doesn't try
				-- to explicitly set it to nullable.
		if @nulltype = 'null'
			begin
				raiserror(15276,-1,-1)
				return(1)
			end

/*
**  Should the user type allow NULLs?
*/
if @nulltype is null
	select @nonull = abs(getansinull()-1)
else if @nulltype = 'null'
	select @nonull = 0
else if @nulltype in ('not null','nonull')
	select @nonull = 1
else
	begin
		raiserror(15085,-1,-1)
		return (1)
	end

/*
**  Check to see that the @typename is valid.
*/
declare @returncode int
execute @returncode = sp_validname @typename
if @returncode <> 0
	return(1)

/*
**  Check to see if the user type already exists or a system type
**  whose name = lower(@typename) (or a synomym) already exists.
*/
if exists (select * from systypes where name = @typename)
		or lower(@typename)
		in ('character','character varying','char varying',
			'integer','dec','binary varying')

	begin
		raiserror(15029,-1,-1,@typename)
		return (1)
	end

/*
** Make physical typename all lower case to ensure case insensitivity.
*/
select @phystype = lower(@phystype)

/*
** Can't supply length with sysname type.
*/
if @phystype like 'sysname%(%'
	begin
		raiserror(15270,-1,-1)
		return(1)
	end

/*
** initialize the length to be NULL first.
*/
select @len = NULL

/*
** If precision and scale were given with the type - extract them
*/
if @phystype like '_%(_%,_%)'
begin
	select @prec = convert(int, substring(@phystype,
		charindex('(',@phystype) + 1,
		charindex(',',@phystype) - 1 - charindex('(',@phystype)))

	select @scale = convert(int, substring(@phystype,
		charindex(',',@phystype) + 1,
		charindex(')',@phystype) - 1 - charindex(',',@phystype)))
	/*
	** Extract the physical type name
	*/
	select @phystype = substring(@phystype, 1,
		   charindex('(', @phystype) - 1)
end
else

/*
**  If a length was given with the user datatype, extract it.
*/
if @phystype like '_%(%)'
begin
	select @len = convert(int, substring(@phystype,
		charindex('(',@phystype) + 1,
		charindex(')',@phystype) - 1 - charindex('(',@phystype)))

	/*
	** Extract the physical type name
	*/
	select @phystype = substring(@phystype, 1,
		   charindex('(', @phystype) - 1)
end

if @phystype='character'
	select @phystype='char'
else if @phystype='character varying'
	select @phystype='varchar'
else if @phystype='char varying'
	select @phystype='varchar'
else if @phystype='integer'
	select @phystype='int'
else if @phystype='dec'
	select @phystype='decimal'
else if @phystype='binary varying'
	select @phystype='varbinary'

/*
**  Make sure that the physical type exists and get its characteristics.
**  System physical types have a usertype < 100 and are owned by the
**  dbo (userid = 1).
*/
select @type = type, @tlen = length, @typeid = usertype,
	@var = variable, @nullegal = allownulls, @tprec = prec,
	@tscale = scale
from systypes
	where usertype < 100 and name = @phystype and uid = 1

if @type is null
begin
	raiserror(15036,-1,-1,@phystype)
	return (1)
end

/*
**  Disallow user-defined datatypes on timestamps.  This is done because
**  a timestamp is not a basic type but is really a binary.  There is,
**  therefore, no way to tell if a user-defined datatype is mapped to
**  a binary or a timestamp.  Timestamps can't have rules or defaults.
*/
if @phystype = 'timestamp'
begin
	raiserror(15038,-1,-1)
	return (1)
end

/*
**  Check if the NULL status of the user type is consistent with the NULL status
**  of the physical type.  Here are the possible cases.
**
**		   physical type
**		  NULLs	  NONULLs
**	        -----------------
** user	NULLs	|  ok	|  no
** type NONULLs	|  ok	|  ok
*/
if @nonull = 0 and @nullegal = 0
	begin
		raiserror(15037,-1,-1,@phystype)
		return (1)
	end

/*
**  We'll use the variable @nullegal when we update the systypes table
**  so we need to set it to reflect if NULLs are allowed (@nonull = 0)
**  or NO NULLs are allowed (@nonull = 1).
*/
if @nonull = 0
	select @nullegal = 1
else
	select @nullegal = 0


/* Decide about precision, scale, length
** First check from NUMERIC, DECIMAL
*/
if (@typeid = 24) or  (@typeid = 10)
begin
	/* Type is NUMERIC or DECIMAL */

	if @len > 0
		begin
			/* Length is really the precision
			** Since no scale is specified then scale
			** is minimum(Default, precision). Default = 4
			*/
			select @prec = @len
			select @scale = 0
		end
	else
		if (@prec is NULL)
			begin
				select @prec = 18
				select @scale = 0
			end

	if (@prec > 38) or (@prec < 1)
		begin
			raiserror(15086,-1,-1)
			return (1)
		end

	if (@scale > @prec) or (@scale < 0)
		begin
			/*
			** Illegal scale specified -- must be less than precision
			** and positive.
			*/
			raiserror(15087,-1,-1)
			return (1)
		end

	/* Compute length from precision */
	if (@prec <= 2)
		select @len = 2

	if (@prec > 2) and (@prec <= 4)
		select @len = 3

	if (@prec > 4) and (@prec <= 7)
		select @len = 4

	if (@prec > 7) and (@prec <= 9)
		select @len = 5

	if (@prec > 9) and (@prec <= 12)
		select @len = 6

	if (@prec > 12) and (@prec <= 14)
		select @len = 7

	if (@prec > 14) and (@prec <= 16)
		select @len = 8

	if (@prec > 16) and (@prec <= 19)
		select @len = 9

	if (@prec > 19) and (@prec <= 21)
		select @len = 10

	if (@prec > 21) and (@prec <= 24)
		select @len = 11

	if (@prec > 24) and (@prec <= 26)
		select @len = 12

	if (@prec > 26) and (@prec <= 28)
		select @len = 13

	if (@prec > 28) and (@prec <= 31)
		select @len = 14

	if (@prec > 31) and (@prec <= 33)
		select @len = 15

	if (@prec > 33) and (@prec <= 36)
		select @len = 16

	if (@prec > 36) and (@prec <= 38)
		select @len = 17
end
else

/*
**  Typeids 1 (char), 2 (varchar), 3 (binary) and 4 (varbinary) are the
**  only ones which allow a length to be specified.
*/
if @typeid > 4
	begin
		/*
		**  We can't use a length and we got one.
		*/
		if @len > 0
			begin
				raiserror(15088,-1,-1)
				return (1)
			end

		/*
		**  Use the fixed length of the physical type.
		*/
		select @len = @tlen
		select @prec = @tprec
		select @scale = @tscale
	end
else
	begin
		/*
		**  We need a length and we didn't get one.
		*/
		if @len is null
			begin
				raiserror(15091,-1,-1)
				return (1)
			end

		if @len <= 0 or @len > 255
			begin
				raiserror(15092,-1,-1)
				return (1)
			end

		select @prec = @len
		select @scale = @tscale
	end

/*
**  Finally, get the maximum existing user type so we use it + 1 for this
**  new type.
*/
select @typeid = max(usertype)
	from systypes

/*
**  There are no user defined types yet so use the first number (101).
*/
if @typeid < 100
	select @typeid = 100

insert systypes (uid, variable, type, length, tdefault,
	domain, name, usertype, allownulls, prec, scale)
select user_id(), @var, @type, @len, 0, 0, @typename, @typeid + 1, @nullegal,
	  @prec, @scale

print 'Type added.'

return (0)
go


raiserror(15339,-1,-1,'sp_addlanguage')
go
create procedure sp_addlanguage
@language varchar(30),
@alias varchar(30) = NULL,
@months varchar(251),
@shortmons varchar(119),
@days varchar(216),
@datefmt char(3),
@datefirst tinyint
as

declare @msg varchar(250)
declare @nextlangid smallint
declare @returncode int

/*  Check to see if the language exists. */
if exists (select * from syslanguages where name = @language)
	begin
		raiserror(15039,-1,-1,@language)
		return (1)
	end

/* Check to see that the list of full month names is valid. */
execute @returncode = sp_chklangparam @months, 'full month', 12, 20
if @returncode <> 0
	return (1)

/* Check to see that the list of short month names is valid. */
execute @returncode = sp_chklangparam @shortmons, 'short month', 12, 9
if @returncode <> 0
	return (1)

/* Check to see that the list of day names is valid. */
execute @returncode = sp_chklangparam @days, 'day', 7, 30
if @returncode <> 0
	return (1)

/* Check to see that the @datefmt is valid. */
if (@datefmt <> 'mdy' and @datefmt <> 'dmy' and @datefmt <> 'ymd' and @datefmt <> 'ydm'
	and @datefmt <> 'myd' and @datefmt <> 'dym')
begin
	raiserror(15093,-1,-1,@datefmt)
	return (1)
end

/*
**  Check to see that the @datefirst is valid.
*/
if (@datefirst < 1 or @datefirst > 7)
begin
	select @msg = convert(char(3), @datefirst)
	raiserror(15094,-1,-1,@msg)
	return (1)
end

/*
**  If the user didn't specify the alias name, the alias name is same as
**  the official name.
*/
if @alias is null
begin
	select @alias =  @language
end

/*  Check to see if the alias exists. */

if exists (select * from syslanguages where alias = @alias)
	begin
		raiserror(15034,-1,-1,@alias)
		return (1)
	end

if @language = 'us_english'
begin
	/*  The language id of us_english is 0. */
	insert syslanguages (langid, dateformat, datefirst, upgrade,
		name, alias, months, shortmonths, days)
	select 0, @datefmt, @datefirst, 0,
		@language, @alias, @months, @shortmons, @days
end
else
begin

	if (select max(langid) from syslanguages) is null
		select @nextlangid = 1
	else
		select @nextlangid = (select max(langid)+1
		from syslanguages)

	insert into syslanguages
		(langid, dateformat, datefirst, upgrade, name, alias,
			months, shortmonths, days)
	select @nextlangid, @datefmt, @datefirst, 0,
		@language, @alias, @months, @shortmons, @days
end


/* If the insert failed, say so. */
if @@error <> 0
	begin
		raiserror(15095,-1,-1)
		return(1)
	end

print 'New language inserted.'
go


raiserror(15339,-1,-1,'sp_altermessage')
go
create procedure sp_altermessage
@message_id       int,
@parameter        varchar(30),
@parameter_value  varchar(5)
as
begin
  declare @rows_affected  varchar(16)
  declare @msg            varchar(128)

  select @parameter = upper(@parameter)
  select @parameter_value = upper(@parameter_value)

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

  /*
  ** Does this message exist?
  */
  if (not exists (select * from master.dbo.sysmessages
                  where error = @message_id))
  begin
          raiserror(15179,-1,-1,@message_id)
          return (1)
  end

  /*
  ** Is Parameter 'WITH_LOG'?
  */
  if (@parameter <> 'WITH_LOG')
  begin
	raiserror(15176,-1,-1)
	return (1)
  end

  /*
  ** Is ParameterValue TRUE or FALSE?
  */
  if (@parameter_value not in ('TRUE', 'FALSE'))
  begin
          raiserror(15277,-1,-1)
          return (1)
  end

  /*
  ** Determine the number of messages affected
  */
  select @rows_affected = convert(varchar(16), count(*)) from master.dbo.sysmessages
       where error = @message_id
  select @msg = @rows_affected + ' Messages altered.'

  /*
  ** Turn dlevel bit 7 on or off
  */
  if (@parameter_value = 'TRUE')
  begin
          update master.dbo.sysmessages
                  set dlevel = dlevel | 0x80
                          where error = @message_id
          if (@@error = 0)
          begin
                  if (convert(int, @rows_affected) = 1) PRINT 'Message altered.'
                  if (convert(int, @rows_affected) > 1) PRINT @msg
          end
  end
  else
  if (@parameter_value = 'FALSE')
  begin
          update master.dbo.sysmessages
                  set dlevel = dlevel & 0x7FFFFF7F
                          where error = @message_id
          if (@@error = 0)
          begin
                  if (convert(int, @rows_affected) = 1) PRINT 'Message altered.'
                  if (convert(int, @rows_affected) > 1) PRINT @msg
          end
  end
  return (0)
end
go


raiserror(15339,-1,-1,'sp_defaultlanguage')
go
create procedure sp_defaultlanguage
@loginame varchar(30),			/* login name of the user */
@language varchar(30) = NULL		/* default language for the new user */
as

declare @msg varchar(250)
declare @returncode int

/*
**  Only the system administrator (sa) can run this command.
**  Check to make sure the executor is the sa.
*/
if (suser_id() <> 1 and suser_id() <> suser_id(@loginame))
begin
	raiserror(15096,-1,-1,@loginame,@loginame)
	return (1)
end

/*
**  Check to see that the @language is valid.
*/
if @language is not null
begin
	execute @returncode = sp_validlang @language
	if @returncode <> 0
		return(1)
end

/*
**  Make sure the login already exists.
*/
if not exists (select * from syslogins where name = @loginame)
	begin
		raiserror(15007,-1,-1,@loginame)
		return (1)
	end

/*
**  Set the default language for this user.
*/
update syslogins
	set language = @language
	 	where name = @loginame

select @msg =  @loginame + '''s default language is changed to ' + @language
print @msg

return (0)
go


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

/* Print all languages if the user didn't give the language name. */
if @language is null
begin
	if exists (select * from syslanguages)
		select * from syslanguages
	else
		print 'No alternate languages are available.'

	/* Find out whether us_english is there or not. */
	if not exists (select * from syslanguages
			where name = 'us_english')
		print 'us_english is always available, even though it is not in syslanguages.'

	return (0)
end

/*  Report information on this language. */
if exists (select * from syslanguages where name = @language)
	begin
		select * from syslanguages where name = @language
		return (0)
	end

if exists (select * from syslanguages where alias = @language)
	begin
		select * from syslanguages where alias = @language
		return (0)
	end

/* Couldn't find this language. */
if @language = 'us_english'
	begin
		print 'us_english is always available, even though it is not in syslanguages.'
		return (0)
	end
else
	begin
		raiserror(15033,-1,-1,@language)
		return (1)
	end
go


raiserror(15339,-1,-1,'sp_droplanguage')
go
create procedure sp_droplanguage
@language varchar(30),
@dropmessages varchar(30) = NULL
as

declare @langid smallint
declare @dropmsgs int


/*  Check to see if the language exists. */
if not exists (select * from syslanguages where name = @language)
	begin
		raiserror(15033,-1,-1,@language)
		return (1)
	end

/* Get language id from syslanguages. */
select @langid = (select langid
			from syslanguages
				where name = @language)

/*  Check to see if 'dropmessages' is requested. */
select @dropmsgs = 0
if @dropmessages is null
	begin
		if exists (select * from sysmessages where langid = @langid)
			begin
				/*
				**  Cannot drop a language if the language has associated
				**  entries in the sysmessages.
				*/	
				raiserror(15097,-1,-1,@language)
				return (1)
			end
	end
else
	begin
		if @dropmessages <> 'dropmessages'
			begin
				raiserror(15098,-1,-1)
				return (1)
			end

		select @dropmsgs = 1
	end

/*
**  Drop the language and delete messages from Sysmessages if there is any.
*/
if @dropmsgs = 1
	delete sysmessages where langid = @langid

delete syslanguages
	where langid = @langid

print 'Language deleted.'

go


raiserror(15339,-1,-1,'sp_setlangalias')
go
create procedure sp_setlangalias
@language varchar(30),
@alias varchar(30)
as

declare @returncode int

/*  Check to see if the language exists. */
exec @returncode = sp_validlang @language
if @returncode <> 0
	return (1)

/*  Check to see if the alias exists. */

if exists (select * from syslanguages where alias = @alias)
	begin
		raiserror(15034,-1,-1,@alias)
		return (1)
	end

/* Reset the alternate language name. */
update syslanguages set alias = @alias where name = @language

/* If the update failed, say so. */
if @@error <> 0
	begin
		raiserror(15099,-1,-1)
		return(1)	
	end

print 'Language alias reset.'
go


raiserror(15339,-1,-1,'sp_bindefault')
go
create procedure sp_bindefault
@defname varchar(92),			/* name of the default */
@objname varchar(61),			/* table or usertype name */
@futureonly varchar(15) = NULL		/* flag to indicate extent of binding */
as

declare @defid int			/* id of the default to bind */
declare @futurevalue varchar(15)	/* the value of @futureonly that causes
					** the binding to be limited */

set nocount on

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 '%.%.%')
   or
   (@defname like '%.%.%' and
	substring(@defname, 1, charindex('.', @defname) - 1) <> db_name())
begin
	raiserror(15076,-1,-1)
	return (1)
end

/*
**  Check that the @futureonly argument, if supplied, is correct.
*/
if (@futureonly IS NOT NULL)
	if (@futureonly <> @futurevalue)
		begin
			raiserror(15100,-1,-1)
			return (1)
		end

/*
**  Check to see that the default exists and get its id.
*/
select @defid = (select id from sysobjects
			where id = object_id(@defname)
				and sysstat & 0xf = 6)	-- default object

if @defid is NULL
	begin
		raiserror(15016,-1,-1,@defname)
		return (1)
	end

/*
**  If @objname is of the form tab.col then we are binding to 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 bound. We also need to ensure
**  that we don't overwrite any DRI style defaults.
*/
if @objname like '%.%'
begin
	declare @tabname varchar(30)		/* name of table */
	declare @colname varchar(30)		/* name of column */

	/*
	**  Get the table name out.
	*/
	select @tabname = substring(@objname, 1, charindex('.', @objname) - 1)
	select @colname = substring(@objname, charindex('.', @objname) + 1, 61)


	/*
	**  If the column type is timestamp, disallow the bind.
	**  Defaults can't be bound to timestamp columns.
	*/
	if exists (select *
			from syscolumns c
		        where c.id = object_id(@tabname)
			and c.name = @colname
			and c.usertype = 80)
	begin
		raiserror(15101,-1,-1)
		return (1)
	end

	/*
	**  If the column category is identity, disallow the bind.
	**  Defaults can't be bound to identity columns.
	*/
	if exists (select *
			from syscolumns c
		        where c.id = object_id(@tabname)
			and c.name = @colname
			and c.status & 128 = 128)
	begin
		raiserror(15102,-1,-1)
		return (1)
	end


        /*
	**  Check to see if the column was created with or altered
        **  to have a DRI style default value.
	*/
	if exists (select *
			from syscolumns c,sysconstraints t
		        where c.id = object_id(@tabname)
			and c.name = @colname
                        and t.id = c.id
                        and t.colid = c.colid
                        and t.status & 0xf = 5)
	begin
		raiserror(15103,-1,-1)
		return (1)
	end

        update syscolumns
		set cdefault = @defid
			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 */

	/*
	**  Did the bind happen?
	*/
	if @@rowcount <> 1
	begin
		raiserror(15104,-1,-1,@tabname,@colname)
		return (1)
	end

	/*
	**  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 bound to column.'

end
else
begin
	/*
	**  We're binding to a user type.  In this case, the @objname
	**  is really the name of the user datatype.
	**  When we bind 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.
	*/
	declare @olddefault int	/* current default for type */

	/*
	**  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(15105,-1,-1)
			return (1)
		end

	update systypes
		set tdefault = @defid
			from systypes
		where name = @objname
			and uid = user_id()
			and usertype > 100


	print 'Default bound to 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
					or syscolumns.cdefault = 0 ) )
	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
                                          or  syscolumns.cdefault = 0 )

		/*
		**  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 = @olddefault
                                          or  syscolumns.cdefault = 0 )

		print 'The new default has been bound to columns(s) of the specified user datatype.'
	end
end

return (0)
go


raiserror(15339,-1,-1,'sp_bindrule')
go
create procedure sp_bindrule
@rulename varchar(92),			/* name of the rule */
@objname varchar(61),			/* table or usertype name */
@futureonly varchar(15) = NULL		/* column name */
as

declare @ruleid int			/* id of the rule to bind */
declare @futurevalue varchar(15)	/* the value of @futureonly that causes
					** the binding to be limited */

set nocount on

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 '%.%.%')
   or
   (@rulename like '%.%.%' and
	substring(@rulename, 1, charindex('.', @rulename) - 1) <> db_name())
	begin
		raiserror(15077,-1,-1)
		return (1)
	end

/*
**  Check that the @futureonly argument, if supplied, is correct.
*/
if (@futureonly IS NOT NULL)
	begin
		if (@futureonly <> @futurevalue)
			begin
				raiserror(15106,-1,-1)
				return (1)
			end
	end

/*
**  Check to see that the rule exists and get its id.
*/
select @ruleid = (select id from sysobjects
			where id = object_id(@rulename)
				and sysstat & 0xf = 7)	-- rule object

if @ruleid is NULL
	begin
		raiserror(15017,-1,-1,@rulename)
		return (1)
	end

/*
**  If @objname is of the form tab.col then we are binding to 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 rule bound.
*/
if @objname like '%.%'
begin
	declare @tabname varchar(30)		/* name of table */
	declare @colname varchar(30)		/* name of column */

	/*
	**  Get the table name out.
	*/
	select @tabname = substring(@objname, 1, charindex('.', @objname) - 1)
	select @colname = substring(@objname, charindex('.', @objname) + 1, 61)

	/*
	**  If the column type is image, text, or timestamp, disallow the bind.
	**  Rules can't be bound to image, text, or timestamp columns.
	**  The qualification to check for types is a little strange because
	**  text and image are real, basic data types while timestamp is not.
	**  Timestamp is really a binary.  The types are checked in case
	**  there is a user-defined datatype that is an image or text.
	**  User-defined datatypes mapping to timestamp are not allowed
	**  by sp_addtype.
	*/
	if exists (select *
			from sysobjects o, syscolumns c
		where c.id = object_id(@tabname)
			and c.name = @colname
			and c.name = @colname
			and o.id = object_id(@tabname)
			and o.sysstat & 0xf = 3
			and (c.type in (35, 34) or c.usertype = 80))
		begin
			raiserror(15107,-1,-1)
			return (1)
		end

	update syscolumns
		set domain = @ruleid
			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 */

	/*
	**  Did the bind happen?
	*/
	if @@rowcount <> 1
	begin
		raiserror(15104,-1,-1,@tabname,@colname)
		return (1)
	end

	/*
	**  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 bound to table column.'

end
else
begin
	/*
	**  We're binding to a user type.  In this case, the @objname
	**  is really the name of the user datatype.
	**  When we bind 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.
	*/
	declare @oldrule int			/* current rule for type */

	/*
	**  If the column type is image, text, or timestamp, disallow the bind.
	**  Rules can't be bound to image or text columns.
	*/
	if exists (select * from systypes
			where name = @objname
				and (type in (35, 34) or usertype = 80))
		begin
			raiserror(15107,-1,-1)
			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(15105,-1,-1)
			return (1)
		end

	update systypes set domain = @ruleid
			from systypes
		where name = @objname
			and uid = user_id()
			and usertype > 100


	print 'Rule bound to 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
                                          or  syscolumns.domain = 0 )     )
	begin
		print 'The new rule has been bound to column(s) of the specified user datatype.'
		/*
		**  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
                                  or  syscolumns.domain = 0 )

		/*
		**  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 = @oldrule
                                  or  syscolumns.domain = 0 )
	end
end

return (0)
go


raiserror(15339,-1,-1,'sp_changedbowner')
go
create procedure sp_changedbowner
@loginame varchar(30),         /* login to become dbo */
@map      varchar(10) = NULL   /* True to map aliases, else drop  */
as

declare @suid    smallint
declare @oldsuid smallint

/*
**  Only the SA can change the owner of a database.
*/
if suser_id() <> 1
begin
	raiserror(15108,-1,-1)
	return(1)
end

/*
**  Can't change the owner of the master database.
*/
if db_id() = 1
begin
	raiserror(15109,-1,-1)
	return(1)
end

/*
**  Make sure that @loginame exists and has a login.
*/
select @suid = suid from syslogins where name = @loginame

if @suid is null
	begin
		raiserror(15007,-1,-1,@loginame)
		return(1)
	end

/*
**  Make sure that @loginame isn't already a user or alias in the database.
*/
if exists (select * from sysusers where suid = @suid)
	begin
		raiserror(15110,-1,-1)
		return(1)
	end

if exists (select * from sysalternates where suid = @suid)
	begin
		raiserror(15111,-1,-1)
		return(1)
	end

/*
** find old (current) dbo's suid
*/
select @oldsuid = suid
	from sysusers
		where uid = 1

begin transaction

/*
**  Now change the suid of the owner of the database to the suid of @loginame.
*/
update sysusers
	set suid = @suid
		where uid = 1

/*
** if the user requested that aliases be mapped to new dbo, do that.
*/
if lower(@map) = 'true'
begin

	if exists (select *
			from sysalternates
				where altsuid = @oldsuid)
	begin
		update sysalternates
			set altsuid = @suid
				where altsuid = @oldsuid

		print 'The dependent aliases were mapped to the new dbo.'
	end
end
/* else drop the aliases to the old dbo */
else
begin

	if exists (select *
			from sysalternates
				where altsuid = @oldsuid)
	begin
		delete from sysalternates
			where altsuid = @oldsuid

		print 'The dependent aliases were dropped.'
	end
end


/*
**  Reflect the new owner of the database in sysdatabases.
*/
update sysdatabases
	set suid = @suid
		where dbid = db_id()

commit transaction

/*
**  Checkpoint the database so that the in-memory data structure for the
**  database will be consistent with sysdatabases.
*/
checkpoint

print 'Database owner changed.'

return (0)
go


raiserror(15339,-1,-1,'sp_changegroup')
go
create procedure sp_changegroup
@grpname varchar(30),			/* group name */
@username varchar(30)			/* user name to add to group */
as

declare @gid int			/* group id */
declare @uid int			/* user id */

/*
**  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 group name exists.
*/
select @gid = uid from sysusers where name = @grpname
	and (uid > 16383 or uid = 0)

/*
**  If no such group, quit.
**  User ids are <= 16383 and group ids are > 16383 or = 0.
*/
if @gid is null
	begin
		raiserror(15014,-1,-1,@grpname)
		return (1)
	end

/*
**  See if the user name exists.
*/
select @uid = uid from sysusers where name = @username
	and (uid <= 16383 and uid > 0)

/*
**  If no such user in the database, quit.
*/
if @uid is null
	begin
		raiserror(15008,-1,-1,@username)
		return (1)
	end

/*
**  Everything is consistent so change the group.
*/
update sysusers set gid = @gid
	from sysusers where uid = @uid

/*
**  We need to invalidate the protection cache since objects have
**  changed ownership.  This command will invalidate the current
**  protection cache so when protections are checked the new and
**  correct protections will be used.
*/
grant all to null

print 'Group changed.'

return (0)
go


raiserror(15339,-1,-1,'sp_checknames')
go
create procedure sp_checknames
@mode varchar(20) = NULL		/* mode of operation; e.g. 'silent' */
as

declare @msilent	int		/* set to 1 if 'silent' mode is on */
declare @ret_val	int		/* set to 1 if we find funny char */
declare @codepoint	tinyint		/* set to 1 if we find funny char */
declare @dbname		varchar(30)	/* holds database name */
declare @msg		varchar(90)	/* used for messages to user */
declare @pat		varchar(132)	/* holds the pattern to search for */

set nocount on

if (@mode like '%help%')
begin
	print 'sp_checknames is used to search for non 7-bit ASCII characters'
	print 'in several important columns of system tables.  The following'
	print 'columns are searched:'
	print ' '
	print '    In ''master'':'
	print '        sysdatabases.name'
	print '        sysdevices.name'
	print '        syslogins.name'
	print '        syslogins.dbname'
	print '        sysremotelogins.remoteusername'
	print '        sysservers.srvname'
	print '        sysservers.srvnetname'
	print ' '
	print '    In all databases:'
	print '        syscolumns.name'
	print '        sysindexes.name'
	print '        sysobjects.name'
	print '        syssegments.name'
	print '        systypes.name'
	print '        sysusers.name'
	print ' '

	return (0)
end

/*
**  First, initialize return value, and set up mode variables:
*/
select @ret_val = 0

if (@mode like '%silent%')
	select @msilent = 1
else
	select @msilent = 0


/*
**  Now, initialize the pattern string we will search for:
*/
select @pat = '%[', @codepoint = 127
while (@codepoint < 255)
begin
	select @codepoint = @codepoint + 1
	select @pat = @pat + char(@codepoint)
end
select @pat = @pat + ']%'


/*
**  Get the database name we are in:
*/
select @dbname = db_name()

if (@msilent = 0)
begin
	print ' '
	select @msg = 'Looking for non 7-bit ASCII characters in the system ' +
			'tables of database:  ''' + @dbname + ''''
	print @msg
	print ' '
end


/*
**  Look through these only if in the master database:
*/
if (@dbname = 'master')
begin
    if exists (select name from sysdatabases
		    where name like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''sysdatabases.name'''
	print ' '
	print 'The following database names contain non 7-bit ASCII characters.'
	print 'If you wish to change their names, use ''sp_renamedb'':'
	print ' '
	select dbid,name from sysdatabases
			where name like @pat
    end

    if exists (select name from sysdevices where name like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''sysdevices.name'''
	print ' '
	print 'The following device names contain non 7-bit ASCII characters.'
	print 'If you wish to change their names, use ''UPDATE'':'
        print ' '
	select name from sysdevices where name like @pat
    end

    if exists (select name from syslogins where name like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''syslogins.name'''
        print ' '
	print 'The following login names contain non 7-bit ASCII characters.'
	print 'If you wish to change these names, use ''sp_droplogin'' and'
	print '''sp_addlogin'':'
        print ' '
	select suid,name from syslogins
			where name like @pat
    end

    if exists (select dbname from master.dbo.syslogins
		    where dbname like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''syslogins.dbname'''
	print ' '
	print 'The following logins have default database names that contain'
	print 'non 7-bit ASCII characters.  If you wish to change them use'
	print '''sp_defaultdb'':'
        print ' '
	select suid,name,dbname from master.dbo.syslogins
			where dbname like @pat
    end

    if exists (select remoteusername from master.dbo.sysremotelogins
		    where remoteusername like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''sysremotelogins.remoteusername'''
        print ' '
	print 'The following remote login names contain non 7-bit ASCII'
	print 'characters.  If you wish to change these names, use'
	print '''sp_dropremotelogin'' and ''sp_addremotelogin'':'
        print ' '
	select remoteserverid,remoteusername from master.dbo.sysremotelogins
			where remoteusername like @pat
    end

    if exists (select srvname from master.dbo.sysservers
		    where srvname like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''sysservers.srvname'''
        print ' '
	print 'The following server names contain non 7-bit ASCII characters.'
	print 'If you wish to change their names, use ''sp_dropserver'' and'
	print '''sp_addserver'':'
        print ' '
	select srvid,srvname from master.dbo.sysservers
			where srvname like @pat
    end

    if exists (select srvnetname from master.dbo.sysservers
		    where srvnetname like @pat)
    begin
	if (@msilent = 1)
	    return (1)

	select @ret_val = 1
	print ' '
	print '==============================================================='
	print 'Table.Column name:  ''sysservers.srvnetname'''
        print ' '
	print 'The following servers have ''initialization file'' names that contain'
	print 'non 7-bit ASCII characters.  If you wish to change these names,'
	print 'use ''UPDATE'':'
        print ' '
	select srvid,srvname,srvnetname from master.dbo.sysservers
			where srvnetname like @pat
    end

end


/*
**  For *ALL* databases, we want to look through these:
*/
if exists (select name from dbo.syscolumns
	    where name like @pat)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''syscolumns.name'''
    print ' '
    print 'The following column and parameter names contain non 7-bit ASCII'
    print 'characters.  If you wish to change these names, use ''sp_rename'':'
    print ' '
    select objname=o.name,colname=c.name from dbo.syscolumns c, dbo.sysobjects o
		where c.name like @pat and o.id = c.id
end

if exists (select name from dbo.sysindexes
	    where name like @pat
	    	  and indid > 0)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''sysindexes.name'''
    print ' '
    print 'The following index names contain non 7-bit ASCII characters.'
    print 'If you wish to change these names, use ''UPDATE'':'
    print ' '
    select id,indid,name from dbo.sysindexes
		where name like @pat
		and indid > 0
end

if exists (select name from dbo.sysobjects
	    where name like @pat)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''sysobjects.name'''
    print ' '
    print 'The following object names contain non 7-bit ASCII characters.'
    print 'If you wish to change these names, use ''sp_rename'':'
    print ' '
    select owner=u.name,o.name from dbo.sysobjects o,dbo.sysusers u
		where o.name like @pat and o.uid=u.uid
end

if exists (select name from dbo.syssegments
	    where name like @pat)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''syssegments.name'''
    print ' '
    print 'The following segment names contain non 7-bit ASCII characters.'
    print 'If you wish to change these names, use ''UPDATE'':'
    print ' '
    select segment,name from dbo.syssegments
		where name like @pat
end

if exists (select name from dbo.systypes
	    where name like @pat)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''systypes.name'''
    print ' '
    print 'The following datatype names contain non 7-bit ASCII characters.'
    print 'If you wish to change these names, use ''sp_rename'':'
    print ' '
    select name from dbo.systypes
		where name like @pat
end

if exists (select name from dbo.sysusers
	    where name like @pat)
begin
    if (@msilent = 1)
	return (1)

    select @ret_val = 1
    print ' '
    print '==============================================================='
    print 'Table.Column name:  ''sysusers.name'''
    print ' '
    print 'The following user or group names contain non 7-bit ASCII'
    print 'characters.  If you wish to change these names, use ''UPDATE'':'
    print ' '
    select suid,uid,name from dbo.sysusers
		where name like @pat
end

if (@ret_val = 0  and  @msilent = 0)
begin
    select @msg = 'Good news!  Database ''' + @dbname + ''' has no obj/user/etc.'
    print @msg
    print 'names that contain non 7-bit ASCII characters.'
end

return (@ret_val)
go

dump transaction master with no_log
go

raiserror(15339,-1,-1,'sp_start_xact')
go
create procedure sp_start_xact
	@applname varchar(30),
	@xactname varchar(30),
	@count	  int,
	@password varchar(30) = NULL
AS

set nocount on

BEGIN
	BEGIN TRANSACTION
		INSERT spt_committab VALUES
		(
			0,
			getdate(),
			getdate(),
			@count,
			@count,
			'b',
			@applname,
			@xactname,
			@password
		)

		UPDATE spt_committab
			set commid = 1 + (select max(commid) from spt_committab)
			where commid = 0

		SELECT max(commid) from spt_committab
	COMMIT TRANSACTION
END
go


raiserror(15339,-1,-1,'sp_commit_xact')
go
create procedure sp_commit_xact
	@commid	int,
	@password varchar(30) = NULL
AS
if exists (select *
	from spt_committab
	where commid = @commid
	and password = @password)
begin
	/*
	**  If status is aborted, return a 1 to indicate a failure.
	*/
	if exists (select *
			from spt_committab
				where commid = @commid
					and status = 'a')
	begin
		select 1
		return (1)
	end

	/*  Mark the xact as committed. */
	UPDATE spt_committab
		SET status = 'c', lastchange = getdate()
		WHERE commid = @commid
	select 0
	return (0)
end
else
begin
	/* Error so return (1) */
	raiserror 30000 'Commit service xact id doesn''t exist.'
	select 1
	return (1)
end
go


raiserror(15339,-1,-1,'sp_abort_xact')
go
CREATE PROCEDURE sp_abort_xact
	@commid	int,
	@password varchar(30) = NULL
AS
if exists (select *
	from spt_committab
	where commid = @commid
	and password = @password)
begin
	UPDATE spt_committab
		SET status = 'a' , lastchange = getdate()
		WHERE commid = @commid
END
else
begin
	raiserror 30001 'Commit service xact id doesn''t exist.'
end
go


raiserror(15339,-1,-1,'sp_remove_xact')
go
CREATE PROCEDURE sp_remove_xact
	@commid	int,
	@count	int,
	@password varchar(30) = NULL
AS
if exists (select *
	from spt_committab
	where commid = @commid
	and password = @password)
begin
	/*
	** Decrement outnum by @count.
	*/
	UPDATE spt_committab
		SET outnum = outnum - @count, lastchange = GETDATE()
		WHERE commid = @commid

	/*
	**  Delete the row if outnum < 1
	*/
	DELETE spt_committab
		WHERE commid = @commid
			and outnum < 1

end
else
begin
	raiserror 30002 'Commit service xact id doesn''t exist.'
end
go


raiserror(15339,-1,-1,'sp_stat_xact')
go
create procedure sp_stat_xact
	@commid	int
AS
BEGIN
	IF EXISTS
	(
		SELECT status
			FROM spt_committab
			WHERE commid = @commid
	)
		SELECT status
			FROM spt_committab
			WHERE commid = @commid
	ELSE
		SELECT status = 'u'
END
go


raiserror(15339,-1,-1,'sp_probe_xact')
go
create procedure sp_probe_xact
	@commid	int
AS
BEGIN
	declare @stat	char(1)

	begin tran
		IF EXISTS ( SELECT status
				FROM spt_committab
					WHERE commid = @commid)
		begin
			SELECT @stat = status
				FROM spt_committab
					WHERE commid = @commid

			if (@stat <> 'c')
			begin
				update spt_committab
					set status = 'a'
						where commid = @commid
				select status = 'a'
			end
			else select status = @stat
		end
		else select status = 'u'
	commit tran

END
go


raiserror(15339,-1,-1,'sp_processinfo')
go
create procedure sp_processinfo
as
/* ====================================================*/
/* sp_processinfo - returns detailed lock              */
/* information for the server                          */
/* Microsoft SQL Server 	               */
/* ====================================================*/

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 FullName, ProcessID

return(0)
GO

raiserror(15339,-1,-1,'sp_scan_xact')
go
create procedure sp_scan_xact
	@commid	int = NULL
as
BEGIN
	IF	@commid = -1 or @commid is NULL

		SELECT commid,start,lastchange,totnum,outnum,
		       status,applname,xactname
		FROM spt_committab
	ELSE
		SELECT commid,start,lastchange,totnum,outnum,
		       status,applname,xactname
		FROM spt_committab
		WHERE @commid = commid
END
go


raiserror(15339,-1,-1,'sp_commonkey')
go
create procedure sp_commonkey
@tabaname  varchar(92),		/* name of first table in the key */
@tabbname varchar(92),		/* name of second table in the key */
@col1a     varchar(30), 	/* first column name of first table */
@col1b     varchar(30), 	/* first column name of second table */
@col2a     varchar(30) = NULL,
@col2b     varchar(30) = NULL,
@col3a     varchar(30) = NULL,
@col3b     varchar(30) = NULL,
@col4a     varchar(30) = NULL,
@col4b     varchar(30) = NULL,
@col5a     varchar(30) = NULL,
@col5b     varchar(30) = NULL,
@col6a     varchar(30) = NULL,
@col6b     varchar(30) = NULL,
@col7a     varchar(30) = NULL,
@col7b     varchar(30) = NULL,
@col8a     varchar(30) = NULL,
@col8b     varchar(30) = NULL
as

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

declare @key1a int		/* colids of the first table */
declare @key2a int
declare @key3a int
declare @key4a int
declare @key5a int
declare @key6a int
declare @key7a int
declare @key8a int

declare @key1b int		/* colids of the second table */
declare @key2b int
declare @key3b int
declare @key4b int
declare @key5b int
declare @key6b int
declare @key7b int
declare @key8b int

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

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

/*
**  See if we can find the objects.  They must be system tables, user tables,
**  or views.  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, @uida = uid
	from sysobjects
		where id = object_id(@tabaname)
			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(15112,-1,-1)
		return (1)
	end

select @objidb = id
	from sysobjects
		where id = object_id(@tabbname)
			and sysstat & 0xf in (1,2,3)

if @objidb is NULL
	begin
		raiserror(15113,-1,-1)
 		return(1)
	end

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

/*
**  Now check to see that the first key columns exist and have compatible types.
*/
select @cnt = 1, @key1a = a.colid, @key1b = b.colid
	from syscolumns a, syscolumns b, master.dbo.spt_values y,
		master.dbo.spt_values z
		where a.name = @col1a
			and a.id = @objida
			and b.name = @col1b
			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
if @key1a is null
	begin
		raiserror(15115,-1,-1)
		return (1)
	end

if @col2a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key2a = a.colid, @key2b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col2a
				and a.id = @objida
				and b.name = @col2b
				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
	if @key2a is null
		begin
			raiserror(15116,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col3a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key3a = a.colid, @key3b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col3a
				and a.id = @objida
				and b.name = @col3b
				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
	if @key3a is null
		begin
			raiserror(15117,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col4a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key4a = a.colid, @key4b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col4a
				and a.id = @objida
				and b.name = @col4b
				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
	if @key4a is null
		begin
			raiserror(15118,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col5a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key5a = a.colid, @key5b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col5a
				and a.id = @objida
				and b.name = @col5b
				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
	if @key5a is null
		begin
			raiserror(15119,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col6a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key6a = a.colid, @key6b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col6a
				and a.id = @objida
				and b.name = @col6b
				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
	if @key6a is null
		begin
			raiserror(15120,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col7a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key7a = a.colid, @key7b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col7a
				and a.id = @objida
				and b.name = @col7b
				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
	if @key7a is null
		begin
			raiserror(15121,-1,-1)
			return (1)
		end
end
else goto keys_ok

if @col8a IS NOT NULL
begin
	select @cnt = @cnt + 1, @key8a = a.colid, @key8b = b.colid
		from syscolumns a, syscolumns b, master.dbo.spt_values y,
			master.dbo.spt_values z
			where a.name = @col8a
				and a.id = @objida
				and b.name = @col8b
				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
	if @key8a is null
		begin
			raiserror(15122,-1,-1)
			return (1)
		end
end

/*
**  If we made it this far then all the columns for the common key are ok.
**  Everything is consistent so add the common key to syskeys.
*/
keys_ok:

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, 3, @objidb, @cnt, 0, @key1a, @key2a, @key3a, @key4a, @key5a,
	@key6a, @key7a, @key8a, @key1b, @key2b, @key3b, @key4b, @key5b,
	@key6b, @key7b, @key8b)

print 'New common key added.'

return (0)
go


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

    @configname   varchar(35) = NULL   -- option name to configure
   ,@configvalue  int         = NULL   -- new configuration value
as

declare
    @confignum                int   --Num of the opt to be configured
   ,@configcount              int   --Num of options like @configname
-- ,@value_in_sysconfigures   int   --For one option, its value bef Upd
   ,@show_advance             int   --Enable/supress actions on "advanced" opts

/*
**  Determine @maxnumber based on advance option in syscurconfigs.
*/
if (select value from syscurconfigs where config = 518) = 1
   select @show_advance = 1   -- Display advanced options
else
   select @show_advance = 0   -- Don't display advanced options

/*
**  Make certain that max user info. reflects any addpak upgrades.
*/
if (select high from master.dbo.spt_values where number=103 and type='C')
   <> @@max_connections

   update master.dbo.spt_values
      set high = @@max_connections
      where number = 103
         and type='C'

/*
**  If no option name is given, the procedure will just print out all the
**  options and their values.
*/
if @configname is NULL
   begin
      select name, minimum = low, maximum = high,
         config_value = c.value,
         run_value = syscurconfigs.value
      from master.dbo.spt_values, sysconfigures c, syscurconfigs
      where type = 'C'
         and number = c.config
         and number = syscurconfigs.config
         and ((c.status/2) | @show_advance) & 1 = @show_advance
      order by lower(name)

      return (0)
   end

set nocount on

/*
**  Use @configname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @configcount = count(*)
   from master.dbo.spt_values v ,sysconfigures c
   where v.name like '%' + @configname + '%' and v.type = 'C'
      and v.number = c.config
      and ((c.status/2) | @show_advance) & 1 = @show_advance

/*
**  If no option, show the user what the options are.
*/
if @configcount = 0
   begin
      raiserror (15123,-1,-1,@configname)

      print ''
      print 'Valid configuration options are:'

      /*
      ** Show the user what the options are.
      */
      select name, minimum = low, maximum = high,
         config_value = c.value,
         run_value = syscurconfigs.value
      from master.dbo.spt_values, sysconfigures c, syscurconfigs
      where type = 'C'
         and number = c.config
         and number = syscurconfigs.config
         and ((c.status/2) | @show_advance) & 1 = @show_advance

      return (1)
   end

/*
**  If more than one option like @configname, show the duplicates and return.
*/
if @configcount > 1
   begin
      raiserror (15124,-1,-1,@configname)
      print ''

      select duplicate_options = name
      from master.dbo.spt_values,sysconfigures c
      where name like '%' + @configname + '%'
         and type = 'C'
         and number = c.config
         and ((c.status/2) | @show_advance) & 1 = @show_advance

      return (1)
   end
else
   /* There must be exactly one, so get the full name. */
   select @configname = name --,@value_in_sysconfigures = c.value
      from master.dbo.spt_values,sysconfigures c
      where name like '%' + @configname + '%' and type = 'C'
         and number = c.config
         and ((c.status/2) | @show_advance) & 1 = @show_advance

/*
** If @configvalue is NULL, just show the current state of the option.
*/
if @configvalue is null
begin
   select name, minimum = low, maximum = high,
      config_value = c.value,
      run_value = syscurconfigs.value
   from master.dbo.spt_values, sysconfigures c, syscurconfigs
   where type = 'C'
      and number *= c.config
      and number *= syscurconfigs.config
      and name like '%' + @configname + '%'
      and ((c.status/2) | @show_advance) & 1 = @show_advance
   return (0)
end

/*
**  Only the SA can execute the update part of this procedure so check.
*/
if suser_id() <> 1
   begin
      raiserror(15125,-1,-1)
      return (1)
   end

/*
**  Now get the configuration number.
*/
select @confignum = number
   from master.dbo.spt_values,sysconfigures c
   where type = 'C'
      and (@configvalue between low and high or @configvalue = 0)
      and name like '%' + @configname + '%'
      and number = c.config
      and ((c.status/2) | @show_advance) & 1 = @show_advance

/*
**  If this is the number of devices configuration parameter,
**  we want to make sure that it's not being set to lower than the
**  number of devices in sysdevices.
*/
if @confignum = 116
begin
   /*
   **  Get the max vdevno.
   */
   declare @maxvdevno int
   select @maxvdevno = max(convert(tinyint, substring(convert(binary(4),
      d.low), v.low, 1)))
   from sysdevices d, master.dbo.spt_values v
   where v.type = 'E'
      and v.number = 3

   /*
   **  If @configvalue = 0, then set it to the current number of devices.
   */
   if @configvalue = 0
   select @configvalue = @maxvdevno + 1
   if (select low from master.dbo.spt_values
         where type = 'C'
         and number = 116) > @configvalue
      begin
         select @configvalue = low
            from master.dbo.spt_values
            where type = 'C'
               and number = 116
      end

   if ((@maxvdevno + 1) > @configvalue)
      begin
         raiserror(15126,-1,-1)
         return (1)
      end
end

/*
**  If this is the number of default language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 124
   begin
   if not exists (select * from syslanguages
         where langid = @configvalue)
      begin
         /* 0 is default language, us_english */
         if @configvalue <> 0
            begin
               raiserror(15127,-1,-1)
               return (1)
            end
      end
   end

/*
**  If this is the number of kernel language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 132
   begin
   if not exists (select * from syslanguages
         where langid = @configvalue)
      begin
         /* 0 is default language, us_english */
         if @configvalue <> 0
            begin
               raiserror(15028,-1,-1)
               return (1)
            end
      end
   end

/*
**  "user options" should not try to set incompatible options/values.
*/
if @confignum = 1534  --"user options"
   begin

   if (@configvalue & (1024+2048) = (1024+2048)) --ansi_null_default_on/off
      begin
      raiserror(15303,-1,-1,@configvalue)
      return (1)
      end
   end

/*
**  Although the @configname is good, @configvalue wasn't in range.
*/
if @confignum is NULL
   begin
   raiserror(15129,-1,-1,@configvalue,@configname)
   return (1)
   end

--Msg 15002, but in 6.5 allow this inside a txn (not check @@trancount) #12828.

/*
**  Now update sysconfigures.
*/
update sysconfigures set value = @configvalue
   where config = @confignum

/*
** If this is memory parameter, we need to calculate a
** new value for number of free buffers.
*/
if @confignum = 104
   begin
   print ''
   print 'Recalculating free buffer setting.'
   update sysconfigures set value = @configvalue/20
      where config = 1515
   end

print 'Configuration option changed. Run the RECONFIGURE command to install.'

return (0)
go



raiserror(15339,-1,-1,'sp_dbinstall')
go
create procedure sp_dbinstall --1995/09/25 16:42

@dbname		varchar(30) = null,	-- name of db
@logical	varchar(30) = null,	-- logical name of device
@physical	varchar(255) = null,	-- physical name of device
@size		int = null,		-- size of device in Meg.
@dev_type	varchar(6) = null,	-- Device can be 'system' or 'data'.
@location	varchar(255) = null	-- Disk location for writable
					-- fragment.  Mandatory for
					-- system device, optional for
					-- data devices.					
as
        declare @vdevno int
	declare @dbid int
	declare @sysdb_version int
	declare @start int

	declare @filesize int
	declare @retcode int
	declare @lstart int
	declare @cmd varchar(255)
	declare @segmap int	

	/*
	** Make sure all parameters were supplied, if not print a syntax diagram.
	*/
	if	@dbname is null
		or @logical is null
		or @physical is null
		or @size is null
		or @dev_type is null
		begin
			raiserror(15130,-1,-1)
			return(1)
		end

	/* Check to see if a valid database name was supplied. */
	exec @retcode = sp_validname @dbname
	if @retcode <> 0
		return(1)

	/* Check to see if a valid device name was supplied. */
	exec @retcode = sp_validname @logical
	if @retcode <> 0
		return(1)

	select @dev_type=lower(@dev_type)

	/* Check to see if device type is valid. */
	if @dev_type not in ('system','data')
		begin
			raiserror(15048,-1,-1,@dev_type)
			return(1)
		end

	/*
        **  Check to see if we're defining the initial device or adding
	**  devices to complete an installation.
	*/

	if @dev_type = 'system'
		begin
			/* We're creating the db, so make sure it doesn't already exist. */
			if exists (select * from sysdatabases where name = @dbname)
				begin
					raiserror(15049,-1,-1)
					return(1)
				end

			/* make sure that new location is specified. */
			if @location is null
				begin
					raiserror(15052,-1,-1)
					return(1)
				end
		end
	else
		begin
			/*
			** We're appending data devices, so make sure db
			** already exists.
			*/
			if not exists (select * from sysdatabases where name = @dbname)
				begin
					raiserror(15050,-1,-1)
					return(1)
				end
		end

	/* Databases must occupy at least 1 meg on a device.
	** Have to trust the user for just how much.
	*/
	if @size < 1
		begin
			raiserror(15051,-1,-1)
			return(1)
		end

	/*
	** Make sure that devices with the supplied logical or physical
	** names don't already exist.
	*/
	if exists (select * from sysdevices where name = @logical)
		begin
			raiserror(15026,-1,-1,@logical)
			return(1)
		end


	if exists (select * from sysdevices where phyname = isnull(@location,' o k'))
		begin
			raiserror(15030,-1,-1,@location)
			return(1)
		end

	/* Get the dbid. */
	if @dev_type = 'system'	/* Initial install, need to calculate one. */
		begin
			/* Get first available database number. */

                        select @dbid = min(dbid)+1
			from sysdatabases d1
			where dbid < 32767	/* Avoid arithmetic overflow if
						** dbid = max smallint exists. */
			and not exists
				(select * from sysdatabases d2
				where d2.dbid = d1.dbid+1)
		end
	else	/* Appending device frags. to existing db., get its dbid. */
		select @dbid = dbid from sysdatabases where name = @dbname


	dbcc getvalue('current_version')  --internal/system schema
	select @sysdb_version = @@error


	/* Get first available device number. */
	select @vdevno = null
	select @vdevno = (min(low)/0x01000000)+1
		from sysdevices d1
		where low/0x01000000 between 0 and 254
		and not exists
			(select * from sysdevices d2
				where d2.low/0x01000000 = (d1.low/0x01000000)+1)

	if @vdevno is null
		begin
			raiserror(15054,-1,-1)
			return(1)
		end

	/* Calculate first virtual page number for device. */
	select  @start = 0x01000000 * @vdevno

	/* Get the file size. */
	exec('dbcc devcontrol('''+@physical+''',filesize) with no_infomsgs')
	select @filesize = @@error
	if @filesize = 0 /* => file can't be opened. */
		begin
			raiserror(15055,-1,-1,@physical)
			return(1)
		end

	if @location is not null
		begin
			select @cmd = 'copy '+@physical+' '+@location
			select @cmd = 'xp_cmdshell '''+@cmd+''''
			exec (@cmd)
			if @@error <> 0
				begin
					print 'Couldn''t move device file'
					return(1)
				end
			select @physical = @location
		end

	begin tran

		if @dev_type = 'system'		-- Don't mark system device as 'read only'
			insert sysdevices
				(low,high,status,cntrltype,name,phyname,mirrorname)
				values
				(@start, @start+@filesize-1, 8194, 0, @logical, @physical, NULL)
		else	-- It must be a data fragment, so mark the device 'read only'
			insert sysdevices
				(low,high,status,cntrltype,name,phyname,mirrorname)
				values
				(@start, @start+@filesize-1,12290, 0, @logical, @physical, NULL)

    		if @@error <> 0
    			begin
				raiserror(15056,-1,-1,'sysdevices')
		    		goto failed
		    	end

                if @dev_type = 'system'	-- New db.
                        begin
        	               select @lstart = 0

                               insert into sysdatabases
			        (name,dbid,suid,mode,status,version,logptr,crdate,dumptrdate,category)
			        values
    		                (@dbname, @dbid, 1, 0, 512, @sysdb_version, 0, getdate(), getdate(), 0 )

    		               if @@error <> 0
    			                begin
    				                raiserror(15056,-1,-1,'sysdatabases')
		    		                goto failed
                                        end

                        end
                else	/* We're appending, so get the last fragment and
        	        ** go from there. */
                        select @lstart = lstart+size from sysusages
                	where dbid=@dbid
        		and lstart = (select max(lstart) from sysusages
        				where dbid=@dbid)

		/*
		** If it's the data device, assume that it's static.
		** Else, it is a system device and we must map the
		** system and log segments to  it.
		*/
		if @dev_type = 'data'
			select @segmap = 0	/* No allocations. */
		else
			/* It's the system device */
			select @segmap = 5	/* System + log */

		insert sysusages
			(dbid,segmap,lstart,size,vstart)
			values
			(@dbid, @segmap, @lstart, @size*512, @start )
    		if @@error <> 0
    			begin
    				raiserror(15056,-1,-1,'sysusages')
		    		goto failed
		    	end

		dbcc dbrepair (@dbname,remap) with no_infomsgs

		/* If we made it to here, we're okay. */

		goto succeeded

		failed:
			begin
				rollback tran
				return(1)
			end

		succeeded:

	commit tran

	print ''
	if @dev_type = 'system'
		begin
	                print 'System device installed.'
			print 'Use sp_dbinstall to install data device(s).'
		end
	else
		begin
			print 'Data device installed.'
			print 'Use sp_dbinstall to install additional data device(s).  Or, if installation is complete, use sp_dboption to bring the database online.'
		end

return(0)
go


dump transaction master with no_log
go



raiserror(15339,-1,-1,'sp_dbremove')
go
create procedure sp_dbremove
@dbname varchar(30) = null,
@dropdev varchar(10) = null
as

	declare @dbid int
	declare @devname varchar(30)
	declare @pmsg varchar(255)
	declare @physname varchar(255)

	declare @cmd1 varchar(255)
	declare @cmd2 varchar(255)
	declare @cmd3 varchar(255)

	if @dbname is null
		begin
			raiserror(15131,-1,-1)
			return(1)
		end

	if lower(@dropdev) <> 'dropdev' and @dropdev is not null
		begin
			raiserror(15131,-1,-1)
			return(1)
		end

	/* Check to see if database exists. */
	select @dbid = null
	select @dbid = dbid from sysdatabases where name=@dbname
	if @dbid is null
		begin
			raiserror(15010,-1,-1,@dbname)
			return(1)
		end

	/* Make sure no one is in the db. */
	if (select count(*) from sysprocesses where dbid = @dbid) > 0
		begin
			raiserror(15069,-1,-1)
			return (1)
		end

	if lower(@dropdev) = 'dropdev'
		begin
			print 'Dropping any devices used only by this database.'

			select @cmd1 = 'declare c1 cursor for
				select distinct d.name from sysdevices d,
					master.dbo.sysusages u
				where u.dbid = '+convert(varchar(5),@dbid)

			select @cmd2 = ' and u.segmap >= 0
 	  			and u.vstart between d.low and d.high
 	  			and d.status & 2 = 2	/* Physical devices only. */
 	  			and not exists
 	  				(select * from master.dbo.sysusages u2
 	  					where u2.dbid <> u.dbid'
 	  		select @cmd3 =			' and u2.vstart between d.low and d.high)'
			exec(@cmd1+@cmd2+@cmd3)

			open c1
			fetch c1 into @devname

			if @@fetch_status < 0
				begin
					print 'This database shares all of its devices with other databases.'
					print '-- no devices will be dropped.'
				end

			while @@fetch_status >= 0
				begin
					select @pmsg = 'Dropping device: '+@devname
					/*
					** Get the physical file name before
					** delete the row from sysdevices.
					*/
					select @physname = phyname
						from sysdevices
						where name = @devname

					/*
					** Release file handle for physical device.
					*/

					dbcc devcontrol(@devname,offline)
                                                if @@error = 0
                                                        begin
					                        select @pmsg = 'File: '''+@physname+''' closed.'
                        					print @pmsg
                                                        end

					delete from sysdevices where name = @devname

					fetch c1 into @devname
				end

			exec('deallocate c1')
		end

	update sysdatabases set status = 256 where dbid=@dbid
	dbcc dbrepair(@dbname,dropdb,noinit)
	print 'Database removed.'

	return(0)
go


raiserror(15339,-1,-1,'sp_devcreate')
go
create procedure sp_devcreate
@dbname varchar(30),
@logical varchar(30),
@physical varchar(255),
@size int
as

declare @retcode int,
	@vdevno int,
	@exec_str varchar(255),
	@size_in_blocks int

exec @retcode = sp_validname @logical
if @retcode <> 0
	return(1)

if @physical is null
	begin
		raiserror (15267,-1,-1,@logical)
		return(1)
	end

if @size is null
	begin
		raiserror (15268,-1,-1,@logical)
		return(1)
	end

if @size < 1
	begin
		raiserror (15262,-1,-1)
		return(1)
	end

/* Get next available device number for this segment. */
select @vdevno = null
select @vdevno = (min(low)/0x01000000)+1
	from sysdevices d1
	where low/0x01000000 between 0 and 254
		and not exists
			(select * from sysdevices d2
			where d2.low/0x01000000 =
				(d1.low/0x01000000)+1)

if @vdevno is null or @@error <> 0
	begin
		raiserror(15054,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @size_in_blocks = @size * 512.

disk init
	name = @logical,
	physname = @physical,
	size = @size_in_blocks,
	vdevno = @vdevno

if @@error <> 0
	begin
		raiserror(15263,-1,-1,'data')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @exec_str = 'alter database '+@dbname+' on '+@logical+
			' = '+convert(varchar(5),@size)
exec(@exec_str)

if @@error <> 0
	begin
		raiserror(15264,-1,-1,'data')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

/* Set sysusages.segmap to 'data' for data fragment. */
update sysusages set segmap = 2
	where vstart =
		(select low from sysdevices where name = @logical)

if @@error <> 0
	begin
		raiserror(15265,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

dbcc dbrepair (@dbname,remap) with no_infomsgs
go



raiserror(15339,-1,-1,'sp_create_removable')
go
create procedure sp_create_removable

@dbname		varchar(30) = null,	/* name of db */
@syslogical	varchar(30) = null,	/* logical name of system device */
@sysphysical	varchar(255) = null,	/* physical name of system device */
@syssize	int = null,		/* size of sys device in Meg. */
@loglogical	varchar(30) = null,	/* logical name of log device */
@logphysical	varchar(255) = null,	/* physical name of log device */
@logsize	int = null,		/* size of log device in Meg. */
@datalogical1	varchar(30) = null,	/* logical name of data device */
@dataphysical1	varchar(255) = null,	/* physical name of data device */
@datasize1	int = null,		/* size of data device in Meg. */
@datalogical2	varchar(30) = null,	/* logical name of data device */
@dataphysical2	varchar(255) = null,	/* physical name of data device */
@datasize2	int = null,		/* size of data device in Meg. */
@datalogical3	varchar(30) = null,	/* logical name of data device */
@dataphysical3	varchar(255) = null,	/* physical name of data device */
@datasize3	int = null,		/* size of data device in Meg. */
@datalogical4	varchar(30) = null,	/* logical name of data device */
@dataphysical4	varchar(255) = null,	/* physical name of data device */
@datasize4	int = null,		/* size of data device in Meg. */
@datalogical5	varchar(30) = null,	/* logical name of data device */
@dataphysical5	varchar(255) = null,	/* physical name of data device */
@datasize5	int = null,		/* size of data device in Meg. */
@datalogical6	varchar(30) = null,	/* logical name of data device */
@dataphysical6	varchar(255) = null,	/* physical name of data device */
@datasize6	int = null,		/* size of data device in Meg. */
@datalogical7	varchar(30) = null,	/* logical name of data device */
@dataphysical7	varchar(255) = null,	/* physical name of data device */
@datasize7	int = null,		/* size of data device in Meg. */
@datalogical8	varchar(30) = null,	/* logical name of data device */
@dataphysical8	varchar(255) = null,	/* physical name of data device */
@datasize8	int = null,		/* size of data device in Meg. */
@datalogical9	varchar(30) = null,	/* logical name of data device */
@dataphysical9	varchar(255) = null,	/* physical name of data device */
@datasize9	int = null,		/* size of data device in Meg. */
@datalogical10	varchar(30) = null,	/* logical name of data device */
@dataphysical10	varchar(255) = null,	/* physical name of data device */
@datasize10	int = null,		/* size of data device in Meg. */
@datalogical11	varchar(30) = null,	/* logical name of data device */
@dataphysical11	varchar(255) = null,	/* physical name of data device */
@datasize11	int = null,		/* size of data device in Meg. */
@datalogical12	varchar(30) = null,	/* logical name of data device */
@dataphysical12	varchar(255) = null,	/* physical name of data device */
@datasize12	int = null,		/* size of data device in Meg. */
@datalogical13	varchar(30) = null,	/* logical name of data device */
@dataphysical13	varchar(255) = null,	/* physical name of data device */
@datasize13	int = null,		/* size of data device in Meg. */
@datalogical14	varchar(30) = null,	/* logical name of data device */
@dataphysical14	varchar(255) = null,	/* physical name of data device */
@datasize14	int = null,		/* size of data device in Meg. */
@datalogical15	varchar(30) = null,	/* logical name of data device */
@dataphysical15	varchar(255) = null,	/* physical name of data device */
@datasize15	int = null,		/* size of data device in Meg. */
@datalogical16	varchar(30) = null,	/* logical name of data device */
@dataphysical16 varchar(255) = null,	/* physical name of data device */
@datasize16	int = null		/* size of data device in Meg. */
	
as

declare @vdevno int,
	@size_in_blocks int,
	@retcode int,
	@exec_str varchar(255),
	@numdevs int

if suser_id() <> 1	-- Make sure that it's the SA executing this.
	begin
		raiserror(15003,-1,-1)
		return(1)	
	end

if @dbname is null
	or @syslogical is null
	or @sysphysical is null
	or @syssize is null
	or @loglogical is null
	or @logphysical is null
	or @logsize is null
	or @datalogical1 is null
	or @dataphysical1 is null
	or @datasize1 is null
		begin
			raiserror (15261,-1,-1)
			return (1)
		end

if exists (select * from sysdatabases where name = @dbname)
	begin
		raiserror(15032,-1,-1,@dbname)
		return(1)
	end

/* Check to verify that valid sizes were supplied for required devices. */
if @syssize < 1 or @logsize < 1 or @datasize1 < 1
	begin
		raiserror (15262,-1,-1)
		return(1)
	end

/* Check to see if a valid database name was supplied. */
exec @retcode = sp_validname @dbname
if @retcode <> 0
	return(1)

/* valid syslogical? */
exec @retcode = sp_validname @syslogical
if @retcode <> 0
	return(1)

/* valid loglogical? */
exec @retcode = sp_validname @loglogical
if @retcode <> 0
	return(1)

/* valid datalogical1? */
exec @retcode = sp_validname @datalogical1
if @retcode <> 0
	return(1)

/* Create the necessary devices. */

/* Get first available device number for the system device. */
select @vdevno = null
select @vdevno = (min(low)/0x01000000)+1
	from sysdevices d1
	where low/0x01000000 between 0 and 254
		and not exists
			(select * from sysdevices d2
			where d2.low/0x01000000 = (d1.low/0x01000000)+1)

if @vdevno is null or @@error <> 0
	begin
		raiserror(15054,-1,-1)
		return(1)
	end

select @size_in_blocks = @syssize * 512.

disk init
	name = @syslogical,
	physname = @sysphysical,
	size = @size_in_blocks,
	vdevno = @vdevno

if @@error <> 0
	begin
		raiserror(15263,-1,-1,'system')
		return(1)
	end

/* Create the database's system device segment. */
select @exec_str = 'create database '+ @dbname+' on '+@syslogical+
		' = '+convert(varchar(5),@syssize)
exec(@exec_str)

if @@error <> 0
	begin
		raiserror(15264,-1,-1,'system')
		return(1)
	end

/* Get next available device number for the first data segment. */
select @vdevno = null
select @vdevno = (min(low)/0x01000000)+1
	from sysdevices d1
	where low/0x01000000 between 0 and 254
		and not exists
			(select * from sysdevices d2
			where d2.low/0x01000000 = (d1.low/0x01000000)+1)

if @vdevno is null or @@error <> 0
	begin
		raiserror(15054,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @size_in_blocks = @datasize1 * 512.

disk init
	name = @datalogical1,
	physname = @dataphysical1,
	size = @size_in_blocks,
	vdevno = @vdevno

if @@error <> 0
	begin
		raiserror(15263,-1,-1,'data')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @exec_str = 'alter database '+@dbname+' on '+@datalogical1+
			' = '+convert(varchar(5),@datasize1)
exec(@exec_str)

if @@error <> 0
	begin
		raiserror(15264,-1,-1,'data')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

/* Set sysusages.segmap to 'data only' for data fragment. */
update sysusages set segmap = 2
	where vstart =
		(select low from sysdevices where name = @datalogical1)

if @@error <> 0
	begin
		raiserror(15265,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

dbcc dbrepair (@dbname,remap) with no_infomsgs

/* Check out optional data devices. */

if @datalogical2 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical2,@dataphysical2,@datasize2
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical2)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = 2
	end
else goto no_more_devs

if @datalogical3 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical3,@dataphysical3,@datasize3
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical3)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical4 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical4,@dataphysical4,@datasize4
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical4)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical5 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical5,@dataphysical5,@datasize5
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical5)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical6 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical6,@dataphysical6,@datasize6
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical6)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical7 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical7,@dataphysical7,@datasize7
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical7)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical8 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical8,@dataphysical8,@datasize8
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical8)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical9 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical9,@dataphysical9,@datasize9
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical9)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical10 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical10,@dataphysical10,@datasize10
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical10)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical11 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical11,@dataphysical11,@datasize11
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical11)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical12 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical12,@dataphysical12,@datasize12
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical12)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical13 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical13,@dataphysical13,@datasize13
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical13)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical14 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical14,@dataphysical14,@datasize14
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical14)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical15 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical15,@dataphysical15,@datasize15
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical15)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end
else goto no_more_devs

if @datalogical16 is not null
	begin
		exec @retcode = sp_devcreate @dbname,@datalogical16,@dataphysical16,@datasize16
		if @retcode <> 0
			begin
				raiserror(15269,-1,-1,@datalogical16)
				exec sp_dbremove @dbname,dropdev
				return(1)
			end
		select @numdevs = @numdevs + 1
	end

no_more_devs:

/* Get next available device number for log segment. */
select @vdevno = null
select @vdevno = (min(low)/0x01000000)+1
	from sysdevices d1
	where low/0x01000000 between 0 and 254
		and not exists
			(select * from sysdevices d2
			where d2.low/0x01000000 = (d1.low/0x01000000)+1)

if @vdevno is null or @@error <> 0
	begin
		raiserror(15054,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @size_in_blocks = @logsize * 512.

disk init
	name = @loglogical,
	physname = @logphysical,
	size = @size_in_blocks,
	vdevno = @vdevno

if @@error <> 0
	begin
		raiserror(15263,-1,-1,'log')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

select @exec_str = 'alter database '+@dbname+' on '+@loglogical+
			' = '+convert(varchar(5),@logsize)
exec(@exec_str)

if @@error <> 0
	begin
		raiserror(15264,-1,-1,'log')
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

/* Set sysusages.segmap to 'log' for log fragment. */
update sysusages set segmap = 4
	where vstart =
		(select low from sysdevices where name = @loglogical)

if @@error <> 0
	begin
		raiserror(15265,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

dbcc dbrepair (@dbname,remap) with no_infomsgs

/* Set sysusages.segmap to 'system' for system fragment. */
update sysusages set segmap = 1
	where vstart =
		(select low from sysdevices where name = @syslogical)

if @@error <> 0
	begin
		raiserror(15265,-1,-1)
		exec sp_dbremove @dbname,dropdev
		return(1)
	end

dbcc dbrepair (@dbname,remap) with no_infomsgs

return(0)

go


raiserror(15339,-1,-1,'sp_defaultdb')
go
create procedure sp_defaultdb
@loginame varchar(30),			/* login name of the user */
@defdb varchar(30) 			/* default db for the user */
as

declare @suid int		/* the suid to use to qualify the change */

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

/*
**  Check that the account exists.
*/
if not exists (select * from syslogins where name = @loginame)
	begin
		raiserror(15007,-1,-1,@loginame)
		return (1)
	end

/*
**  Check that the database name is valid.
*/
if not exists (select * from sysdatabases where name = @defdb)
	begin
		raiserror(15010,-1,-1,@defdb)
		return (1)
	end

/*
**  Both the owner of the account (@loginame) and the SA can run this
**  command.  If the SA is running it, set @suid to the suid of @loginame.
*/
select @suid = suser_id()
if @suid = 1
	begin
		/*
		**  Get the suid for @loginame.  We know it exists because we
		**  checked above.
		*/
		select @suid = suid from syslogins where name = @loginame
	end

/*
**  Change the database
*/
update syslogins set dbname = @defdb
	where suid = @suid
	and name = @loginame

/*
**  If nothing got updated then it means that the the user tried to change
**  someone else's default.
*/
if @@rowcount < 1
	begin
		raiserror(15132,-1,-1)
		return (1)
	end

print 'Default database changed.'

return (0)
go


raiserror(15339,-1,-1,'sp_depends')
go
create procedure sp_depends  --1996/03/15 12:51
@objname varchar(92)		/* the object we want to check */
as

declare @objid int			/* the id of the object we want */
declare @found_some bit			/* flag for dependencies found */
declare @dbname varchar(30)

/*
**  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.
*/
select @objid = object_id(@objname), @dbname=db_name()
if @objid is null
	begin
		raiserror(15009,-1,-1,@objname,@dbname)
		return (1)
	end

/*
**  Initialize @found_some to indicate that we haven't seen any dependencies.
*/
select @found_some = 0

set nocount on

/*
**  Print out the particulars about the local dependencies.
*/
if exists (select *
		from sysdepends
			where id = @objid)
begin
	print 'In the current database the specified object references the following:'
	select		 'name' = substring((s6.name + '.' + o1.name), 1, 40),
			 type = substring(v2.name, 1, 16),
			 updated = substring(u4.name, 1, 7),
			 selected = substring(w5.name, 1, 8)
		from	 sysobjects		o1
			,master.dbo.spt_values	v2
			,sysdepends		d3
			,master.dbo.spt_values	u4
			,master.dbo.spt_values	w5 --11667
			,sysusers		s6
		where	 o1.id = d3.depid
		and	 o1.sysstat & 0xf = v2.number and v2.type = 'O'
		and	 u4.type = 'B' and u4.number = d3.resultobj
		and	 w5.type = 'B' and w5.number = d3.readobj|d3.selall
		and	 d3.id = @objid
		and	 o1.uid = s6.uid

	select @found_some = 1
end

/*
**  Now check for things that depend on the object.
*/
if exists (select *
		from sysdepends
			where depid = @objid)
begin
	print 'In the current database the specified object is referenced by the following:'
	select distinct 'name' = substring((s.name + '.' + o.name), 1, 40),
		type = substring(v.name, 1, 16)
			from sysobjects o, master.dbo.spt_values v, sysdepends d,
				sysusers s
			where o.id = d.id
				and o.sysstat & 0xf = v.number and v.type = 'O'
				and d.depid = @objid
				and o.uid = s.uid
	select @found_some = 1
end

/*
**  Did we find anything in sysdepends?
*/
if @found_some = 0
	print 'Object doesn''t reference any object and no objects reference it.'

set nocount off

return (0)
go


raiserror(15339,-1,-1,'sp_diskdefault')
go
create procedure sp_diskdefault
@logicalname	varchar(30),		/* logical name of the device */
@defstatus	varchar(15)		/* turn on or off */
as

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

/*
**  Only the SA can run this sproc.
*/
if suser_id() <> 1
	begin
		raiserror(15003,-1,-1)
		return (1)
	end

/*
**  Make sure that a device with @logicalname exists.
*/
if not exists (select * from sysdevices where name = @logicalname)
	begin
		raiserror(15012,-1,-1,@logicalname)
		return (1)
	end

/*
**  Make sure that it is a database disk and not a dump device.
*/
if exists (select * from sysdevices
		where name = @logicalname
			and status & 16 = 16)
	begin
		raiserror(15035,-1,-1,@logicalname)
		return (1)
	end

/*
**  Make sure that the database disk is NOT a RAM device.
*/
if exists (select *
		from sysdevices
		where name = @logicalname
			and status & 2048 = 2048 )
	begin
		raiserror(15139,-1,-1)
		return (1)
	end

if @defstatus = 'defaulton'
	begin
		update sysdevices set status = status | 1
			where name = @logicalname
		return (0)
	end

if @defstatus = 'defaultoff'
	begin
		update sysdevices set status = status & ~1
			where name = @logicalname
		return (0)
	end

/*
**  @defstatus must be 'defaulton' or 'defaultoff'
*/
raiserror(15140,-1,-1)

return (1)
go

dump transaction master with no_log
go


raiserror(15339,-1,-1,'sp_dropalias')
go
create procedure sp_dropalias
@loginame varchar(30)		/* account name of the user with the alias */
as

/*
**  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 make sure that the @loginame has an account.
*/
if (select suser_id(@loginame)) is null
begin
	raiserror(15007,-1,-1,@loginame)
	return (1)
end

/*
**  Delete the alias, if any, from sysalternates.
*/
delete from sysalternates
	where suid = suser_id(@loginame)

/*
**  If nothing happened (rowcount = 0), there was no alias.
*/
if @@rowcount > 0
	begin
		print 'Alias user dropped.'
		return (0)
	end
else
	begin
		raiserror(15134,-1,-1)
		return (1)
	end
go


raiserror(15339,-1,-1,'sp_dropdevice')
go
create procedure sp_dropdevice
@logicalname	varchar(30),		-- logical name of the device
@delfile	varchar(7) = null	-- optional param. to delete disk file
as

declare @physname varchar(255)
declare @ctrltype smallint
declare @msg varchar(255)
declare @cmd varchar(255)

/*
** See if user specified something for @delfile and, if so, validate it.
*/
if @delfile is not null
	begin
		select @delfile = lower(@delfile)

		if @delfile <> 'delfile'
			begin
				raiserror(15216,-1,-1,@delfile)
				return(1)
			end
	end

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

/*
**  Only the system administrator (SA) can run this command.
**  Check to make sure the executor is the sa.
*/
if suser_id() <> 1
	begin
		raiserror(15003,-1,-1)
		return (1)
	end

/*
**  Check and make sure that the device actually exists.
*/
if not exists (select * from sysdevices where name = @logicalname)
	begin
		raiserror(15012,-1,-1,@logicalname)
		return (1)
	end

/*
**  Check and make sure that no database is using the device.
**  If so, print out who is using it and exit.
*/
if exists (select *
	from sysdatabases s, sysusages u, sysdevices d,
		master.dbo.spt_values p
	where s.dbid = u.dbid
		and u.segmap >= 0
		and d.low <= u.size + u.vstart
		and d.high >= u.size + u.vstart - 1
		and d.status & 2 = 2
		and p.type = 'S'
		and d.name = @logicalname)
begin
	raiserror(15141,-1,-1)

	select distinct 'Device used by database(s):' = s.name
		from sysdatabases s, sysusages u, sysdevices d,
			master.dbo.spt_values p
		where s.dbid = u.dbid
			and u.segmap >= 0
			and d.low <= u.size + u.vstart
			and d.high >= u.size + u.vstart - 1
			and d.status & 2 = 2
			and p.type = 'S'
			and p.number >= 0
			and d.name = @logicalname
	order by s.name

	return (1)
end

select @physname = phyname,@ctrltype = cntrltype
		from sysdevices
		where name = @logicalname

if @ctrltype <> 6	-- Can't release file handle for 'pipe' device.
	begin
		/*
		** Release file handle for physical devices.
		*/
		dbcc devcontrol(@logicalname,offline)

		if @@error in (0,5154)	-- 5154 => Device is not open.
			begin
				select @msg = 'File: '''+@physname+''' closed.'
				print @msg

				/*
				** Drop the device.
				*/
				delete from sysdevices
					where name = @logicalname
				print 'Device dropped.'

				if @delfile = 'delfile'
					begin
						select @cmd = 'del '+@physname
						select @cmd = 'xp_cmdshell '''+@cmd+''''
						exec (@cmd)

						/* See if the delete was successful. */
						exec('dbcc devcontrol(''' +
							@physname +
							''',filesize) with no_infomsgs')
						if @@error <> 0 /* => file can't be opened. */
							begin
								print 'Couldn''t delete device file'
								return(1)
							end
						else
							print 'Physical file deleted.'
					end
			end
		else return(1)
	end

return (0)
go


raiserror(15339,-1,-1,'sp_dropextendedproc')
go
create procedure sp_dropextendedproc
@functname varchar(62) -- name of function  (30-->62 1996/01/31)
as
/*
**  If we're in a transaction, disallow the dropping of the
**  extended stored procedure.
*/
if @@trancount > 0
	begin
		raiserror(15002,-1,-1,'sp_dropextendedproc')
		return (1)
	end

/*
** Drop the extended procedure mapping.
*/
dbcc dropextendedproc( @functname )
return (0)
go


raiserror(15339,-1,-1,'sp_dropgroup')
go
create procedure sp_dropgroup
@grpname varchar(30)		/* group to be dropped */
as

declare @gid int		/* group id of the group to be dropped */

/*
**  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 group exists.
**  User ids are <= 16383 and group ids are > 16383.
*/
select @gid = (select uid
	from sysusers
		where name = @grpname
			and (uid > 16383 or uid = 0))

if @gid is null
	begin
		raiserror(15014,-1,-1,@grpname)
		return (1)
	end

/*
**  Can't drop the group public.
*/
if @gid = 0
	begin
		raiserror(15142,-1,-1)
		return (1)
	end

/*
**  Check to see that nobody is in the group.  If so, return.
*/
if (select count(*) from sysusers where gid = @gid and uid <= 16383) <> 0
	begin
		raiserror(15144,-1,-1)

		/*
		**  Show who is in the group.
		*/
		select name from sysusers
			where gid = @gid
			and uid <= 16383

		return (1)
	end

/*
**  Drop the group.
**  Also drop any references to the group in the sysprotects table.
*/
begin transaction

	delete from sysusers
		where uid = @gid

	delete from sysprotects
		where uid = @gid

commit transaction

print 'Group has been dropped.'

return (0)
go


raiserror(15339,-1,-1,'sp_dropkey')
go
create procedure sp_dropkey
@keytype varchar(10), 			/* type of key to drop */
@tabname varchar(92),			/* table with the key */
@deptabname varchar(92) = null		/* dependent table */
as

declare @id int				/* id of @tabname */
declare @uid smallint			/* owner of @tabname */
declare @depid int			/* id of related table */
declare @depuid smallint		/* owner of @related table */
declare @dbname varchar(30)

/*
**  First make sure that the key type is ok.
*/
if lower(@keytype) not in ('primary', 'foreign', 'common')
	begin
		raiserror(15145,-1,-1)
		return (1)
	end

/*
**  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 @deptabname like '%.%.%'
	and substring(@deptabname, 1, charindex('.', @deptabname) - 1) <> db_name()
	begin
		raiserror(15078,-1,-1)
		return (1)
	end

/*
**  Get the ids of the @tabname and @deptabname.
*/
select @id = id, @depid = object_id(@deptabname), @uid = uid
		from sysobjects
			where id = object_id(@tabname)
if @id is null
	begin
		select @dbname = db_name()
		raiserror(15009,-1,-1,@tabname,@dbname)
		return (1)
	end

if @uid <> user_id()
	begin
		raiserror(15146,-1,-1)
		return (1)
	end

/*
**  If primary key, just drop it.
*/
if lower(@keytype) = 'primary'
	begin
		delete from syskeys where id = @id and type = 1

		if @@rowcount = 0
			begin
				raiserror(15147,-1,-1)
				return (1)
			end

		else
			print 'Primary key for the table or view dropped.'

		/*
		**  Check to see if there are any foreign keys dependent on the
		**  primary key.  If so -- drop them.
		*/
		delete from syskeys where depid = @id and type = 2

		if @@rowcount <> 0
			print 'Dependent foreign keys were also dropped.'

		return (0)
	end

/*
**  It's either a foreign or common key so we need to verify the
**  existence of the @deptabname.
*/
if @depid is null
	begin
		/*
		**  Was the @deptabname supplied?
		*/
		if @deptabname is null
			begin
				raiserror(15148,-1,-1)
				return (1)
			end

		/*
		**  It was supplied but it doesn't exist.
		*/
		raiserror(15081,-1,-1)
		return (1)
	end


/*
**  If foreign key, get rid of it.
*/
if lower(@keytype) = 'foreign'
	begin
		/*
		**  Get rid of the foreign key entry.
		*/
		delete from syskeys
			where type = 2
			and id = @id
			and depid = @depid

		if @@rowcount = 0
			begin
				raiserror(15149,-1,-1)
				return (1)
			end

		print 'Foreign key dropped.'

		return (0)
	end

/*
**  Key type must be common so just get rid of the common keys
**  with the right ids and depids.  Since whenever a common key is defined
**  it is added to both of the tables involved, we'll get rid of both of
**  those entries.
*/
delete from syskeys
	where type = 3
		and id = @id
		and depid = @depid

if @@rowcount = 0
	begin
		raiserror(15150,-1,-1)
		return (1)
	end

/*
**  Now get rid of the inverse common key entries.
*/
delete from syskeys
	where type = 3
		and id = @depid
		and depid = @id

print 'Common keys dropped.'

return (0)
go


raiserror(15339,-1,-1,'sp_droplogin')
go
create procedure sp_droplogin -- 1995/10/24 18:21

@loginame sysname		-- name of login to drop
as

set nocount on

declare @login_suid  smallint
       ,@char_login_suid  varchar(6)
declare @username sysname
declare @dbname	sysname

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

/*
**  Only the system administrator (SA) can run this command.
**  Check to make sure the executor is the sa.
*/
if suser_id() <> 1
	begin
		raiserror(15003,-1,-1)
		return (1)
	end

/*
**  If login exists, capture the corresponding suid.
*/
select @login_suid = min(suid)
   from master..syslogins
   where name = @loginame

if @login_suid is null
   begin
   raiserror(15007,10,-1,@loginame)
   return(1)
   end

select @char_login_suid = convert(varchar,@login_suid)

/*
**  This work table will hold all problems found.
*/
