DatabaseProcApplicationCreatedLinks
sybsystemprocssp_opt_querystats_main  31 Aug 14Defects Dependencies

1     
2     /*
3     ** SP_OPT_QUERYSTATS_MAIN
4     **
5     ** This is the main stored procedure for the sp_opt_querystats utility.
6     ** This stored procedure handles verification of the conditions for
7     ** executing the optimizer diagnostic utility are present and then
8     ** creates and executes the Job Scheduler job to generate the diagnostic
9     ** information.  Once the job has completed, this stored procedure
10    ** retrieves the results from the Job Scheduler database and returns
11    ** then to the caller.
12    **
13    ** History:
14    **    4/28/2011   pdorfman   written
15    */
16    create procedure sp_opt_querystats_main
17        @query varchar(16384),
18        @input_params varchar(2048) = "all",
19        @target_database varchar(30) = null,
20        @user_name varchar(30) = null
21    as
22        declare @job_name varchar(80)
23        declare @option_string varchar(4096)
24        declare @server_name varchar(256)
25        declare @jobid int
26        declare @ret int
27        declare @first_row int
28        declare @last_row int
29        declare @offset int
30        declare @options int
31        declare @begin int
32        declare @length int
33        declare @current_parameter varchar(50)
34        declare @current_option int
35        declare @input_length int
36        declare @position int
37        declare @command varchar(1024)
38        declare @optgoal_count int
39        declare @return_code int
40        declare @use_db_cmd varchar(50)
41        declare @exit_code int
42        declare @max_job_output int
43        declare @set_user_cmd varchar(60)
44    
45        declare @statio_string varchar(30)
46        declare @stattime_string varchar(30)
47        declare @showplan_string varchar(30)
48        declare @missingstats_string varchar(30)
49        declare @resource_string varchar(30)
50        declare @plancost_string varchar(30)
51        declare @option_show_string varchar(30)
52        declare @exec_string varchar(30)
53        declare @option_show_long_string varchar(30)
54        declare @allrows_mix_string varchar(30)
55        declare @allrows_oltp_string varchar(30)
56        declare @allrows_dss_string varchar(30)
57        declare @diagmode_string varchar(30)
58        declare @option_all_string varchar(30)
59        declare @option_allexec_string varchar(30)
60        declare @showdata_string varchar(30)
61        declare @switches_string varchar(30)
62        declare @quoted_identifier_string varchar(30)
63    
64        /*
65        ** The following variable definitions and assignments must correspond
66        ** exactly to those in sp_opt_querystats_job
67        */
68        declare @query_evaluating_const int
69        declare @query_pending_const int
70        declare @query_finished_const int
71    
72        declare @statio_const int
73        declare @stattime_const int
74        declare @showplan_const int
75        declare @missingstats_const int
76        declare @resource_const int
77        declare @plancost_const int
78        declare @option_show_const int
79        declare @noexec_const int
80        declare @option_show_long_const int
81        declare @allrows_mix_const int
82        declare @allrows_oltp_const int
83        declare @allrows_dss_const int
84        declare @diagmode_const int
85        declare @nodata_const int
86        declare @switches_const int
87        declare @quoted_identifier_const int
88    
89        select @statio_const = 1
90        select @stattime_const = 2
91        select @showplan_const = 4
92        select @missingstats_const = 8
93        select @resource_const = 16
94        select @plancost_const = 32
95        select @option_show_const = 64
96        select @noexec_const = 128
97        select @option_show_long_const = 256
98        select @allrows_mix_const = 512
99        select @allrows_oltp_const = 1024
100       select @allrows_dss_const = 2048
101       select @diagmode_const = 4096
102       select @nodata_const = 8192
103       select @switches_const = 16384
104       select @quoted_identifier_const = 32768
105   
106       select @query_pending_const = 0
107       select @query_evaluating_const = 1
108       select @query_finished_const = 2
109       /*
110       ** End common constant definitions
111       */
112   
113       select @statio_string = "statio"
114       select @stattime_string = "stattime"
115       select @showplan_string = "showplan"
116       select @missingstats_string = "missingstats"
117       select @resource_string = "resource"
118       select @plancost_string = "plancost"
119       select @option_show_string = "option_show"
120       select @exec_string = "exec"
121       select @option_show_long_string = "option_show_long"
122       select @allrows_mix_string = "allrows_mix"
123       select @allrows_oltp_string = "allrows_oltp"
124       select @allrows_dss_string = "allrows_dss"
125       select @diagmode_string = "diagmode"
126       select @option_all_string = "all"
127       select @option_allexec_string = "allexec"
128       select @showdata_string = "showdata"
129       select @switches_string = "switches"
130       select @quoted_identifier_string = "quoted_identifier"
131   
132       select @options = 0
133       select @return_code = 0
134   
135       if (@query = "help")
136       begin
137           print "sp_opt_querystats stored procedure"
138           print ""
139           print "Reports information about the optimization of a query."
140           print ""
141           print '   Usage: sp_opt_querystats "<query text>" | help [, "<diagnostic options>" | null [, <database name> [, <user name>]]]'
142           print ""
143           print "   Where:"
144           print ""
145           print "    <query text> (required) is the text of the query to be analyzed."
146           print ""
147           print "    <diagnostic options>  (optional) is a comma-separated list containing one or more of the following strings:"
148           print ""
149           print "     - statio"
150           print "     - stattime"
151           print "     - showplan"
152           print "     - missingstats"
153           print "     - resource"
154           print "     - plancost"
155           print "     - showdata"
156           print "     - exec"
157           print "     - option_show_long"
158           print "     - option_show"
159           print "     - allrows_mix"
160           print "     - allrows_oltp"
161           print "     - allrows_dss"
162           print "     - diagmode"
163           print "     - switches"
164           print "     - quoted_identifier"
165           print "     - all"
166           print "     - allexec"
167           print ""
168           print "    Note that the values within the following lists are mutually exclusive. You can only specify one of these:"
169           print "       {allrows_mix, allrows_oltp, allrows_dss}"
170           print "       {option_show, option_show_long}"
171           print "       {all, allexec}"
172           print ""
173           print "   <database name> (optional) can be used to specify the name of the database in which the query should be executed.  This is used when the table names in the query are not fully qualified.  Note that all unqualified tables must be in a single database that is specified by this parameter."
174           print ""
175           print "   <user name> (optional) can be used to specify the name of the user under which the query should be executed. The user must be a valid user in the database specified by the database name parameter."
176           print ""
177           print "   Note that the database name parameter cannot be NULL if user name is specified."
178           print ""
179           print "For example:"
180           print ""
181           print '  sp_opt_querystats "select * from pubs2.dbo.authors"'
182           print "or"
183           print '	 sp_opt_querystats "select * from pubs2.dbo.authors", "showplan,statio,option_show,plancost"'
184           print "or"
185           print '  sp_opt_querystats "select * from authors", "all", pubs2'
186   
187           return (0)
188       end
189   
190       /*
191       ** Verify that the user has sufficient permissions to
192       ** execute DBCC commands used by the job
193       */
194       if (proc_role("sa_role") < 1)
195       begin
196           return - 1
197       end
198   
199       /*
200       ** Verify that the user has the required Job Scheduler role
201       */
202       if ((charindex("js_admin_role", show_role()) = 0)
203               and (charindex("js_user_role", show_role()) = 0))
204       begin
205           /*
206           ** "ERROR: You must have either 'js_user_role' or 'js_admin_role' to run
207           **  this stored procedure."
208           */
209           raiserror 17094
210           return - 1
211       end
212   
213       /*
214       ** Verify that the Job Scheduler is enabled.  Note that this does not
215       ** guarantee that the Job Scheduler is actually running.  See the next check.
216       */
217       if not exists (select 1 from master.dbo.syscurconfigs cc, master.dbo.sysconfigures sc
218               where cc.config = sc.config and cc.value = 1
219                   and sc.comment = 'enable job scheduler')
220       begin
221           /*
222           ** "ERROR: The Job Scheduler is not enabled on this server. The Job
223           **  Scheduler must be enabled to execute this stored procedure. "
224           */
225           raiserror 17095
226           return - 1
227       end
228   
229       /*
230       ** Verify that the Job Scheduler is running
231       */
232       if not exists (select 1 from master.dbo.sysprocesses where cmd = "JOB SCHEDULER")
233       begin
234           /*
235           ** "ERROR: The Job Scheduler is not running. Contact a system administrator
236           **  to resolve this problem."
237           */
238           raiserror 17009
239           return - 1
240       end
241   
242       /*
243       ** Parse the input parameters first and set the options bit mask
244       */
245       if (@input_params is null)
246       begin
247           select @input_params = @option_all_string
248       end
249   
250       /*
251       ** Enable nodata and noexec by default.  These will
252       ** be disabled if the user specifies exec or showdata options.
253       */
254       select @options = @nodata_const + @noexec_const
255   
256       select @input_params = ltrim(rtrim(@input_params))
257       select @input_length = char_length(@input_params)
258       select @length = @input_length
259       select @optgoal_count = 0
260       select @begin = 1
261   
262       while (@length > 0)
263       begin
264           select @position = charindex(",", substring(@input_params, @begin,
265                       (@input_length - @begin)))
266   
267           if (@position != 0)
268           begin
269               select @length = @position - 1
270               select @current_parameter = rtrim(ltrim(substring(@input_params, @begin,
271                               @length)))
272           end
273           else
274           begin
275               select @length = @input_length - @begin + 1
276               select @current_parameter = rtrim(ltrim(substring(@input_params, @begin,
277                               @length)))
278           end
279   
280           if (@current_parameter = @option_all_string
281                   or @current_parameter = @option_allexec_string)
282           begin
283               select @options = @options
284                   | @statio_const
285                   | @stattime_const
286                   | @showplan_const
287                   | @missingstats_const
288                   | @resource_const
289                   | @plancost_const
290                   | @option_show_long_const
291                   | @switches_const
292   
293               if (@current_parameter = @option_allexec_string)
294               begin
295                   select @options = @options ^ @noexec_const
296               end
297           end
298           else if (@current_parameter = @statio_string)
299               select @options = @options | @statio_const
300           else if (@current_parameter = @stattime_string)
301               select @options = @options | @stattime_const
302           else if (@current_parameter = @showplan_string)
303               select @options = @options | @showplan_const
304           else if (@current_parameter = @missingstats_string)
305               select @options = @options | @missingstats_const
306           else if (@current_parameter = @resource_string)
307               select @options = @options | @resource_const
308           else if (@current_parameter = @plancost_string)
309               select @options = @options | @plancost_const
310           else if (@current_parameter = @option_show_string)
311               select @options = @options | @option_show_const
312           else if (@current_parameter = @switches_string)
313               select @options = @options | @switches_const
314           else if (@current_parameter = @quoted_identifier_string)
315               select @options = @options | @quoted_identifier_const
316           else if (@current_parameter = @exec_string)
317               -- Disable the default noexec option
318               select @options = @options ^ @noexec_const
319           else if (@current_parameter = @option_show_long_string)
320               select @options = @options | @option_show_long_const
321           else if (@current_parameter = @showdata_string)
322               -- Disable the default nodata option
323               select @options = @options ^ @nodata_const
324           else if (@current_parameter = @allrows_mix_string)
325           begin
326               select @options = @options | @allrows_mix_const
327               select @optgoal_count = @optgoal_count + 1
328           end
329           else if (@current_parameter = @allrows_oltp_string)
330           begin
331               select @options = @options | @allrows_oltp_const
332               select @optgoal_count = @optgoal_count + 1
333           end
334           else if (@current_parameter = @allrows_dss_string)
335           begin
336               select @options = @options | @allrows_dss_const
337               select @optgoal_count = @optgoal_count + 1
338           end
339           else if (@current_parameter = @diagmode_string)
340               select @options = @options | @diagmode_const
341           else
342           begin
343               /*
344               ** "ERROR: Invalid option parameter: '%1!'", @current_parameter
345               */
346               raiserror 17013, @current_parameter
347               return - 1
348           end
349   
350           select @begin = @begin + @length + 1
351   
352           if (@begin > @input_length)
353           begin
354               break
355           end
356       end
357   
358       if ((@options & @option_show_const != 0)
359               and (@options & @option_show_long_const != 0))
360       begin
361           /*
362           ** "ERROR: Both '%1!' and '%2!' were specified. You can only use one of
363           **  these options at a time.",
364           */
365           raiserror 17014, @option_show_string, @option_show_long_string
366           return - 1
367       end
368   
369       if (@optgoal_count > 1)
370       begin
371           /*
372           ** "ERROR: You have specified more than one optmizer goal. Only one
373           ** optimizer goal can be specified at a time."
374           */
375           raiserror 17049
376           return - 1
377       end
378   
379       /*
380       ** Create the job that will be used to execute this query
381       */
382       if (@@servername is null)
383       begin
384           /*
385           ** "ERROR: The @@servername variable is null.  The server name must be set."
386           */
387           raiserror 17071
388           return - 1
389       end
390   
391       select @server_name = @@servername
392   
393       /*
394       ** Create a unique job name and then create the job definition
395       */
396   
397       select @job_name = "opt_qstat_" +
398           convert(varchar(4), datepart(yy, getdate())) +
399           convert(varchar(2), datepart(mm, getdate())) +
400           convert(varchar(2), datepart(dd, getdate())) +
401           convert(varchar(2), datepart(hh, getdate())) +
402           convert(varchar(2), datepart(mi, getdate())) +
403           convert(varchar(2), datepart(ss, getdate())) +
404           convert(varchar(4), @@spid)
405   
406       /*
407       ** Only create a use database command if the target_database is not null
408       */
409       if (@target_database is not null)
410       begin
411           if not exists (select 1 from master.dbo.sysdatabases
412                   where name = @target_database)
413           begin
414   
415               /*
416               ** ERROR: Database '%1!' does not exist on this server.", @target_database
417               */
418               raiserror 17097, @target_database
419               select @return_code = - 1
420               return - 1
421           end
422   
423           select @use_db_cmd = "use " + @target_database + " go "
424       end
425       else
426       begin
427           select @use_db_cmd = ""
428       end
429   
430       if (@user_name is not null)
431       begin
432           if (@target_database is null)
433           begin
434               /*
435               ** ERROR: The user name can only be specified if the database name is
436               ** also specified.
437               */
438               raiserror 17099
439               return - 1
440           end
441   
442           select @set_user_cmd = ' setuser "' + @user_name + '" go '
443       end
444       else
445       begin
446           select @set_user_cmd = " "
447       end
448   
449       select @option_string = "jcmd=select jobid = @js_sjobid into #odu1 go "
450           + @use_db_cmd
451           + @set_user_cmd -- must be executed after the user database command
452           + " declare @jid int select @jid = jobid from #odu1 exec sp_opt_querystats_job @jid,server="
453           + @server_name
454           + ",sjproperties=shared_run"
455   
456       exec @jobid = sybmgmtdb.dbo.sp_sjobcreate @name = @job_name, @option = @option_string
457   
458       if (@jobid < 0)
459       begin
460           /*
461           ** "ERROR: Failed to create job '%1!' with option '%2!' with error code: %3!"
462           */
463           raiserror 17073, @job_name, @option_string, @jobid
464           return - 1
465       end
466   
467       /*
468       ** Determine whether the work table already exists.  If it does
469       ** not, create it now.
470       */
471       if not exists (select 1 from tempdb.dbo.sysobjects where name = @job_name)
472       begin
473           select @command =
474               "create table tempdb.." + @job_name + " " +
475               "(
476   	  status unsigned int, -- 0 = not executed; 1 = executing; 2 = executed
477   	  jobid int,
478   	  options unsigned int,
479   	  query text
480   	)"
481   
482           exec (@command)
483       end
484   
485       if not exists (select 1 from tempdb.dbo.sysobjects where name = @job_name)
486       begin
487           /*
488           ** "ERROR: Creation of work table tempdb..%1! failed", @job_name
489           */
490           raiserror 17072, @job_name
491           return - 1
492       end
493   
494       /*
495       * Insert the query into the work table now that we have the jobid
496       */
497       select @command = "insert tempdb.." + @job_name + " " +
498           "values (@query_pending_const, @jobid, @options, @query)"
499       exec (@command)
500   
501       /*
502       ** Call the Job Scheduler to execute the analysis of the query
503       */
504       exec @ret = sybmgmtdb.dbo.sp_sjobcontrol @name = @job_name, @option = "run_now"
505   
506       if (@ret < 0)
507       begin
508           /*
509           ** "ERROR: An error occurred while executing the job.  Job name: '%1!',
510           **  jobid: %2!.  Error: %3!",
511           */
512           raiserror 17074, @job_name, @jobid, @ret
513           select @return_code = - 1
514           goto cleanup
515       end
516   
517       /*
518       ** Do not continue until the JS Agent completes handling job output
519       */
520       while exists (select jsh_state from sybmgmtdb.dbo.js_history
521               where jsh_sjobid = @jobid
522                   and jsh_state in ("W", "Q", "B", "R1", "R2"))
523       begin
524           waitfor delay "00:00:01"
525       end
526   
527       /*
528       ** Pause to allow the Job Scheduler Agent to update the JS database
529       ** before removing the job history
530       */
531       waitfor delay "00:00:05"
532   
533       /*
534       ** Check the exit code for the job and raise an error if it was
535       ** not successful.
536       */
537       select @exit_code = h.jsh_exit_code
538       from sybmgmtdb.dbo.js_history h
539       where h.jsh_sjobid = @jobid
540   
541       if (@exit_code != 0)
542       begin
543           /*
544           ** ERROR: The job (jobid '%1!') failed with exit code '%2!'. Verify that 
545           ** the current user has a valid externlogin defined for this server and 
546           ** review the Job Scheduler agent log for any errors.
547           */
548           raiserror 17098, @jobid, @exit_code
549   
550           select @return_code = - 1
551           goto cleanup2
552       end
553   
554       /*
555       ** Extract the output from the job from the Job Scheduler history 
556       ** table and return it to the caller.
557       */
558       select seq_no = o.jsout_seqno,
559           job_output = convert(varchar(901),
560           substring(o.jsout_text, 1, o.jsout_size))
561       into #temp_history
562       from sybmgmtdb.dbo.js_output o,
563           sybmgmtdb.dbo.js_history h,
564           sybmgmtdb.dbo.js_scheduledjobs j
565       where j.sjob_id = h.jsh_sjobid
566           and h.jsh_sjobid = @jobid
567           and j.sjob_name = @job_name
568           and o.jsout_exid = h.jsh_exid
569       order by o.jsout_seqno asc
570   
571       /*
572       ** Check to see whether there was any job output
573       ** This must immediately follow the select into #temp_history
574       */
575       if (@@rowcount = 0)
576       begin
577           /*
578           ** "ERROR: No output found for job (jobid: '%1!'). The job may have failed
579           **  or the Job Scheduler may not be running. Contact a system administrator
580           **  to verify that the Job Scheduler is running and review the Job Scheduler
581           **  Agent log for errors.", 
582           */
583           raiserror 17076, @jobid
584           select @return_code = - 1
585           goto cleanup
586       end
587   
588       /*
589       ** Locate the rows containing the begin and end markers and delete
590       ** all rows before and after these rows.  They only contain progress
591       ** messages.
592       */
593       select @first_row = seq_no
594       from #temp_history
595       where job_output like "%BEGIN QUERY ANALYSIS%"
596   
597       select @last_row = seq_no
598       from #temp_history
599       where job_output like "%END QUERY ANALYSIS%"
600   
601       /*
602       ** If the diagnostic results are not found report an error and display the
603       ** job output in case this contains useful information to determine why
604       ** the job did not execute as expected.
605       */
606       if (@first_row is null or @last_row is null)
607       begin
608           select @max_job_output = cc.value
609           from master.dbo.syscurconfigs cc, master.dbo.sysconfigures sc
610           where cc.config = sc.config
611               and sc.comment = 'maximum job output'
612   
613           /*
614           ** ERROR: The optimizer diagnostics were incomplete.  This may be because 
615           ** the value of the 'maximum job output' configuration parameter (%1!) is 
616           ** smaller than the size of the diagnostic output. Consider increasing the 
617           ** value of 'maximum job output'.
618           */
619           raiserror 17077, @max_job_output
620   
621           select @return_code = - 1
622   
623           if (@options & @diagmode_const != 0)
624           begin
625               goto diagnostic_mode
626           end
627   
628           goto cleanup
629       end
630       else if (@options & @diagmode_const = 0)
631       begin
632           delete #temp_history
633           where seq_no < @first_row
634               or seq_no > @last_row
635   
636           /*
637           ** Update the rows containing the begin an end markers to
638           ** remove the text that lies before the beginning and
639           ** after the end markers.
640           */
641           select @offset = patindex("%BEGIN QUERY ANALYSIS%", job_output) - 2
642           from #temp_history
643           where seq_no = @first_row
644   
645           update #temp_history
646           set job_output = substring(job_output, @offset, (901 - @offset + 1))
647           where seq_no = @first_row
648   
649           select @offset = patindex("%END QUERY ANALYSIS%", job_output) + 20
650           from #temp_history
651           where seq_no = @last_row
652   
653           update #temp_history
654           set job_output = substring(job_output, 1, (@offset - 1))
655           where seq_no = @last_row
656       end
657   
658   diagnostic_mode:
659   
660       /*
661       ** Now return the output to the caller
662       */
663       select job_output
664       from #temp_history
665       order by seq_no asc
666   
667   cleanup:
668   
669       drop table #temp_history
670   
671   cleanup2:
672   
673       /*
674       ** Drop the output after we have displayed it
675       */
676   
677       exec @ret = sybmgmtdb.dbo.sp_sjobhistory @name = @job_name, @option = "drop"
678   
679       if (@ret != 0)
680       begin
681           /*
682           ** "ERROR: The call to sp_sjobhistory to drop job history '%1!' failed
683           ** with error code %2!",
684           */
685           raiserror 17078, @job_name, @ret
686           select @return_code = - 1
687       end
688   
689       exec @ret = sybmgmtdb.dbo.sp_sjobdrop @name = @job_name, @option = "all"
690   
691       if (@ret != 0)
692       begin
693           /*
694           **  "ERROR: call to sp_sjobdrop to drop job '%1!' failed with error code %2!"
695           */
696           raiserror 17096, @job_name, @ret
697           select @return_code = - 1
698       end
699   
700       select @command = "drop table tempdb.." + @job_name
701       exec (@command)
702   
703       return @return_code
704   


