DatabaseProcApplicationCreatedLinks
sybsystemprocssp_dropuser  14 déc. 14Defects Propagation Dependencies

1     
2     /* 
3     ** IMPORTANT: Please read the following instructions before
4     **   making changes to this stored procedure.
5     **
6     **	To make this stored procedure compatible with High Availability (HA),
7     **	changes to certain system tables must be propagated 
8     **	to the companion server under some conditions.
9     **	The tables include (but are not limited to):
10    **		syslogins, sysservers, sysattributes, systimeranges,
11    **		sysresourcelimits, sysalternates, sysdatabases,
12    **		syslanguages, sysremotelogins, sysloginroles,
13    **		sysalternates (master DB only), systypes (master DB only),
14    **		sysusers (master DB only), sysprotects (master DB only)
15    **	please refer to the HA documentation for detail.
16    **
17    **	Here is what you need to do: 
18    **	For each insert/update/delete statement, add three sections to
19    **	-- start HA transaction prior to the statement
20    **	-- add the statement
21    **	-- add HA synchronization code to propagate the change to the companion
22    **
23    **	For example, if you are adding 
24    **		insert master.dbo.syslogins ......
25    **	the code should look like:
26    **	1. Before that SQL statement:
27    **		
28    **	2. Now, the SQL statement:
29    **		insert master.dbo.syslogins ......
30    **	3. Add a HA synchronization section right after the SQL statement:
31    **		
32    **
33    **	You may need to do similar change for each built-in function you
34    **	want to add.
35    **
36    **	After that, you need to add a separate part at a place where it can not
37    **	be reached by the normal execution path:
38    **	clean_all:
39    **		
40    **		return (1)
41    */
42    
43    create or replace procedure sp_dropuser
44        @name_in_db varchar(255) /* user name to drop */
45    as
46    
47        declare @suid int /* suid of the user */
48        declare @uid int /* uid of the user */
49        declare @objectcount int /* count of objects user owns */
50        declare @predcount int /* count of predicates user owns */
51        declare @typecount int /* count of types user owns */
52        declare @grantcount int /* count of grants user made */
53        declare @userdropped int /* flag to indicate user was dropped */
54        declare @threshcount int /* count of thresholds bound by user */
55        declare @spexebndcount int /* cnt of user owned sp exe bindings */
56        declare @sp_name varchar(255) /* name of stored proc */
57        declare @msg varchar(1024)
58        declare @msg_all varchar(30) /* msg for "all" equivalent */
59        declare @msg_true varchar(30) /* msg for "true" equivalent */
60        declare @msg_false varchar(30) /* msg for "false" equivalent */
61        declare @dummy int
62        declare @dbname varchar(255)
63        declare @tempdb_mask int /* All database status bit for a tempdb */
64        declare @isatempdb int /* is database a temporary database */
65        declare @err1 int /* temp. variable to store @@error */
66    
67        declare @HA_CERTIFIED tinyint /* Is the SP HA certified ? */
68        declare @retstat int
69        declare @status1 int
70        declare @status2 int
71        declare @nullarg char(1)
72        declare @gp_enabled int /* granular permissions enabled? */
73        declare @nopriverr int
74        declare @uwp varchar(16384)
75    
76    
77    
78        select @status1 = 1
79        select @status2 = 1
80        select @nopriverr = 0
81    
82        select @HA_CERTIFIED = 0
83    
84    
85    
86        /* check to see if we are using HA specific SP for a HA enabled server */
87        exec @retstat = sp_ha_check_certified 'sp_dropuser', @HA_CERTIFIED
88        if (@retstat != 0)
89            return (1)
90    
91        if @@trancount = 0
92        begin
93            set chained off
94        end
95    
96        set transaction isolation level 1
97    
98    
99        /*
100       **  Only the Database Owner (DBO) or
101       **  Accounts with SA or SSO role can execute it.
102       **  If the user has SA role, it's uid will
103       **  be DBO uid (1). If granular permissions is enabled then
104       **  users with 'manage any user' permission can execute it.
105       */
106       select @dbname = db_name()
107       select @nullarg = NULL
108       execute @status1 = sp_aux_checkroleperm "sso_role",
109           "manage any user", @dbname, @gp_enabled output
110   
111       if (@status1 != 0)
112       begin
113           if (@gp_enabled = 0)
114           begin
115               if (user_id() != 1)
116               begin
117                   execute @status2 = sp_aux_checkroleperm "sa_role",
118                       @nullarg, @nullarg, @gp_enabled output
119                   if (@status2 != 0)
120                   begin
121                       /* 
122                       ** proc_role() will raise permission errors
123                       ** and send audit records to the audit trail.
124                       */
125                       select @dummy = proc_role("sa_role")
126                       select @dummy = proc_role("sso_role")
127                       return (1)
128                   end
129               end
130           end
131           else
132           begin
133               /* 
134               ** Call proc_auditperm here to do auditing and error 
135               ** message. 
136               */
137               select @dummy = proc_auditperm("manage any user",
138                       @status1, @dbname)
139               return (1)
140           end
141       end
142   
143       /* 
144       ** Send apropriate audit records, already determined user has one
145       ** of the roles or the permission. 
146       */
147       if (@gp_enabled = 0)
148       begin
149           if (@status1 = 0)
150               select @dummy = proc_role("sso_role")
151           if (@status2 = 0)
152               select @dummy = proc_role("sa_role")
153       end
154       else
155       begin
156           select @dummy = proc_auditperm("manage any user",
157                   @status1, @dbname)
158       end
159       /*
160       ** Disallow dropping the usedb_user user. This user must always
161       ** be available for users entering the database because they have
162       ** USE DATABASE permission.
163       */
164       if (@name_in_db = "usedb_user")
165       begin
166           /*
167           ** 17543, "You cannot drop the '%1!'."
168           */
169           raiserror 17543, @name_in_db
170           return (1)
171       end
172       /*
173       **  See if the user exists in the database.
174       */
175       select @uid = uid, @suid = suid from sysusers
176       where name = @name_in_db and
177           ((uid < @@mingroupid and uid != 0) or (uid > @@maxgroupid))
178   
179       /*
180       **  No such user so return.
181       */
182       if @uid is NULL
183       begin
184           /*
185           ** 17232, "No user with the specified name exists in the current database."
186           */
187           raiserror 17232
188           return (1)
189       end
190   
191   
192   
193   out_of_HA_checking:
194   
195       /*
196       **  Big trouble if dbo (uid = 1) is dropped so check.
197       */
198       if @uid = 1
199       begin
200           /*
201           ** 17543, "You cannot drop the '%1!'."
202           */
203           raiserror 17543, "database owner"
204           return (1)
205       end
206   
207       /*
208       ** Check to see if we are dealing with a temporary database.
209       */
210       select @tempdb_mask = number
211       from master.dbo.spt_values
212       where type = "D3" and name = "TEMPDB STATUS MASK"
213   
214       if (db_id() = 2) or exists (select * from master..sysdatabases
215               where dbid = db_id()
216                   and (status3 & @tempdb_mask) != 0)
217       begin
218           select @isatempdb = 1
219       end
220   
221       /*
222       **  Trouble if guest gets dropped from master or tempdb, so check.
223       */
224       if (@name_in_db = "guest" and (db_id() = 1 or @isatempdb = 1))
225       begin
226           /*
227           ** 17544, "You cannot drop the 'guest' user from master or tempdb."
228           */
229           raiserror 17544
230           return (1)
231       end
232   
233       /*
234       **  If the user owns any objects or datatypes and we're not
235       **  forcing the drop, return without doing anything.
236       */
237       select @objectcount = count(*)
238       from sysobjects
239       where uid = @uid
240       select @predcount = count(*)
241       from sysobjects
242       where uid = @uid and type = 'RP'
243       select @typecount = count(*)
244       from systypes
245       where uid = @uid
246       select @grantcount = count(*)
247       from sysprotects
248       where grantor = @uid
249           and id not in (select id from sysobjects
250               where uid = @uid)
251       select @threshcount = count(*)
252       from systhresholds
253       where suid = @suid
254   
255       select @spexebndcount = count(*)
256       from sysattributes
257       where (class = 6 and object_type = 'PR' and object_info1 = @uid)
258   
259       if @objectcount > 0 or @typecount > 0 or @grantcount > 0 or @threshcount > 0 or
260           @spexebndcount > 0
261       begin
262           if ((@objectcount > 0) and (@objectcount > @predcount))
263           begin
264               /*
265               ** 17545, "You cannot drop user because user '%1!' owns objects in database."
266               */
267               raiserror 17545, @name_in_db
268               select name, type
269               from sysobjects
270               where uid = @uid and type != 'RP'
271           end
272   
273           if @typecount > 0
274           begin
275               /*
276               ** 17546, "You cannot drop user because user '%1!' owns types in database."
277               */
278               raiserror 17546, @name_in_db
279               select user_type = a.name, physical_type = b.name
280               from systypes a, systypes b
281               where a.uid = @uid
282                   and a.type = b.type
283                   and b.usertype < 100
284           end
285   
286           if @grantcount > 0
287           begin --{
288   
289               /*
290               ** 17431, "true"
291               ** 17432, "false"
292               */
293               exec sp_getmessage 17431, @msg_true output
294               exec sp_getmessage 17432, @msg_false output
295               /* 17673, "All" */
296               exec sp_getmessage 17673, @msg_all out
297   
298               /* create and populate temp tables so that we can map 
299               ** column bit map to names 
300               */
301               create table #sysprotects1(id int, uid int,
302                   action smallint,
303                   protecttype tinyint,
304                   grantor int, number int)
305   
306               create table #sysprotects2(id int, col_count smallint)
307               create table #sysprotects3(grantee sysname(30),
308                   object longsysname null,
309                   column varchar(10) null,
310                   privilege varchar(28))
311   
312               insert into #sysprotects2(id, col_count)
313               select id, count(*)
314               from syscolumns
315               group by id
316   
317               insert into #sysprotects1(id, uid, action, protecttype,
318                   grantor, number)
319               select distinct
320                   p.id, p.uid, p.action, p.protecttype,
321                   p.grantor, c.number
322               from sysprotects p, master.dbo.spt_values c
323               where (~ isnull(convert(tinyint, substring(p.columns, c.low, 1)), 0) & c.high != 0
324                       and c.number <= (select col_count from #sysprotects2 where id = p.id))
325                   and c.type = "P"
326                   and c.number <= 1024
327                   and p.columns is not null
328                   and convert(tinyint, substring(p.columns, 1, 1)) & 0x1 != 0
329                   and (convert(tinyint, substring(p.columns, 1, 1)) & 0xfe != 0
330                       or substring(p.columns, 2, 1) is not null)
331   
332               insert into #sysprotects1(id, uid, action, protecttype,
333                   grantor, number)
334               select distinct
335                   p.id, p.uid, p.action, p.protecttype,
336                   p.grantor, c.number
337               from sysprotects p, master.dbo.spt_values c
338               where convert(tinyint, substring(isnull(p.columns, 0x1), c.low, 1))
339                   & c.high != 0
340                   and c.type = "P"
341                   and c.number <= 1024
342                   and (p.columns is null
343                       or convert(tinyint, substring(p.columns, 1, 1)) & 0x1 = 0
344                       or (convert(tinyint, substring(p.columns, 1, 1)) & 0xfe = 0
345                           and substring(p.columns, 2, 1) is null))
346   
347               /* Set nocount on to avoid intermingling of output */
348               set nocount on
349   
350               /*
351               ** 17549, "You cannot drop user because user '%1!' owns 
352               ** grantable privileges and granted them to other users.  The 
353               ** user has granted the following privileges:"
354               */
355               raiserror 17549, @name_in_db
356               print " "
357   
358               /*
359               ** Look for permissions that have objects associated 
360               ** with them.
361               */
362               if exists (select 1 from #sysprotects1 p, sysobjects o
363                       where p.id = o.id and p.grantor = @uid)
364               begin
365                   insert #sysprotects3(grantee, object, column, privilege)
366                   select grantee = u.name,
367                       object = o.name,
368                       column = substring(isnull(col_name(p.id,
369                                   p.number), @msg_all), 1, 10),
370                       privilege = s.name
371                   from sysusers u, sysobjects o, #sysprotects1 p,
372                       master.dbo.spt_values s
373                   where p.grantor = @uid and p.uid = u.uid
374                       and p.protecttype < 2
375                       and p.action not in
376                       (6, 76, 88, 122, 125, 128, 143, 148)
377                       and p.id = o.id
378                       and s.number = p.action
379                       and s.name is not NULL
380                       and (s.type = 'T' or s.type = 'GP')
381               end
382               /*
383               ** Look for permissions that have databases associated 
384               ** with them.
385               */
386               if exists (select 1 from #sysprotects1 p,
387                           master.dbo.sysdatabases d
388                       where p.id = d.dbid and p.grantor = @uid)
389               begin
390                   /* actions with dbname only apply to the master database */
391                   if (db_name() = 'master')
392                   begin
393                       insert #sysprotects3(grantee, object, column, privilege)
394                       select grantee = u.name,
395                           object = d.name,
396                           column = substring(isnull(col_name(p.id,
397                                       p.number), @msg_all), 1, 10),
398                           privilege = s.name
399                       from sysusers u, master.dbo.sysdatabases d,
400                           #sysprotects1 p, master.dbo.spt_values s
401                       where p.grantor = @uid and p.uid = u.uid
402                           and p.protecttype < 2
403                           and p.id = d.dbid
404                           and p.action in
405                           (6, 76, 88, 122, 125, 128, 143,
406                               148)
407                           and s.number = p.action
408                           and s.name is not NULL
409                           and (s.type = 'T' or s.type = 'GP')
410                   end
411               end
412   
413               /*
414               ** Look for permissions that don't have objects associated 
415               ** with them.
416               */
417               if exists (select 1 from #sysprotects1 p, sysusers u
418                       where
419                           p.grantor = @uid
420                           and p.id = 0
421                       )
422               begin
423                   insert #sysprotects3(grantee, privilege)
424                   select grantee = u.name,
425                       privilege = s.name
426                   from #sysprotects1 p, sysusers u,
427                       master.dbo.spt_values s
428                   where
429                       p.grantor = @uid
430                       and p.uid = u.uid
431                       and p.id = 0
432                       and p.protecttype < 2
433                       and s.number = p.action
434                       and s.name is not NULL
435                       and (s.type = 'T' or s.type = 'GP')
436               end
437               exec sp_autoformat @fulltabname = #sysprotects3,
438                   @selectlist = "grantee, object, column, privilege",
439                   @orderby = "order by grantee, object, privilege"
440   
441               /*
442               ** 18053, "User '%1!' was granted grantable privileges by the
443               **         following users:"
444               */
445               exec sp_getmessage 18053, @msg output
446               print " "
447               print @msg, @name_in_db
448   
449               select distinct grantor = u.name
450               from sysusers u, sysprotects p
451               where p.uid = @uid and u.uid = p.grantor and p.protecttype = 0
452   
453               union
454   
455               /* for non-object level grants */
456               select distinct grantor = u.name
457               from sysusers u, sysprotects p
458               where p.uid = @uid and u.uid = p.grantor and p.protecttype = 1
459                   and p.id = 0
460               order by grantor
461           end --}
462   
463           if @threshcount > 0
464           begin
465               /*
466               ** 18033, "You cannot drop user because user '%1!' owns thresholds in database."
467               */
468               raiserror 18033, @name_in_db
469               select "Segment name" = g.name, "Free pages" = t.free_space
470               from syssegments g, systhresholds t
471               where t.suid = @suid
472                   and t.segment = g.segment
473           end
474   
475           if @spexebndcount > 0
476           begin
477               select @sp_name = object_cinfo from sysattributes
478               where (class = 6 and object_type = 'PR' and object_info1 = @uid)
479               /*
480               ** 18554, "You cannot drop user '%1!' because stored proc '%2!'
481               **	 owned by it is bound to an execution class. Use 
482               **	 sp_unbindexeclass before dropping user."
483               */
484               raiserror 18554, @name_in_db, @sp_name
485           end
486           return (1)
487       end
488   
489       /*
490       ** Check if userid appears in sysprocesses. In that case somebody
491       ** is still using it so we can not remove it.
492       */
493       if exists (select * from master.dbo.sysprocesses where uid = @uid
494                   and dbid = db_id())
495       begin
496           /*
497           ** 17915, "Warning: the specified account is currently active."
498           */
499           exec sp_getmessage 17915, @msg output
500           print @msg
501   
502           /*
503           ** 17918, "Nothing changed."
504           */
505           exec sp_getmessage 17918, @msg output
506           print @msg
507           return (1)
508       end
509   
510       /*
511       **  Drop the user.
512       **  Also drop any references to the user in the sysprotects table.
513       **  If anyone is aliased to the user, drop them also.
514       **
515       ** IMPORTANT: The name rs_logexec is significant. It is used by 
516       ** Replication Server.
517       */
518   
519   
520   
521       begin transaction rs_logexec
522   
523   
524   
525       delete from sysusers
526       where uid = @uid
527       select @err1 = @@error, @userdropped = @@rowcount
528   
529   
530   
531       delete from sysprotects
532       where uid = @uid
533   
534   
535   
536       /*
537       **  Drop any dependent aliases.
538       */
539       if exists (select *
540               from sysalternates
541               where altsuid = @suid)
542       begin
543           delete from sysalternates
544           where altsuid = @suid
545   
546   
547           /*
548           ** 17547, "The dependent aliases were also dropped."
549           */
550           exec sp_getmessage 17547, @msg output
551           print @msg
552       end
553   
554       /* 
555       **  Delete entries from sysattributes
556       */
557       delete from sysattributes
558       where object_type = "U"
559           and object = @uid
560   
561   
562   
563       /* Delete entries from sysencryptkeys */
564   
565       if exists (select * from sysencryptkeys
566               where uid = @uid)
567       begin
568           delete from sysencryptkeys
569           where uid = @uid
570       end
571   
572   
573   
574       if @userdropped != 1
575       begin
576           /*
577           ** 19941, "You cannot drop the user because the suid value for
578           ** user '%1!' is not unique in the database."
579           */
580           raiserror 19941, @name_in_db
581   
582           goto clean_all
583       end
584   
585   
586       if (@gp_enabled = 1 and db_name() = 'master')
587       begin -- {
588           select @uwp = users_with_privilege(
589                   'manage security permissions', 0)
590           if @uwp is NULL
591           begin -- {
592               select @nopriverr = 1
593               goto clean_all
594           end -- }
595           select @uwp = users_with_privilege(
596                   'manage server permissions', 0)
597           if @uwp is NULL
598           begin -- {
599               select @nopriverr = 1
600               goto clean_all
601           end -- }
602       end -- }
603   
604       /*
605       ** Write the log record to replicate this invocation 
606       ** of the stored procedure.
607       */
608       if (logexec() != 1)
609       begin
610           /*
611           ** 17756, "The execution of the stored procedure '%1!'
612           ** 	   in database '%2!' was aborted because there
613           ** 	   was an error in writing the replication log
614           **	   record."
615           */
616           select @dbname = db_name()
617           raiserror 17756, "sp_dropuser", @dbname
618   
619           rollback transaction rs_logexec
620           return (1)
621       end
622   
623   
624   
625       commit transaction rs_logexec
626   
627       /* Update protection timestamp in Resource */
628       grant all to null
629   
630   print_msg:
631   
632       /*
633       ** 17548, "User has been dropped from current database."
634       */
635       exec sp_getmessage 17548, @msg output
636       print @msg
637   
638       return (0)
639   
640   clean_all:
641       if (@gp_enabled = 1 and @nopriverr != 0)
642       begin
643           /** 
644           ** 17040, "Operation failed. There must be at least one 
645           ** unlocked login with privilege MANAGE SECRUITY PERMISSIONS 
646           ** and at least one unlocked login with privilege MANAGE 
647           ** SERVER PERMISSIONS after this operation.
648           **/
649           raiserror 17040, "sp_dropuser"
650       end
651       rollback transaction rs_logexec
652       return (1)
653   


