<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.0.0 (http://www.squarespace.com/) on Fri, 21 Nov 2008 21:49:16 GMT--><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/"><rss:channel rdf:about="http://blogs.interfacett.com/jeff-jones-blog/"><rss:title>Jeff Jones Blog</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/</rss:link><rss:description>Jeff Jones is an instructor in SQL for Interface Technical Training</rss:description><dc:language>en-US</dc:language><dc:date>2008-11-21T21:49:16Z</dc:date><admin:generatorAgent rdf:resource="http://www.squarespace.com/">Squarespace Site Server v5.0.0 (http://www.squarespace.com/)</admin:generatorAgent><rss:items><rdf:Seq><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/who-has-access.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2007/7/11/sql-server-2005-index-information.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2007/5/18/integration-services-security.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/12/14/dynamic-pivot.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/12/8/fn_split-table-valued-function.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/12/1/renaming-sql-server.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/11/9/moving-logins-across-multiple-sql-servers.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/11/8/accessing-mastersysperfinfo-table.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/11/3/reporting-services-automated-scripter.html"/><rdf:li rdf:resource="http://blogs.interfacett.com/jeff-jones-blog/2006/11/2/sql-server-2005-partitioning-script.html"/></rdf:Seq></rss:items></rss:channel><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/who-has-access.html"><rss:title>Who has access?</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/who-has-access.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2007-07-11T23:58:21Z</dc:date><dc:subject>SQL Server 2005</dc:subject><content:encoded><![CDATA[<p>Occasionally you would like to find out all the&nbsp;tables, views and stored procedures a user can access and what permissions they have.&nbsp; With a combination of the new EXECUTE AS command and the new HAS_PERMS_BY_NAME function you can figure this out.&nbsp;&nbsp;Below&nbsp;is a query that uses the sys.All_Objects metadata view to generate object names.&nbsp; Then&nbsp;it passes the object&nbsp;names&nbsp;through the new function with some additional parameters (the securable type, and permission type) and it returns 1 if the user has that permission and 0 if they do not.</p><p>The result shows both implicit permissions granted through&nbsp;fixed server or database roles. It also shows&nbsp;explicit permission granted though user-defined roles&nbsp;or granted directly to the database user account.&nbsp; </p><p>The EXECUTE AS can only specify individual user principal defined to SQL Server.&nbsp; It cannot reference a Windows Group.&nbsp; This is only valid with SQL Server 2005.&nbsp; </p><p><strong>EXECUTE AS LOGIN = 'miami\anders'</strong></p><p><strong>SELECT SCHEMA_NAME(schema_id) + '.' + name TableName <br />, type_desc<br />, HAS_PERMS_BY_NAME(SCHEMA_NAME(schema_id) + '.' + name, <br />&nbsp;&nbsp;&nbsp; 'OBJECT', 'SELECT') AS have_select<br />, HAS_PERMS_BY_NAME(SCHEMA_NAME(schema_id) + '.' + name, <br />&nbsp;&nbsp;&nbsp; 'OBJECT', 'UPDATE') AS have_update<br />, HAS_PERMS_BY_NAME(SCHEMA_NAME(schema_id) + '.' + name, <br />&nbsp;&nbsp;&nbsp; 'OBJECT', 'INSERT') AS have_insert<br />, HAS_PERMS_BY_NAME(SCHEMA_NAME(schema_id) + '.' + name, <br />&nbsp;&nbsp;&nbsp; 'OBJECT', 'DELETE') AS have_delete<br />, HAS_PERMS_BY_NAME(SCHEMA_NAME(schema_id) + '.' + name, <br />&nbsp;&nbsp;&nbsp; 'OBJECT', 'EXECUTE') AS have_execute<br />FROM sys.all_objects<br />WHERE type_desc IN ('USER_TABLE', 'SQL_STORED_PROCEDURE', 'VIEW')<br />AND SCHEMA_NAME(schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA')<br />ORDER BY type_desc, tablename</strong></p><p><strong>REVERT</strong></p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2007/7/11/sql-server-2005-index-information.html"><rss:title>SQL Server 2005 Index Information</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2007/7/11/sql-server-2005-index-information.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2007-07-11T23:32:11Z</dc:date><dc:subject>SQL Server 2005</dc:subject><content:encoded><![CDATA[<p>Here are some queries using the new Dynamic Management views and functions see which indexes are being used and how they are being updated.&nbsp; </p><p>This query shows which indexes are used, whether it was a seek, scan or lookup and the date it was last performed.&nbsp;When using the object_name function, you want&nbsp;to&nbsp;USE the database you are interested in and then filter the view so it only shows objects from that database.&nbsp; Filtering on object_id &gt; 100 eliminates system tables from the output.</p><p><strong>USE Adventureworks</strong></p><p><strong>SELECT object_name(object_id), *<br />FROM sys.dm_db_index_usage_stats<br />WHERE object_id &gt; 100 AND database_id = DB_ID('Adventureworks'</strong>)</p><p>This query provides more information about&nbsp;current low-level I/O, locking, latching, and access method activity for each partition of a table or index in the database.&nbsp;&nbsp; Since this query uses a table-valued function, you must pass parameters for the database id, table id, index id, and partition number.&nbsp; If you want to select all tables in a database you just need to pass the database id and specify DEFAULT for the other three parameters.&nbsp; Filtering on object_id &gt; 100 eliminates system tables from the output.</p><p><br /><strong>SELECT object_name(object_id), *<br />FROM sys.dm_db_index_operational_stats (db_id('Adventureworks'), default, default, default)<br />WHERE object_id &gt; 100</strong></p><p>The last query provides read and write I/O counts by file.&nbsp; This can help you determine which files have the highest I/O activity.&nbsp; <br /><br /><strong>SELECT db_name(database_id), * <br />FROM sys.dm_io_virtual_file_stats(default, default)</strong></p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2007/5/18/integration-services-security.html"><rss:title>Integration Services Security</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2007/5/18/integration-services-security.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2007-05-18T22:46:27Z</dc:date><dc:subject>Integration Services</dc:subject><content:encoded><![CDATA[<p>Defining security for SQL Server Integration Services (SSIS) is a bit complex. I want to focus on the security required by a developer to create and manage their own packages and people that are not SysAdmins but need to manage all packages. </p><p>After a package has been developed using BI Development Studio, it must be deployed to a location for subsequent execution. This is a similar model to application dll&rsquo;s and exe&rsquo;s that must be deployed to an object library for execution. With SSIS you can deploy a package to any file system directory, the MSDB database or a special file system directory known by the Integration Services Service. When deploying to a file system directory (whether known by Integration Services Service or not), you must rely on OS file system security to control access to these packages. If you deploy to the MSDB database you have other mechanisms available to control access to packages. </p><p>The MSDB database has three predefined fixed database roles specifically designed for SSIS. They are db_dtsltduser, db_dtsoperator and db_dtsadmin. Each of the roles has execute permissions on a set of MSDB stored procedures that are used to manipulate packages located in the dbo.sysdtspackages90 table. You can also define your own custom database roles to further secure packages deployed to MSDB. The user needs a database user account in MSDB to be assigned to these roles. </p><p>Each package has a default assignment&nbsp;to both the&nbsp;readerrole and writerrole. The readerrole allows for enumerating a packaging (displaying its name), viewing a package&rsquo;s definition, executing a package interactively, exporting a package definition and running a package under SQL Server Agent as a job. The writerrole allows for importing a package, deleting a package and changing package security roles. </p><p>When a package is placed in the MSDB database a default role assignment is made. The package&rsquo;s readerrole is assigned to db_dtsadmin, db_dtsoperator and the creator of the package. The writerrole is assigned to db_dtsadmin and the creator of the package. The details for each role and what&nbsp;they can do is described in SQL Server 2005 Books Online under the &ldquo;Integration Services Roles&rdquo; topic. </p><p>For those developers that need to deploy packages to MSDB, enumerate and execute packages that they own, they need to a member of db_dtsltduser. Again they can only manipulate packages that they own. </p><p>If a person that is not a Sysadmin needs to administer all the packages stored in MSDB, they need to be in the db_dtsadmin role. All users with SysAdmin rights can see and do anything with packages. </p><p>To execute any package, the user must be in the db_dtsoperator role. </p><p>Additional user-defined database roles can be created in MSDB to provide an additional level of control. The additional roles work in conjunction with the fixed roles described above. By default, when a package is placed in the MSDB database, the owner of the package and the users in the db_dtsadmin role can view the package definition (via exporting), modify the package (via importing), and execute the package. Also users in the db_dtsoperator role can execute the package. When you assign a user-defined role as the readerrole, anyone in that user-defined role can view the package and execute it. When you assign a user-defined role&nbsp;as the writerrole, anyone in that user-defined role can update the package definition. The user must also be in the db_dtsltduser role. So users must be in both the user-defined role and the db_dtsltduser role to access packages. </p><p>For example, you have a development team creating Integration Services packages. They decide to deploy the packages to SQL Server MSDB for execution. The packages where created by different developers and therefore the packages have different creators/owners. We want the entire team to be able to read and potentially update the various packages. The DBA does not want to give the developers SysAdmin permissions nor the ability to read, update and execute all the packages in the MSDB database. One approach would be to:</p><p>1.&nbsp;Create a user-defined role in MSDB, place all the developers in that role. </p><p>2. Assign that role to the db_dtsltduser fixed database role. This allows the developer team to access packages that they created and own. </p><p>3. Assign&nbsp;each package the team created to the user-defined role created earlier. </p><p>This will allow all team members to access all associated packages no matter who created them. </p><p>There are other issues related to the encryption of sensitive data in the package that I will cover in another blog post. </p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/12/14/dynamic-pivot.html"><rss:title>Dynamic PIVOT</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/12/14/dynamic-pivot.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-12-14T23:20:26Z</dc:date><dc:subject>SQL Server 2005</dc:subject><content:encoded><![CDATA[<p>One aspect of using the PIVOT is to include a list of columns that will be used as the crosstab of the query.&nbsp; For example, if you wish to display the total quantity ordered by Productid by Year you need to include the list of years for the query.&nbsp; This unfortunately must be a static list of values.&nbsp; So as you add years to the table, the query must be modified to include the new year.&nbsp; We discussed different ways to build a dynamic query to generate the list of years based on the data and insert that list into the PIVOT clause.&nbsp; </p><p>Following are a couple of scripts to solve the problem.&nbsp; The first one generates a sum of orderqty by productid pivoted by the duedate year.&nbsp; The second one generate a sum and avg of orderqty by productid by the duedate year.&nbsp; This one must UNION two PIVOT queries into a single result set.</p><p><br /><strong>-- Dynamically build the list of years based on the years in<br />-- the purchasing.purchaseorderdetail table.&nbsp; <br />-- Then use the list to perform a PIVOT operation displaying the<br />-- ProductID in each row and the sum of orderqty by Year.</strong></p><p><strong>DECLARE @Yearlist VARCHAR(MAX)<br />DECLARE @Years TABLE (Year int)</strong></p><p><strong>INSERT @Years (year)<br />&nbsp;SELECT DISTINCT top 100 percent YEAR(duedate)<br />&nbsp;FROM purchasing.purchaseorderdetail <br />&nbsp;ORDER BY YEAR(duedate) </strong></p><p><strong>SELECT @YearList = COALESCE(@YearList + ',[', '[') + <br />CAST(year AS CHAR(4)) + ']'<br />FROM @Years t</strong></p><p><strong>EXEC ('SELECT *<br />FROM (SELECT productid, YEAR(duedate) theyear, orderqty <br />FROM purchasing.PurchaseOrderDetail) t<br />PIVOT (SUM(OrderQty) FOR theyear IN (' + @Yearlist + ')) PVT')</strong></p><p><strong>-- Dynamically build the list of years based on the years in<br />-- the purchasing.purchaseorderdetail table.&nbsp; <br />-- Then use the list to perform a PIVOT operation displaying the<br />-- ProductID in each row and the sum of orderqty by Year.<br />-- Union this result with the same query performing an AVG on the <br />-- orderqty by productid. Included a literal column to identify <br />-- if the data is a sum or average.</strong></p><p><strong>DECLARE @Yearlist VARCHAR(MAX)<br />DECLARE @Years TABLE (Year int)</strong></p><p><strong>INSERT @Years (year)<br />&nbsp;SELECT DISTINCT top 100 percent YEAR(duedate)<br />&nbsp;FROM purchasing.purchaseorderdetail <br />&nbsp;ORDER BY YEAR(duedate) </strong></p><p><strong>SELECT @YearList = COALESCE(@YearList + ',[', '[') + <br />CAST(year AS CHAR(4)) + ']'<br />FROM @Years t</strong></p><p><strong>EXEC ('SELECT *<br />&nbsp;FROM (SELECT&nbsp; productid, ''sum'' type, YEAR(duedate) theyear, orderqty <br />&nbsp; FROM purchasing.PurchaseOrderDetail) t<br />&nbsp;PIVOT (SUM(OrderQty) FOR theyear IN (' + @Yearlist + ')) PVT'<br />&nbsp;+ 'UNION ' +<br />&nbsp;'SELECT *<br />&nbsp;FROM (SELECT&nbsp; productid, ''avg'' type, YEAR(duedate) theyear, orderqty <br />&nbsp; FROM purchasing.PurchaseOrderDetail) t<br />&nbsp;PIVOT (AVG(OrderQty) FOR theyear IN (' + @Yearlist + ')) PVT ' +<br />&nbsp;'ORDER BY productid')</strong></p><p>There is one more technique for generating the comma-delimited list of years using the FOR XML PATH option of a SELECT statement.&nbsp; I found this technique in Itzik Ben-Gan's new T-SQL Querying book.&nbsp; I decided to apply it to our dynamic pivot problem to see if we can come up with a simpler way to generate the list of years for the PIVOT operator. I quess we can debate whether this is simpler, at least it gets rid of the need to create a table variable and eliminates a statement.</p><p>This technique takes advantage of the PATH option on the FOR XML clause.&nbsp; If you specify an empty string in the PATH option it does not place any XML tags around the text.&nbsp; The STUFF function deletes the first comma generated in the string.&nbsp; </p><p>Following is a rewrite of the simple pivot above using this technique.<br /><br /><strong>DECLARE @Yearlist VARCHAR(MAX)</strong></p><p><strong>SELECT <br />@Yearlist = STUFF((SELECT ', [' + DYear + ']' AS [text()]<br />FROM (SELECT DISTINCT <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CONVERT(VARCHAR, YEAR(duedate)) dyear&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM purchasing.purchaseorderdetail) Y&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDER BY dyear<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR XML PATH('')), 1, 1, '')</strong></p><p><strong>EXEC ('SELECT *<br />FROM (SELECT productid, YEAR(duedate) theyear, orderqty <br />FROM purchasing.PurchaseOrderDetail) t<br />PIVOT (SUM(orderqty) FOR theyear IN (' + @Yearlist + ')) PVT')<br /></strong></p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/12/8/fn_split-table-valued-function.html"><rss:title>FN_Split() Table Valued Function</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/12/8/fn_split-table-valued-function.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-12-08T22:45:11Z</dc:date><dc:subject>SQL Server 2005 SQL Server 2000 Reporting Services</dc:subject><content:encoded><![CDATA[<a href="http://www.sqlmag.com/articles/index.cfm?articleid=21071&" target="_blank"><u><font style="color: #bb3300" color="#bb3300">Treat Yourself to Fn_Split()</font></u></a><br /><br />The link above is to an article in SQL Server magazine on a user-defined function called fn_split(). This function allows you to pass a string of values to an IN clause of a SQL query. It breaks them down into a set of rows in a virtual table. Then you use a subquery in the IN clause.]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/12/1/renaming-sql-server.html"><rss:title>Renaming SQL Server</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/12/1/renaming-sql-server.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-12-01T18:49:20Z</dc:date><dc:subject>SQL Server 2005 SQL Server 2000</dc:subject><content:encoded><![CDATA[<p>Following is a T-SQL script you can use to rename your SQL Server after you have changed the computer name. This script will work if you are connected to the default instance or a named instance. After running the script, you must restart SQL Server for the action to complete. </p><p>DECLARE @machinename sysname, @servername sysname, @instancename sysname <br />SELECT @instancename = <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CASE&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEN charindex('\', @@servername) = 0 THEN ''&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE SUBSTRING(@@servername,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CHARINDEX('\', @@servername), (len(@@servername)+ 1) -&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CHARINDEX('\', @@servername))&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END <br />SET @machinename = convert(nvarchar(100), serverproperty('machinename')) + @instancename; <br />EXEC sp_dropserver @@servername; <br />EXEC sp_addserver @machinename, 'local'</p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/11/9/moving-logins-across-multiple-sql-servers.html"><rss:title>Moving Logins Across Multiple SQL Servers</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/11/9/moving-logins-across-multiple-sql-servers.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-11-10T00:40:20Z</dc:date><dc:subject>SQL Server 2005 SQL Server 2000</dc:subject><content:encoded><![CDATA[<p>Moving logins from SQL Server to SQL Server has to be done alot.&nbsp; There are a number of situations that require moving logins like: log shipping, moving a database from one server to another, or database mirroring.&nbsp; In SQL Server 2000 DTS&nbsp;Transfer Logins didn't seem to do the job I wanted.&nbsp; The SQL Server 2005 Integration Services product is closer but it doesn't move SQL login passwords.&nbsp;&nbsp;</p><p>So I wrote a set of SQL statements that creates a script of sp_addlogins to copy the passwords and SIDs across for SQL Server 2000 and another query that creates the same script for SQL Server 2005 using CREATE LOGIN.&nbsp;&nbsp;&nbsp;The generated&nbsp;script includes Window logins, denied Windows logins and sets all server role memberships.&nbsp; If you are moving a database from one instance of&nbsp;SQL Server to another instance this script can help.&nbsp; It has been tested on SQL Server 2000 running SP3a and SQL Server 2005 running SP1.&nbsp; I would run this script before detaching databases (if you are using the detach/attach approach) and then run the resulting script on the new&nbsp;instance after you have attached or restored the databases to the new server.&nbsp; </p><p>This script moves all logins (except the SA, builtin\administrators, administrative local groups (SQL Server 2005) &nbsp;and nt authority\system logins) for all databases defined to an instance of SQL Server. If you are running this script with Query Analyzer or Management Studio, make sure the maximum characters per column is set to 8000.&nbsp;&nbsp; </p><p>Now for the disclaimer. I offer this script with no implied support nor has it been extensively tested.&nbsp; You should thoroughly review the script generated before applying it to your system.&nbsp; You can use this script for the intended purpose and also as a model for how you can use SQL to write scripts using a database table as the source.</p><p>I hope it helps.</p><p>Click&nbsp;<a href="http://jbjgroup.com/files/movelogins2000.zip"><strong>HERE</strong></a> to get the SQL Server 2000 script file.</p><p>Click <a href="http://jbjgroup.com/files/movelogins2005.zip"><strong>HERE</strong></a> to get the SQL Server 2005 script file.&nbsp;</p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/11/8/accessing-mastersysperfinfo-table.html"><rss:title>Accessing Master..Sysperfinfo Table</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/11/8/accessing-mastersysperfinfo-table.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-11-08T22:32:46Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>The SQL Server 2000 statistics are available in a pseudo-table in Master called sysperfinfo. This table returns the statistics in a table format. There are some statistics that represent ratios (i.e., Buffer Cache Hit Ratio). These statitics must combine two rows. One row provides the data value and the second row provides a divisor. Therefore to be able to read ratio statistics, you must bring these two rows together to compute the final result.<br /><br />Included in this post is a SELECT statement that displays all the statistics as well as perform the necessary calculation to display ratio statistics correctly. <br /><br />This query can come in handy if you need to view SQL Server statistics when you don't have access to the server's performance monitor program. It can also allow you to collect SQL Server statistics for storage in a SQL table for subsequent analysis. Just add a column with a GUID or DateTime stamp to group each statistics snapshot.<br /><br />I just found that all the statistics that are time adjusted like Logins/sec, Batches/sec, Transactions/sec, etc. are not displayed properly through a query of Master..Sysperfinfo. It will display a monotonically increasing number since the start of SQL Server. There is no way to compute the per second value. This also means that you cannot set SQL Server Alerts that use a per second threshold from these statistics to fire the alert. I noticed this behavior when doing more testing on my query and then found article 555064 in the Microsoft Knowledge Base confirming what I saw. This reduces the usefulness of this query. But you can still get access to most of the statistics. <br /><br /><strong>SELECT p1.object_name<br />, p1.counter_name<br />, p1.instance_name<br />, CASE p1.cntr_type<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEN 537003008 -- Count is a ratio<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; THEN CONVERT(FLOAT, p1.cntr_value) /&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CASE p2.cntr_value<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;WHEN 0 THEN 1 -- Make sure we don't divide by zero<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ELSE p2.cntr_value<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;END<br />&nbsp;&nbsp; ELSE p1.cntr_value -- No calculation necessary, display value<br />END AS Value<br />FROM master..sysperfinfo p1&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; LEFT OUTER JOIN master..sysperfinfo p2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ON (SUBSTRING(p1.counter_name , 1, --Deal with ratios that has (ms) in name<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COALESCE(NULLIF(charindex(' (ms)',p1.counter_name), 0), len(p1.counter_name) + 1))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= SUBSTRING(p2.counter_name, 1, CHARINDEX(' Base', p2.counter_name))) --Remove Base from counter name<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND p1.instance_name = p2.instance_name<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND p2.cntr_type = 1073939459 -- Only join if row is a ratio<br />WHERE p1.cntr_type 1073939459 -- Don't include rows with base divisor value</strong></p>]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/11/3/reporting-services-automated-scripter.html"><rss:title>Reporting Services Automated Scripter</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/11/3/reporting-services-automated-scripter.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-11-03T22:39:17Z</dc:date><dc:subject>SQL Server 2000</dc:subject><content:encoded><![CDATA[<a href="http://sqldbatips.com/showarticle.asp?ID=62" target="_blank"><u><font style="color: #bb3300" color="#bb3300">Download Reporting Services Scripter</font></u></a><br /><br />In class this week, one of the students told me about an automated scriptor for SQL Server 2000 Reporting Services. So I checked it out and wanted to pass it along to anyone actually reading this blog. <br /><br />If you go to the link above, it will take you to a website describing the RSScriptor program. It's a .NET program that connects to your Reporting Services server and gives you an MMC view of all your Reporting Services objects. You can then select the objects, specify what you want to script in the Options section and it will generate .RSS scripts that use the RS.EXE program. It also generates a .CMD file that executes RS.EXE with the proper parameters.<br /><br />This tool can make it easier to move reports, datasources, and resources from a development server to production. And the best part is that it builds and underlying script that can be reexecuted multiple times.<br /><br />It's also a great way to learn how to code some of the Reporting Services web service methods. <br /><br />Thank you DK for the reference.]]></content:encoded></rss:item><rss:item rdf:about="http://blogs.interfacett.com/jeff-jones-blog/2006/11/2/sql-server-2005-partitioning-script.html"><rss:title>SQL Server 2005 Partitioning Script</rss:title><rss:link>http://blogs.interfacett.com/jeff-jones-blog/2006/11/2/sql-server-2005-partitioning-script.html</rss:link><dc:creator>Jeff Jones</dc:creator><dc:date>2006-11-02T22:43:06Z</dc:date><dc:subject>SQL Server 2005</dc:subject><content:encoded><![CDATA[<p>In my SQL Server 2005 DBA Upgrade class I demonstrated the use of the new partitioning feature with a rolling range scenario. The rolling range scenario that I used keeps 6 months of orders and order detail data. The tables are partitioned based on orderdate where each partition holds one month of data. When a new month of data is added to the table, the oldest month of data is dropped out. <br /><br />The power of partitioning comes from the ability to manipulate large chunks of data in an even larger table with only metadata operations. These metadata operations are very fast. The old data can be switched out in a second. Then after loading the new months data into the proper filegroup, it can be switched into the larger multi-month table in a second. <br /><br />The script that I used to demonstrate partitioning is included <a href="http://jbjgroup.com/files/partitioning.zip"><font style="color: #bb3300" color="#bb3300"><strong>HERE</strong>. </font></a><br /><br />This script demonstrates both Left and Right based partitioning functions.</p>]]></content:encoded></rss:item></rdf:RDF>