exec sp_procxmode 'sp_opt_querystats_main', 'AnyMode'
go

Grant Execute on sp_opt_querystats_main to public
go
RESULT SETS
sp_opt_querystats_main_rset_001

DEFECTS
 PERR 6 Parsing Error Could not find definition for table sybmgmtdb..js_history 520
 PERR 6 Parsing Error Could not find definition for table sybmgmtdb..js_history 538
 PERR 6 Parsing Error Could not find definition for table sybmgmtdb..js_output 562
 MBRV 4 Bad return value [-1-99] return - 1 196
 MBRV 4 Bad return value [-1-99] return - 1 210
 MBRV 4 Bad return value [-1-99] return - 1 226
 MBRV 4 Bad return value [-1-99] return - 1 239
 MBRV 4 Bad return value [-1-99] return - 1 347
 MBRV 4 Bad return value [-1-99] return - 1 366
 MBRV 4 Bad return value [-1-99] return - 1 376
 MBRV 4 Bad return value [-1-99] return - 1 388
 MBRV 4 Bad return value [-1-99] return - 1 420
 MBRV 4 Bad return value [-1-99] return - 1 439
 MBRV 4 Bad return value [-1-99] return - 1 464
 MBRV 4 Bad return value [-1-99] return - 1 491
 MEST 4 Empty String will be replaced by Single Space 138
 MEST 4 Empty String will be replaced by Single Space 140
 MEST 4 Empty String will be replaced by Single Space 142
 MEST 4 Empty String will be replaced by Single Space 144
 MEST 4 Empty String will be replaced by Single Space 146
 MEST 4 Empty String will be replaced by Single Space 148
 MEST 4 Empty String will be replaced by Single Space 167
 MEST 4 Empty String will be replaced by Single Space 172
 MEST 4 Empty String will be replaced by Single Space 174
 MEST 4 Empty String will be replaced by Single Space 176
 MEST 4 Empty String will be replaced by Single Space 178
 MEST 4 Empty String will be replaced by Single Space 180
 MEST 4 Empty String will be replaced by Single Space 427
 MINU 4 Unique Index with nullable columns master..sysconfigures master..sysconfigures
 MULT 4 Using literal database 'tempdb' tempdb..sysobjects 471
 MULT 4 Using literal database 'tempdb' tempdb..sysobjects 485
 QTYP 4 Comparison type mismatch Comparison type mismatch: other vs int 521
 QTYP 4 Comparison type mismatch Comparison type mismatch: other vs int 539
 QTYP 4 Comparison type mismatch Comparison type mismatch: other vs int 566
 QTYP 4 Comparison type mismatch Comparison type mismatch: other vs varchar(80) 567
 TNOI 4 Table with no index master..syscurconfigs master..syscurconfigs
 TNOI 4 Table with no index master..sysprocesses master..sysprocesses
 MDYN 3 Proc uses Dynamic SQL but is not flagged with Dynamic Ownership Chain 16
 MGTP 3 Grant to public master..sysconfigures  
 MGTP 3 Grant to public master..syscurconfigs  
 MGTP 3 Grant to public master..sysdatabases  
 MGTP 3 Grant to public master..sysprocesses  
 MGTP 3 Grant to public sybsystemprocs..sp_opt_querystats_main  
 MGTP 3 Grant to public tempdb..sysobjects  
 MNER 3 No Error Check should check @@error after select into 558
 MNER 3 No Error Check should check @@error after delete 632
 MNER 3 No Error Check should check @@error after update 645
 MNER 3 No Error Check should check @@error after update 653
 MUCO 3 Useless Code Useless Brackets 135
 MUCO 3 Useless Code Useless Brackets 187
 MUCO 3 Useless Code Useless Brackets 194
 MUCO 3 Useless Code Useless Brackets 202
 MUCO 3 Useless Code Useless Brackets 245
 MUCO 3 Useless Code Useless Brackets 262
 MUCO 3 Useless Code Useless Brackets 267
 MUCO 3 Useless Code Useless Brackets 280
 MUCO 3 Useless Code Useless Brackets 293
 MUCO 3 Useless Code Useless Brackets 298
 MUCO 3 Useless Code Useless Brackets 300
 MUCO 3 Useless Code Useless Brackets 302
 MUCO 3 Useless Code Useless Brackets 304
 MUCO 3 Useless Code Useless Brackets 306
 MUCO 3 Useless Code Useless Brackets 308
 MUCO 3 Useless Code Useless Brackets 310
 MUCO 3 Useless Code Useless Brackets 312
 MUCO 3 Useless Code Useless Brackets 314
 MUCO 3 Useless Code Useless Brackets 316
 MUCO 3 Useless Code Useless Brackets 319
 MUCO 3 Useless Code Useless Brackets 321
 MUCO 3 Useless Code Useless Brackets 324
 MUCO 3 Useless Code Useless Brackets 329
 MUCO 3 Useless Code Useless Brackets 334
 MUCO 3 Useless Code Useless Brackets 339
 MUCO 3 Useless Code Useless Brackets 352
 MUCO 3 Useless Code Useless Brackets 358
 MUCO 3 Useless Code Useless Brackets 369
 MUCO 3 Useless Code Useless Brackets 382
 MUCO 3 Useless Code Useless Brackets 409
 MUCO 3 Useless Code Useless Brackets 430
 MUCO 3 Useless Code Useless Brackets 432
 MUCO 3 Useless Code Useless Brackets 458
 MUCO 3 Useless Code Useless Brackets 506
 MUCO 3 Useless Code Useless Brackets 541
 MUCO 3 Useless Code Useless Brackets 575
 MUCO 3 Useless Code Useless Brackets 606
 MUCO 3 Useless Code Useless Brackets 623
 MUCO 3 Useless Code Useless Brackets 630
 MUCO 3 Useless Code Useless Brackets 679
 MUCO 3 Useless Code Useless Brackets 691
 MZMB 3 Zombie: use of non-existent object master..sp_sjobcreate 456
 MZMB 3 Zombie: use of non-existent object master..sp_sjobcontrol 504
 MZMB 3 Zombie: use of non-existent object sybmgmtdb..js_history 520
 MZMB 3 Zombie: use of non-existent object sybmgmtdb..js_history 538
 MZMB 3 Zombie: use of non-existent object sybmgmtdb..js_output 562
 MZMB 3 Zombie: use of non-existent object sybmgmtdb..js_history 563
 MZMB 3 Zombie: use of non-existent object sybmgmtdb..js_scheduledjobs 564
 MZMB 3 Zombie: use of non-existent object master..sp_sjobhistory 677
 MZMB 3 Zombie: use of non-existent object master..sp_sjobdrop 689
 QAFM 3 Var Assignment from potentially many rows 593
 QAFM 3 Var Assignment from potentially many rows 597
 QAFM 3 Var Assignment from potentially many rows 608
 QAFM 3 Var Assignment from potentially many rows 641
 QAFM 3 Var Assignment from potentially many rows 649
 QNAJ 3 Not using ANSI Inner Join 217
 QNAJ 3 Not using ANSI Inner Join 562
 QNAJ 3 Not using ANSI Inner Join 609
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {name}
471
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysobjects.ncsysobjects unique
(name, uid)
Intersection: {name}
485
 QTLO 3 Top-Level OR 633
 VNRD 3 Variable is not read @query_pending_const 106
 VNRD 3 Variable is not read @query_evaluating_const 107
 VNRD 3 Variable is not read @query_finished_const 108
 VUNU 3 Variable is not used @current_option 34
 MDYS 2 Dynamic SQL Marker 482
 MDYS 2 Dynamic SQL Marker 499
 MDYS 2 Dynamic SQL Marker 701
 MRST 2 Result Set Marker 663
 MSUB 2 Subquery Marker 217
 MSUB 2 Subquery Marker 232
 MSUB 2 Subquery Marker 411
 MSUB 2 Subquery Marker 471
 MSUB 2 Subquery Marker 485
 MTR1 2 Metrics: Comments Ratio Comments: 25% 16
 MTR2 2 Metrics: Cyclomatic Complexity Cyclo: 45 = 57dec - 14exi + 2 16
 MTR3 2 Metrics: Query Complexity Complexity: 402 16
 PRED_QUERY_COLLECTION 2 {c=master..syscurconfigs, c2=master..sysconfigures} 0 217
 PRED_QUERY_COLLECTION 2 {c=master..syscurconfigs, c2=master..sysconfigures} 0 608

DEPENDENCIES
PROCS AND TABLES USED
reads table master..sysprocesses (1)  
reads table master..sysconfigures (1)  
reads table master..sysdatabases (1)  
read_writes table tempdb..#temp_history (1) 
reads table tempdb..sysobjects (1)  
reads table master..syscurconfigs (1)  

CALLERS
called by proc sybsystemprocs..sp_opt_querystats