exec sp_procxmode 'sp_dropuser', 'AnyMode'
go

Grant Execute on sp_dropuser to public
go
RESULT SETS
sp_dropuser_rset_004
sp_dropuser_rset_003
sp_dropuser_rset_002
sp_dropuser_rset_001

DEFECTS
 QCAR 6 Cartesian product between tables #sysprotects1 p and [sybsystemprocs..sysusers u] 417
 QJWI 5 Join or Sarg Without Index 249
 QJWI 5 Join or Sarg Without Index 282
 QJWI 5 Join or Sarg Without Index 323
 QJWI 5 Join or Sarg Without Index 338
 QJWI 5 Join or Sarg Without Index 472
 MINU 4 Unique Index with nullable columns sybsystemprocs..sysattributes sybsystemprocs..sysattributes
 MINU 4 Unique Index with nullable columns sybsystemprocs..sysencryptkeys sybsystemprocs..sysencryptkeys
 MINU 4 Unique Index with nullable columns sybsystemprocs..sysprotects sybsystemprocs..sysprotects
 MTYP 4 Assignment type mismatch object: longsysname(0) = longsysname(255) 367
 MTYP 4 Assignment type mismatch privilege: varchar(28) = varchar(255) 370
 MTYP 4 Assignment type mismatch object: longsysname(0) = sysname 395
 MTYP 4 Assignment type mismatch privilege: varchar(28) = varchar(255) 398
 MTYP 4 Assignment type mismatch privilege: varchar(28) = varchar(255) 425
 MUSP 4 Unquoted String Parameter sybsystemprocs..sp_autoformat: @fulltabname 437
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: spt_values.spt_valuesclust clustered
(number, type)
Intersection: {type}
212
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {uid}
239
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {uid}
242
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {grantor}
248
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {uid}
250
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {uid}
270
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid}
451
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {uid}
532
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {object_type, object}
558
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysencryptkeys.csysencryptkeys unique clustered
(id, type, uid)
Intersection: {uid}
566
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysencryptkeys.csysencryptkeys unique clustered
(id, type, uid)
Intersection: {uid}
569
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 215
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 257
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 283
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 324
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 374
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 378
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 388
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 402
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 403
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 407
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 432
 QTYP 4 Comparison type mismatch Comparison type mismatch: int vs smallint 433
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 451
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 458
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 478
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 494
 TNOI 4 Table with no index master..sysprocesses master..sysprocesses
 TNOI 4 Table with no index sybsystemprocs..syssegments sybsystemprocs..syssegments
 TNOI 4 Table with no index sybsystemprocs..systhresholds sybsystemprocs..systhresholds
 TNOU 4 Table with no unique index master..spt_values master..spt_values
 MAW1 3 Warning message on %name% sybsystemprocs..sysobjects.id: Warning message on sysobjects 249
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 249
 MAW1 3 Warning message on %name% tempdb..#sysprotects2.id: Warning message on #sysprotects2_crby_sybsystemprocs__sp_dropuser 312
 MAW1 3 Warning message on %name% sybsystemprocs..syscolumns.id: Warning message on syscolumns 313
 MAW1 3 Warning message on %name% sybsystemprocs..syscolumns.id: Warning message on syscolumns 315
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 317
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 320
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 324
 MAW1 3 Warning message on %name% tempdb..#sysprotects2.id: Warning message on #sysprotects2_crby_sybsystemprocs__sp_dropuser 324
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 332
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 335
 MAW1 3 Warning message on %name% sybsystemprocs..sysobjects.id: Warning message on sysobjects 363
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 363
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 368
 MAW1 3 Warning message on %name% sybsystemprocs..sysobjects.id: Warning message on sysobjects 377
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 377
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 388
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 396
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 403
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 420
 MAW1 3 Warning message on %name% tempdb..#sysprotects1.id: Warning message on #sysprotects1_crby_sybsystemprocs__sp_dropuser 431
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 459
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 328
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 329
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 338
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 343
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 344
 MGTP 3 Grant to public master..spt_values  
 MGTP 3 Grant to public master..sysdatabases  
 MGTP 3 Grant to public master..sysprocesses  
 MGTP 3 Grant to public sybsystemprocs..sp_dropuser  
 MGTP 3 Grant to public sybsystemprocs..sysalternates  
 MGTP 3 Grant to public sybsystemprocs..sysattributes  
 MGTP 3 Grant to public sybsystemprocs..syscolumns  
 MGTP 3 Grant to public sybsystemprocs..sysobjects  
 MGTP 3 Grant to public sybsystemprocs..sysprotects  
 MGTP 3 Grant to public sybsystemprocs..syssegments  
 MGTP 3 Grant to public sybsystemprocs..systhresholds  
 MGTP 3 Grant to public sybsystemprocs..systypes  
 MGTP 3 Grant to public sybsystemprocs..sysusers  
 MNER 3 No Error Check should check return value of exec 293
 MNER 3 No Error Check should check return value of exec 294
 MNER 3 No Error Check should check return value of exec 296
 MNER 3 No Error Check should check @@error after insert 312
 MNER 3 No Error Check should check @@error after insert 317
 MNER 3 No Error Check should check @@error after insert 332
 MNER 3 No Error Check should check @@error after insert 365
 MNER 3 No Error Check should check @@error after insert 393
 MNER 3 No Error Check should check @@error after insert 423
 MNER 3 No Error Check should check return value of exec 437
 MNER 3 No Error Check should check return value of exec 445
 MNER 3 No Error Check should check return value of exec 499
 MNER 3 No Error Check should check return value of exec 505
 MNER 3 No Error Check should check @@error after delete 531
 MNER 3 No Error Check should check @@error after delete 543
 MNER 3 No Error Check should check return value of exec 550
 MNER 3 No Error Check should check @@error after delete 557
 MNER 3 No Error Check should check @@error after delete 568
 MNER 3 No Error Check should check return value of exec 635
 MUCO 3 Useless Code Useless Brackets 88
 MUCO 3 Useless Code Useless Brackets 89
 MUCO 3 Useless Code Useless Brackets 111
 MUCO 3 Useless Code Useless Brackets 113
 MUCO 3 Useless Code Useless Brackets 115
 MUCO 3 Useless Code Useless Brackets 119
 MUCO 3 Useless Code Useless Brackets 127
 MUCO 3 Useless Code Useless Brackets 139
 MUCO 3 Useless Code Useless Brackets 147
 MUCO 3 Useless Code Useless Brackets 149
 MUCO 3 Useless Code Useless Brackets 151
 MUCO 3 Useless Code Useless Brackets 164
 MUCO 3 Useless Code Useless Brackets 170
 MUCO 3 Useless Code Useless Brackets 188
 MUCO 3 Useless Code Useless Brackets 204
 MUCO 3 Useless Code Useless Brackets 224
 MUCO 3 Useless Code Useless Brackets 230
 MUCO 3 Useless Code Useless Brackets 257
 MUCO 3 Useless Code Useless Brackets 262
 MUCO 3 Useless Code Useless Brackets 391
 MUCO 3 Useless Code Useless Brackets 478
 MUCO 3 Useless Code Useless Brackets 486
 MUCO 3 Useless Code Useless Brackets 507
 MUCO 3 Useless Code Useless Brackets 586
 MUCO 3 Useless Code Useless Brackets 608
 MUCO 3 Useless Code Useless Brackets 620
 MUCO 3 Useless Code Useless Brackets 638
 MUCO 3 Useless Code Useless Brackets 641
 MUCO 3 Useless Code Useless Brackets 652
 MUIN 3 Column created using implicit nullability 301
 MUIN 3 Column created using implicit nullability 306
 MUIN 3 Column created using implicit nullability 307
 QAFM 3 Var Assignment from potentially many rows 210
 QAFM 3 Var Assignment from potentially many rows 477
 QCRS 3 Conditional Result Set 268
 QCRS 3 Conditional Result Set 279
 QCRS 3 Conditional Result Set 449
 QCRS 3 Conditional Result Set 469
 QCTC 3 Conditional Table Creation 301
 QCTC 3 Conditional Table Creation 306
 QCTC 3 Conditional Table Creation 307
 QDIS 3 Check correct use of 'select distinct' 319
 QDIS 3 Check correct use of 'select distinct' 334
 QDIS 3 Check correct use of 'select distinct' 449
 QDIS 3 Check correct use of 'select distinct' 456
 QGWO 3 Group by/Distinct/Union without order by 319
 QGWO 3 Group by/Distinct/Union without order by 334
 QGWO 3 Group by/Distinct/Union without order by 456
 QISO 3 Set isolation level 96
 QIWC 3 Insert with not all columns specified missing 2 columns out of 4 423
 QNAJ 3 Not using ANSI Inner Join 280
 QNAJ 3 Not using ANSI Inner Join 322
 QNAJ 3 Not using ANSI Inner Join 337
 QNAJ 3 Not using ANSI Inner Join 362
 QNAJ 3 Not using ANSI Inner Join 371
 QNAJ 3 Not using ANSI Inner Join 386
 QNAJ 3 Not using ANSI Inner Join 399
 QNAJ 3 Not using ANSI Inner Join 417
 QNAJ 3 Not using ANSI Inner Join 426
 QNAJ 3 Not using ANSI Inner Join 450
 QNAJ 3 Not using ANSI Inner Join 457
 QNAJ 3 Not using ANSI Inner Join 470
 QNUA 3 Should use Alias: Table #sysprotects2 324
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {class, object_type, object_info1}
257
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {uid, id, protecttype}
458
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {class, object_type, object_info1}
478
 QTJ1 3 Table only appears in inner join clause 362
 QTJ1 3 Table only appears in inner join clause 387
 QUNI 3 Check Use of 'union' vs 'union all' 449
 VNRD 3 Variable is not read @dummy 156
 VNRD 3 Variable is not read @msg_true 293
 VNRD 3 Variable is not read @msg_false 294
 VNRD 3 Variable is not read @err1 527
 MRST 2 Result Set Marker 268
 MRST 2 Result Set Marker 279
 MRST 2 Result Set Marker 449
 MRST 2 Result Set Marker 469
 MSUB 2 Subquery Marker 214
 MSUB 2 Subquery Marker 249
 MSUB 2 Subquery Marker 362
 MSUB 2 Subquery Marker 386
 MSUB 2 Subquery Marker 417
 MSUB 2 Subquery Marker 493
 MSUB 2 Subquery Marker 539
 MSUB 2 Subquery Marker 565
 MSUC 2 Correlated Subquery Marker 324
 MTR1 2 Metrics: Comments Ratio Comments: 36% 43
 MTR2 2 Metrics: Cyclomatic Complexity Cyclo: 51 = 59dec - 10exi + 2 43
 MTR3 2 Metrics: Query Complexity Complexity: 361 43
 PRED_QUERY_COLLECTION 2 {t=sybsystemprocs..systypes, t2=sybsystemprocs..systypes} 0 279
 PRED_QUERY_COLLECTION 2 {p=sybsystemprocs..sysprotects, u=sybsystemprocs..sysusers} 0 449
 PRED_QUERY_COLLECTION 2 {p=sybsystemprocs..sysprotects, u=sybsystemprocs..sysusers} 0 456
 PRED_QUERY_COLLECTION 2 {s=sybsystemprocs..syssegments, t=sybsystemprocs..systhresholds} 0 469

