DBPedias

Your Database Knowledge Community

Bob Horkay

  1. Parse XML in a Report

    Parsing an XML Node in a SQL Server Reporting services report.

    Nothing more fun than having to parse XML in a report. 

    It is basically the following steps:

    - modify the query in the dataset to include the XML column

    - In the Report Properties (from the report menu pad)

       * Add a Reference to System.XML

       * Paste the code from the attached txt file in Code section (this code is specific to the XML that I was parsing, but the concept could be modified or enhanced as needed based on your requirements)

    - Add a column to the report for what you are getting from the XML (notes in my case) and set the textbox Expression to =Code.ParseXML(Fields!{column here no brackets}.Value)

    Below is the code to paste into the code section

    Function ParseXML (ByVal xmlText as String) AS String
    Dim i as Integer
    Dim ret as String
    Dim xmlDoc As New System.Xml.XmlDocument
    Dim nodeList As System.Xml.XmlNodeList
    Dim node As System.Xml.XmlNode

    Try
    xmlDoc.LoadXml(xmlText)
    nodeList = xmlDoc.GetElementsByTagName("fd")

    ' Loop through the nodelist returned by the "fd" query (should be only 1)
    For Each node In nodeList
    ' Loop through all the child nodes of "fd" and format the key-value
      For i = 0 to node.ChildNodes.Count - 1
          ret = ret & node.ChildNodes.Item(i).InnerText & vbCrLf
      Next
    Next

    'If the DB is Null this sets the value to "N/A" instead of #Error
    Catch ex As Exception
      ret = "N/A"
      Return ret
    End Try

    'Format as date and time if it's an ETA
    Try
    Dim dt as DateTime
      dt = DateTime.parse(ret)
      ret = "ETA: " & Format(dt, "General Date")
    Catch ex As Exception
    End Try

    Return ret

    End Function


    While working on this I found a new XML Editor, I have no idea if it works, but I like it, "the interface is plain and convenient"!

     

    Parsing an XML Node in a SQL Server Reporting services report.

    Nothing more fun than having to parse XML in a report. 

    It is basically the following steps:

    - modify the query in the dataset to include the XML column

    - In the Report Properties (from the report menu pad)

       * Add a Reference to System.XML

       * Paste the code from the attached txt file in Code section (this code is specific to the XML that I was parsing, but the concept could be modified or enhanced as needed based on your requirements)

    - Add a column to the report for what you are getting from the XML (notes in my case) and set the textbox Expression to =Code.ParseXML(Fields!{column here no brackets}.Value)

    Below is the code to paste into the code section

    Function ParseXML (ByVal xmlText as String) AS String
    Dim i as Integer
    Dim ret as String
    Dim xmlDoc As New System.Xml.XmlDocument
    Dim nodeList As System.Xml.XmlNodeList
    Dim node As System.Xml.XmlNode

    Try
    xmlDoc.LoadXml(xmlText)
    nodeList = xmlDoc.GetElementsByTagName("fd")

    ' Loop through the nodelist returned by the "fd" query (should be only 1)
    For Each node In nodeList
    ' Loop through all the child nodes of "fd" and format the key-value
      For i = 0 to node.ChildNodes.Count - 1
          ret = ret & node.ChildNodes.Item(i).InnerText & vbCrLf
      Next
    Next

    'If the DB is Null this sets the value to "N/A" instead of #Error
    Catch ex As Exception
      ret = "N/A"
      Return ret
    End Try

    'Format as date and time if it's an ETA
    Try
    Dim dt as DateTime
      dt = DateTime.parse(ret)
      ret = "ETA: " & Format(dt, "General Date")
    Catch ex As Exception
    End Try

    Return ret

    End Function


    While working on this I found a new XML Editor, I have no idea if it works, but I like it, "the interface is plain and convenient"!

     

  2. Unhandled Exception

    This is nothing users dislike more than an Unhandled Exception, an I agree.

    SQL Server Management Studio (SSMS) Express 2008 (patched with SP3), recently began giving this error to a user of mine, every time they clicked on the "New Query" button.  "Microsoft .NET Framework"  Unhandled Exception has occured in a component in your application.


    ************** Exception Text **************
    System.NullReferenceException: Object reference not set to an instance of an object.
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellCodeWindowControl.CreateCWWindow()
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellCodeWindowControl.OnHandleCreated(EventArgs a)
       at System.Windows.Forms.Control.WmCreate(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellTextEditorControl.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


    ************** Loaded Assemblies **************

    The user recently received from patches for Visual Studio 2010 and then things stopped working.

    Basically the user was using SSMS express.  I Unininstalled SSMS Express 2008 (and the SQLExpress instance) and installed SQL Server Developer Edition 2008.  In the process of installing developer edition, the installation was aborted due to missing Visual Studio 2008 SP1.  I applied Visual Studio 2008 sp1 and then restarted the installation of developer edition, the install was successful.  The user was able to open SSMS and launch a new query window without error.  I wonder if applying VS 2008 SP1 would have corrected the original error, but at the point I realized VS 2008 sp 1 was missing, I had already installed SSMS Express 2008.

    I hope to never see this error again, but I've been trouble shooting many issues related to having Visual Studio 2005, 2008, 2010 and SQL Server 2005,2008, 2008r2.   I can't even imagine throwing sql 2012 into the mix, but I guess it's coming....prepare for more compatability issues.

    This is nothing users dislike more than an Unhandled Exception, an I agree.

    SQL Server Management Studio (SSMS) Express 2008 (patched with SP3), recently began giving this error to a user of mine, every time they clicked on the "New Query" button.  "Microsoft .NET Framework"  Unhandled Exception has occured in a component in your application.


    ************** Exception Text **************
    System.NullReferenceException: Object reference not set to an instance of an object.
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellCodeWindowControl.CreateCWWindow()
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellCodeWindowControl.OnHandleCreated(EventArgs a)
       at System.Windows.Forms.Control.WmCreate(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at Microsoft.SqlServer.Management.UI.VSIntegration.ShellTextEditorControl.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


    ************** Loaded Assemblies **************

    The user recently received from patches for Visual Studio 2010 and then things stopped working.

    Basically the user was using SSMS express.  I Unininstalled SSMS Express 2008 (and the SQLExpress instance) and installed SQL Server Developer Edition 2008.  In the process of installing developer edition, the installation was aborted due to missing Visual Studio 2008 SP1.  I applied Visual Studio 2008 sp1 and then restarted the installation of developer edition, the install was successful.  The user was able to open SSMS and launch a new query window without error.  I wonder if applying VS 2008 SP1 would have corrected the original error, but at the point I realized VS 2008 sp 1 was missing, I had already installed SSMS Express 2008.

    I hope to never see this error again, but I've been trouble shooting many issues related to having Visual Studio 2005, 2008, 2010 and SQL Server 2005,2008, 2008r2.   I can't even imagine throwing sql 2012 into the mix, but I guess it's coming....prepare for more compatability issues.

  3. Hotfix

    I must be forthright, I've dedicated far too much mental energy to a full consideration of Germanic Goddess Jordan Carver as we move closer to Oktoberfest.

    This has caused me to be slack in my duties of continuously patching sql server.  I had decided to "sit and wait" while SP3 for SQL 2008 finished it's CTP and not apply any more cumulative updates.

    Of course that has now caused me to be burned by two bugs, both of which are patched in either a Hotfix or a cumulative update.

    The first was a security patch for something with an XML Editor, I love when other people find my unpatched vulnerabilities in sql server, makes me feel really good.

    http://support.microsoft.com/kb/2494089

     

    http://technet.microsoft.com/en-us/security/bulletin/ms11-049

    The other was an issue with a Microsoft Cluster, the remote registry service kept stopping.  If you haven't noticed you can't connect to cluster administrator if this service is not running, and you can't remotely monitor Perfmon counters without this service.  Of course this is not a sql server problem, so I sent it to the engineers, the engineers were non too pleased and after much needling on my part they did begin to try and figure it out... they were nice enough to show me that sql server was causing this service to fail and that I did not have it patched to the correct level, argh, i love when an engineer points out that we don't have sql patched correctly and it's causing the service I put a ticket in for to crash.  Absolutely lovely. 

    >

    http://support.microsoft.com/kb/2159286

    Also be advised that without the remote registry service running, the sql server cumulative update will fail.  You can research the message endlessly or just start the remote registry service, set it to restart every time it fails and try again.  The exact error message is the following message:

    SQL Server Setup failure.
    ------------------------------

    SQL Server Setup has encountered the following error:

    Failed to retrieve data for this request..

     

  4. SQL Server Last date / time a password was changed

    I don't know why, but this simple request for SOX Compliance took me a while to find. There is a function that retrieves login properties, LOGINPROPERTY, duh! Of interest is the PasswordLastSetTime.

    It also has many other useful properties, see: http://msdn.microsoft.com/en-us/library/ms345412(v=SQL.100).aspx . It now becomes very easy to drop into any query, below is one of many sox queries we run that is now required to include this:


    SELECT --l.sid, loginname AS [Login Name], loginproperty(loginname,'PasswordLastSetTime') as PasswordLastSetTime, dbname AS [Default Database], CASE isntname WHEN 1 THEN 'AD Login' ELSE 'SQL Login' END AS [Login_Type], sl.is_disabled, sl.is_policy_checked, sl.is_expiration_checked, CASE WHEN isntgroup = 1 THEN 'AD Group' WHEN isntuser = 1 THEN 'AD User' ELSE '' END AS [AD Login Type], CASE sysadmin WHEN 1 THEN 'Yes' ELSE 'No' END AS [sysadmin], CASE [securityadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [securityadmin], CASE [serveradmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [serveradmin], CASE [setupadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [setupadmin], CASE [processadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [processadmin], CASE [diskadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [diskadmin], CASE [dbcreator] WHEN 1 THEN 'Yes' ELSE 'No' END AS [dbcreator], CASE [bulkadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [bulkadmin] FROM master.dbo.syslogins l left outer join sys.sql_logins sl on l.sid = sl.sid ORDER BY[Login Name], [Login_Type], [AD Login Type]

    I don't know why, but this simple request for SOX Compliance took me a while to find. There is a function that retrieves login properties, LOGINPROPERTY, duh! Of interest is the PasswordLastSetTime.

    It also has many other useful properties, see: http://msdn.microsoft.com/en-us/library/ms345412(v=SQL.100).aspx . It now becomes very easy to drop into any query, below is one of many sox queries we run that is now required to include this:


    SELECT --l.sid, loginname AS [Login Name], loginproperty(loginname,'PasswordLastSetTime') as PasswordLastSetTime, dbname AS [Default Database], CASE isntname WHEN 1 THEN 'AD Login' ELSE 'SQL Login' END AS [Login_Type], sl.is_disabled, sl.is_policy_checked, sl.is_expiration_checked, CASE WHEN isntgroup = 1 THEN 'AD Group' WHEN isntuser = 1 THEN 'AD User' ELSE '' END AS [AD Login Type], CASE sysadmin WHEN 1 THEN 'Yes' ELSE 'No' END AS [sysadmin], CASE [securityadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [securityadmin], CASE [serveradmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [serveradmin], CASE [setupadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [setupadmin], CASE [processadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [processadmin], CASE [diskadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [diskadmin], CASE [dbcreator] WHEN 1 THEN 'Yes' ELSE 'No' END AS [dbcreator], CASE [bulkadmin] WHEN 1 THEN 'Yes' ELSE 'No' END AS [bulkadmin] FROM master.dbo.syslogins l left outer join sys.sql_logins sl on l.sid = sl.sid ORDER BY[Login Name], [Login_Type], [AD Login Type]
  5. SQL Server Cluster Changing Port Number

    changing the port number for a sql server cluster should be a pretty straight forward task.  Most Clustered sql servers will be mission critical, hence the clustering; this also means it will be properly secured behind a firewall.  This means you will need to run the SQL Server instance on a static port.  In some instances you can not choose the port that SQL chooses for you.  In these instances you will need to change the port number for SQL Server.

    There are several resources out there on how to do this (why Microsoft didn't make choosing this as part of the install, or an option in cluster manager ), but all of them referenced using a command line program "Cluster Res", unfortunately this errors out on Windows 2008 R2 and SQL 2008 (r2 as well), with a "can not find the file specified".

    For Windows 2008 R2 and SQL 2008 you need to run "Cluster . Resource" from the command line.

    The basic directions are:

    1.  Take the SQL Server instance off line.

    2.  cluster . resource "SQL Server (<InstanceName>)" /removecheckpoints:"HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\MSSQL.x\MSSQLSERVER"

    3.  Open SQL Server Configuration Manager (ensure to "Run as Administrator"), Make the appropriate changes.

    4.  cluster . resource "SQL Server (<InstanceName>)" /addcheckpoints:"HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\MSSQL.x\MSSQLSERVER"

    5.  Bring the SQL Server Instance back on line

    6.  Verify in the sql server error log that the instance is using the correct port.

    Easy stuff, that Microsoft should have made easier.

    How to change SQL Server parameters in a clustered environment when SQL Server is not online (http://support.microsoft.com/kb/953504)

    http://sqlserverpedia.com/blog/sql-server-bloggers/sql-server-configuration-time-bombs/

  6. SQL Server Encryption for Express or Standard

    SQL Server Encryption for Express or Standard

    Security is the game that needs to be played to make management think they are taking adequate steps to safe guard data.  Ask Sony if this appropriate.

    I've recently been asked to provide encryption for a sql server express database implementation.  There is much written about sql server's encryption features, but you don't see many details about how to do it for real in an application.  Of course the standard replies about Tabular Data Encryption (TDE) are not available in any edition of SQL Server, except enterprise, so this methodology I am laying out here works for Express, Standard or Work Group.

    The goal was to provide a standard guidance for developing applications that require encryption, and also it should work for legacy applications with as few changes as possible (Oh, that's a beauty).

    What I came up with was an encryption architecture that pulls from things I learned from:
    - Protegrity (a security vendor, appliance)
    - Expert SQL Server 2008 Encryption by Michael Coles and J. Luetkehoelter
    - Database Encryption and Key Management for Microsoft SQL Server 2008: Understanding cell-level encryption and Transparent Data Encryption in Microsoft by Rob Walters and Christian Kirsch

    [Damn, now that's a title for a book, they should have chosen "The Rats of SQL" or something just to make it interesting!]

    Here it is, comments and suggestions are welcomed as often there are just too many bull shit blog posts on encryption; giving simple regurgitated examples from books on line.  That's crap, working with encryption for real in your application does not need to be nightmare, you do not need to fork over 20K+ a socket for enterprise edition [well, you might!!], you do not need to re-write your whole application, performance may suck, but that's not the point of this guidance....
    -----------------------

    Encryption is bad, but so is Cicada flavored ice cream.

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

    SQL Server Express Database Encryption

     

    The goal of encrypting data in the database engine is to protect data at rest (including backups) at the column (cell) level.  It does not protect data during transit over the network or from users who have the appropriate permissions and/or passwords.

     

    The approach outlined here is only for the field database engine, it is targeted for SQL Server Express 2008, small databases with limited number of users; this solution is not designed for highly scalable OLTP databases.

     

    The goal of the encryption process is to abstract the tables with cell level encryption by over-laying them with views.  This allows the application (with the proper permissions) to continue to work with the encrypted data seamlessly via the normal development methodologies without having to consistently write the code to decrypt / encrypt the columns (cells).  This process is the generally the same for new applications and existing applications that need to be modified to encrypt data with the key difference being the requirement to open the keys for new applications to provide additional security.

     

    The SQL Server encryption functions return varbinary data, so all columns to be encrypted need to be changed to varbinary.  The use of Views to over-lay the tables provides an abstraction layer so the data types can be properly viewed for data modelers, developers, administrators, analysts and other end users.  To encrypt a SSN, varchar(9) field requires the column in the base table to be implemented as varbinary(200).  The data modeling group creates a logical model subject area in Erwin that uses the views and other non-encrypted tables to create a data model that is useable (not displaying varbinary as the data type for encrypted fields, but their actual un-encrypted data type).

     

    Users that access the views, who do not have permissions to open the proper key(s) will not receive an error, but the column will not be decrypted and will be populated with nulls.

     

    Database developers will need to work closely with the data modeling team and the administrators to ensure the data types, views, encryption keys, backup and restore of keys are implemented properly.  Data is not recoverable if the backup of keys and databases are not implemented properly.

     

    Guidelines for implementing cell level encryption.

     

    All tables that include an encrypted cell (column) follow the normal standard naming conventions with the addition of an underscore and the word base to the table name {tablename}_base.  All columns follow the standard implementation with the exception of those to be encrypted, which must use a varbinary data type.  The length of the varbinary column is determined by the max length returned from the encryption function.  Please work the data modeler and the administrators to determine the proper length based on the requirements for each column.

     

    A view is created that follows the normal standards, except the name is implemented off the base table by dropping the underscore and the word base that was used to name the table (this allows legacy code to continue to work).  The view will make use of the decryption function and the proper Cast and Convert statements to manipulate the varbinary column to the correct un-encrypted data type.

     

    Inserts, updates and deletes are handled in the normal manner, with the tsql statements being executed against the view, NOT the underlying tables.  “Instead of Triggers” are created on each view to handle the Inserts, updates and deletes.  This provides an additional layer of abstraction so that consistency can be maintained with the code.

     

    All data access should continue according to the published standards (generally this is through stored procedures), refer to the Database governance document for details.

     

    The ability to truncate a table is not available on views (by design), or on base tables according to our standard development methodologies, use the stored procedure truncate_tbl, the procedure will determine if it is a view and truncate the underlying table.

     

    Text and Blob columns are not explicitely covered by this guidance, blob and text columns must be encrypted using CLR functions or by the application.  A more detailed example encrypting blobs will be published later.  (Be especially careful of free form text columns, end users often put PII data elements in these, thus requiring them to be encrypted).

     

    A short tsql script example:

       

     

    Create database encrypt_test;

    go

     

    use encrypt_test;

    go

     

    Create master key encryption by password = 'knights12$gzmlauncher#1@%dmissionisclear*()'

    go

     

    create certificate cert_sk with subject = 'Certificate for accessing symmteric keys - for use by App'

    go

     

    CREATE SYMMETRIC KEY sk_encrypt_test WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE cert_sk

    go

     

    ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY;

    go

     

    create table dbo.Client_Base

          ( client_Id int Identity(1,1) primary key,

                ssn varbinary(200),

                Amount_due varbinary(200),

                Comments varchar(1000)

          );

    go

     

    create view dbo.Client

    as

     

          Select Client_ID,

                convert(varchar(9),decryptbykeyautocert(cert_id('cert_sk'),

                      Null,SSN,1,convert(varchar(10),client_Id))) AS SSN,

                convert(money,convert(varchar(10),decryptbykeyautocert(cert_id('cert_sk'),

                      Null,Amount_Due,1,convert(varchar(10),client_Id)))) AS Amount_Due,

                Comments

          From dbo.Client_Base;

    go

     

    select * from dbo.client;

    go

     

    create trigger dbo.trg_client_insert

          on dbo.Client

    INSTEAD OF INSERT

    AS

          BEGIN

     

                Declare @Client_ID int, @SSN varchar(9), @Amount_Due money,

                      @Comments varchar(1000);

                     

                open SYMMETRIC key sk_encrypt_test decryption by certificate cert_sk;

     

                DECLARE cur_Client CURSOR FOR

                      SELECT      SSN,Amount_Due,Comments FROM INSERTED;

                OPEN cur_Client;

                FETCH NEXT FROM cur_Client INTO @SSN, @Amount_Due,@Comments;

                WHILE @@FETCH_STATUS = 0

                BEGIN

                      Insert into dbo.Client_Base (Comments) values (@Comments)

                      set @Client_Id = scope_identity()

                      Update dbo.Client_base

                            set SSN = encryptbykey(key_guid('sk_encrypt_test'),@SSN,1,Convert(varchar(10),@Client_ID))

                                  ,Amount_Due = encryptbykey(key_guid('sk_encrypt_test'),convert(varchar(10),@Amount_Due),1,Convert(varchar(10),Client_ID))

                            where Client_ID = @Client_ID

     

                FETCH NEXT FROM cur_Client INTO @SSN, @Amount_Due,@Comments

                END

                CLOSE cur_Client

                DEALLOCATE cur_Client        

     

                CLOSE SYMMETRIC key sk_encrypt_test

     

          END

    go

     

    create TRIGGER trg_Client_Update ON dbo.Client

    INSTEAD OF UPDATE

    AS

    BEGIN

     

          open SYMMETRIC key sk_encrypt_test decryption by certificate cert_sk

     

          Update Client_base

                Set SSN = encryptbykey(key_guid('sk_encrypt_test'),i.SSN,1,Convert(varchar(10),i.Client_ID))

                      ,Amount_Due = encryptbykey(key_guid('sk_encrypt_test'),convert(varchar(10),i.Amount_Due),1,Convert(varchar(10),i.Client_ID))

                FROM Client_Base

                inner join inserted i on Client_Base.Client_ID = i.Client_Id

     

          CLOSE SYMMETRIC key sk_encrypt_test

     

    END

    go

     

    create trigger dbo.trg_Client_Delete

          on dbo.Client

    INSTEAD OF DELETE

    AS

    BEGIN

          Delete Client_Base

          from Client_Base db

          inner join deleted d on db.Client_ID = d.Client_ID

    END

    go

     

    -- Stored procedures are written as normal

     

    Create procedure dbo.usp_Client_get_by_SSN

          @ssn varchar(9)

    As

    begin

          Select * from Client

                where ssn = @ssn

    end

     

     

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

    -- MUST OPEN KEY or all insert statements will FAIL

    OPEN MASTER KEY

    DECRYPTION BY PASSWORD = N'knights12$gzmlauncher#1@%dmissionisclear*()';

    GO

    Insert into dbo.client (ssn,amount_due,comments) values

          ('123456789',256.01,'This is a test of encryption')

    go

    select * from dbo.client;

    select * from dbo.client_base;

    go

     

    Update Client

          set ssn = 987654321,

                Amount_Due = 100

          where ssn = 123456789;

    go

     

    select * from Client;

    go

     

    Close Master Key;

    -- stored procedures work normally, though no data if key is not open

    exec dbo.usp_Client_get_by_ssn @SSN = 987654321

    -- now open key and data is returned.

    OPEN MASTER KEY

    DECRYPTION BY PASSWORD = N'knights12$gzmlauncher#1@%dmissionisclear*()';

    GO

    exec dbo.usp_Client_get_by_ssn @SSN = 987654321;

    go

     

    delete from client where SSN = 987654321

    go

     

    select * from Client;

    go

     

     

     

     


     

    >
  7. SQL Agent - cursor operation set options have changed

    SQL Agent - Could not complete cursor operation because the set options have changed since the cursor was declared. [SQLSTATE 42000] (Error 16958).

    Some how I've had this error before.  SQL Agent maintenance job with dynamic SQL in the job step fails with the above error. 

    I've had this on sql 2005 and sql 2008; for the most part I thought I'd never see this error again, but alas it keeps coming back.  This time the solution was to just remove the cursor from the dynamic SQL and use a temporary table.  Solutions in the past have been SP4 for sql 2005, sp2 for sql 2008; working on getting the set options right, all these are valid solutions, but none of them worked.  So this is what I had to do.

    In particular this script reindexes all user databases on a sql 2008 instance, where the compatability mode of the database is in 9.0.  We have a different step in the maintenance job for databases that are in 10.0 mode.

    Fun.

    StartReindex_90_compatability.txt (4.17 KB)

  8. Whats in the Index File Group and How Big

    I'm just going to decorate this post with a much more upbeat photo of Denise Milani in a captivating, top-heavy series of photographs in a Southwest desert setting. 

    Thinking of how big things are, I recently ran into an issue of an index file group growing pretty large, and I wanted to know which indexes were in it, and how big they were.  My biggest concern was non-clustered indexes that were changed to clustered indexes (causing the whole table to move into the index file group).

    I have previously found two great scripts, one that shows the size of an index and another that shows what is in a file group.  I combined these two together to get a complete picture of what I needed.

    Script for Indexes Size and What File Group they are in:

    Select FileGroup = FILEGROUP_NAME(a.data_space_id),index_listing.* from (
    Select
        s.[name] as [schema],
        Case
      When i.[name] is null
      Then o.[name]
      Else i.[name]
     end as name,
        i.type_desc,
        space_used_in_mb = (page_count * 8.0 / 1024.0),
        space_used_in_kb = (page_count * 8.0),
     i.object_id,i.index_id
    From
        sys.indexes I
    Inner Join
        sys.dm_db_index_physical_stats(db_id(), object_id('.'), null, null, null) P
      On I.[object_id] = P.[object_id]
      and I.[index_id] = P.[index_id]
    Inner Join
     sys.objects o
      on i.[object_id] = o.[object_id]
    Inner Join sys.schemas s
      on o.[schema_id] = s.[schema_id]
    ) index_listing
    INNER JOIN sys.partitions p on index_listing.object_id = p.object_id
     AND index_listing.index_id = p.index_id
    Left Join sys.allocation_units a ON a.container_id = CASE WHEN a.type in(1,3)
     THEN p.hobt_id ELSE p.partition_id END AND p.object_id > 1024
    --where FILEGROUP_NAME(a.data_space_id) = 'Index_data'
    -- and index_listing.type_desc = 'Clustered'
    Order by space_used_in_mb Desc

  9. Client Network Utility

    Always thought this wasn't available unless client tools were installed, but that is not correct.

    Found a great post here on the client network utility, http://www.mssqltips.com/tip.asp?tip=1620 but what surprised me was this part,

    "If you haven't installed the SQL Server 2005/2008 client tools, you can still create an alias using the SQL Server Client Network Utility. This has come installed automatically on every operating system from Windows 2000 on. To bring up the utility, click on Start, then Run, and run cliconfg.exe."

    No sense rehasing such a great tip, but at least I'll have a place holder on my blog for cliconfg.exe; especially for those pesky vendors that tell you they can use a named instance, but then after you do all the paper work to open the ports on the firewall wait for the monthly change window and then the vendor on site (at our expense).... "well we can use a name instance, but we can't specify a port number" !  doh !  They have to have the slash \ ; which i don't want to open port resolution with the firewall...

    Client network utility to the rescue;

    1.  Client network utility does not require sql client tools to be installed.

    2.  Just because sql client tools is not installed, does not mean an alias does not exist on a server.

     

  10. Windows 2008 R2, Needs hotfix for SQL Server 2008...

    During recent load testing of our larger sql server databases we ran into some performance issues.  After much research by Microsoft it turned out to be an OS issue, and required a patch.  We were running SQL Server 2008 on Windows 2008 R2.

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;979149 

    Our errors didn't show themselves exactly as the support document does, but we were seeing lots of sql timeout errors (which we did not see under sql 2005 and windows 2003 for the exact same tests). 

    The hotfix appears to have corrected the issues.

    The sql error logs contained lots of:

    Errors in connection pool - 2010-09-16 19:19:27,Error,2,18056,MSSQLSERVER,{removed}.{removed}.corp,"The client was unable to reuse a session with SPID 437, which had been reset for connection pooling. The failure ID is 29. This error may have been caused by an earlier operation failing. Check the error logs for failed operations immediately before this error message."

      So this a typical exception\timeout side effect. The failure id is important here – id is 29. State 29 occurs when there is an Attention received from the client while the Redo Login code is being executed. So as stated I have seen this associated with other more serious exceptions and way I dealt with it is by flushing connection pool on serious exception error handling (handling deadlock for instance). Flushing pool will have however serious performance effects in ADO.NET and cannot be recommended easily.

    If the above error message (note that the state number should reflect 29) is the only message in the SQL Server Errorlog along with no other errors noticed in the environment (connectivity failures to the SQL instance in question, degraded performance, high CPU usage, Out of Memory errors), then this message can be treated as benign and safely ignored.

      ·         Errors on login, perhaps real cause of Redo Login and therefore error above - 2010-09-16 19:19:27,Failure Audit,4,18456,MSSQLSERVER,{removed}.{removed}.corp,Login failed for user '{removed}'. Reason: Failed to open the database configured in the login object while revalidating the login on the connection. [CLIENT: {removed ip}]

      ·         2010-09-16 19:19:27,Error,2,10982,MSSQLSERVER,{removed}.{removed}.corp,Failed to run resource governor classifier user-defined function. See previous errors in SQL Server error log from session ID 2185 for details.  Classifier elapsed time: 1 ms.

  1. 1
  2. Next ›
  3. Last »