DEPENDENCIES
PROCS AND TABLES USED
writes table sybsystemprocs..sp_dropuser_rset_003 
read_writes table sybsystemprocs..sysattributes  
read_writes table tempdb..#sysprotects1 (1) 
read_writes table tempdb..#sysprotects2 (1) 
writes table sybsystemprocs..sp_dropuser_rset_004 
writes table sybsystemprocs..sp_dropuser_rset_002 
read_writes table sybsystemprocs..sysprotects  
calls proc sybsystemprocs..sp_getmessage  
   reads table master..syslanguages (1)  
   reads table sybsystemprocs..sysusermessages  
   calls proc sybsystemprocs..sp_validlang  
      reads table master..syslanguages (1)  
   reads table master..sysmessages (1)  
reads table sybsystemprocs..systhresholds  
calls proc sybsystemprocs..sp_autoformat  
   reads table tempdb..systypes (1)  
   writes table sybsystemprocs..sp_autoformat_rset_001 
   writes table sybsystemprocs..sp_autoformat_rset_003 
   writes table sybsystemprocs..sp_autoformat_rset_005 
   read_writes table tempdb..#colinfo_af (1) 
   reads table master..systypes (1)  
   writes table sybsystemprocs..sp_autoformat_rset_004 
   calls proc sybsystemprocs..sp_autoformat  
   calls proc sybsystemprocs..sp_namecrack  
   writes table sybsystemprocs..sp_autoformat_rset_002 
   reads table master..syscolumns (1)  
   reads table tempdb..syscolumns (1)  
reads table sybsystemprocs..syscolumns  
writes table tempdb..#sysprotects3 (1) 
reads table master..sysprocesses (1)  
reads table sybsystemprocs..systypes  
reads table sybsystemprocs..syssegments  
calls proc sybsystemprocs..sp_aux_checkroleperm  
   reads table master..sysconfigures (1)  
   reads table master..syscurconfigs (1)  
writes table sybsystemprocs..sp_dropuser_rset_001 
read_writes table sybsystemprocs..sysalternates  
read_writes table sybsystemprocs..sysencryptkeys  
reads table master..spt_values (1)  
reads table sybsystemprocs..sysobjects  
reads table master..sysdatabases (1)  
calls proc sybsystemprocs..sp_ha_check_certified  
   reads table tempdb..sysobjects (1)  
read_writes table sybsystemprocs..sysusers