Wednesday, March 20, 2013

SQLServer: Arithmetic overflow error converting IDENTITY to data type smallint

Keep a check on your IDENTITY columns in SQL Server

The IDENTITY columns, or 'auto number' columns as some people call them, are auto incrementing columns provided by SQL Server. There can only be one IDENTITY column per table. You just have to provide a base value, and an increment value, and SQL Server will take care of incrementing this column automatically. Some people like these, and some don't, but the truth is, IDENTITY columns are gaining popularity, and many production systems, including critical ones are using IDENTITY columns these days. So, it is important to keep an eye on these columns, to make sure they are not reaching the limit of their base data type. For example, if you created an IDENTITY column of smallint datatype, its values can go upto 32767. If you try to insert anymore rows, you will get the following error:

Server: Msg 8115, Level 16, State 1, Line 1
Arithmetic overflow error converting IDENTITY to data type smallint.
Arithmetic overflow occurred.

If this table happens to be a part of a critical production system, then you are in trouble. You will have to do something about it to resolve it. If the data from this table can be deleted, then delete the data using TRUNCATE TABLE command. TRUNCATE TABLE resets the IDENTITY column to its base value. The DELETE command doesn't do this. But then, if this table is referenced by a foreign key, then TRUNCATE TABLE is not allowed on this table. Your other option is to run DBCC CHECKIDENT on your table with RESEED option.

An IDENTITY column of tinyint datatype can go upto 255, smallint can go upto 32767, int can go upto 2147483647 and bigint can go upto 9223372036854775807.

You can proactively monitor these IDENTITY columns, to avoid getting into such problems. If you can see in advance, that an IDENTITY column is reaching its limit, then you could do something about it, before it reaches the limit. The other day, one of my friends was trying to automate a process that checks all the IDENTITY columns in a database and reports on how far away those columns are from the limit. He was using a cursor to go through all the tables in the database, and running a "SELECT MAX(IdentityCol) FROM TableName" on all the tables that have an IDENTITY column. It would take ages to run on a database with many big tables. It can be simplified into one simple query using IDENT_CURRENT function. That's what I did, and thought it will be useful for other DBAs as well. So, here I am writing about it.

There are three different versions of this procedure. First one is for SQL Server 2005. The second and third versions work in SQL Server 2000. You will have to create this procedure in the database of your interest. And run it as shown below:

EXEC dbo.CheckIdentities
GO

This procedure below, displays information about all IDENTITY columns in the database, and shows you the percentage of IDENTITY values already used. If you are seeing any IDENTITY columns that have used up 80% or more values, then you need to start thinking about it. You could customise this procedure to automatically email you or log an error if there are any IDENTITY columns that are nearing the limit. You could also schedule this procedure as an SQL Agent job, so that it checks these columns regularly. Any new IDENTITY columns added to the database will automatically get picked up by this query.

A quick note about 64 bit SQL Server. Even though SQL Server 64 bit editions can access a lot more memory inherently, than the 32 bit systems could - the IDENTITY columns are still limited to the limits imposed by the base datatypes. I'm writing this because, someone recently asked me if int data type can store a higher number in 64 bit server, compared to a 32 bit server.

Here's a screen shot of output from the AdventureWorks sample database in SQL Server 2005.


/* The SQL Server 2005 version of the stored procedure. It uses new catalog views */


CREATE PROC dbo.CheckIdentities
AS
BEGIN
 SET NOCOUNT ON

 SELECT QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' +  QUOTENAME(t.name) AS TableName, 
  c.name AS ColumnName,
  CASE c.system_type_id
   WHEN 127 THEN 'bigint'
   WHEN 56 THEN 'int'
   WHEN 52 THEN 'smallint'
   WHEN 48 THEN 'tinyint'
  END AS 'DataType',
  IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) AS CurrentIdentityValue,
  CASE c.system_type_id
   WHEN 127 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 9223372036854775807
   WHEN 56 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 2147483647
   WHEN 52 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 32767
   WHEN 48 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 255
  END AS 'PercentageUsed' 
 FROM sys.columns AS c 
  INNER JOIN
  sys.tables AS t 
  ON t.[object_id] = c.[object_id]
 WHERE c.is_identity = 1
 ORDER BY PercentageUsed DESC
END



If you try to create the above stored procedure in SQL Server 2000, you will get the following error:

Server: Msg 195, Level 15, State 10, Procedure a, Line 4
'SCHEMA_NAME' is not a recognized function name.

So, here are some SQL Server 2000 compatible versions.


/* The SQL Server 2000 version of the stored procedure. Uses system tables. This should work in SQL Server 7.0 too */


CREATE PROC dbo.CheckIdentities
AS
BEGIN
 SET NOCOUNT ON

 SELECT QUOTENAME(USER_NAME(t.uid))+ '.' +  QUOTENAME(t.name) AS TableName, 
  c.name AS ColumnName,
  CASE c.xtype
   WHEN 127 THEN 'bigint'
   WHEN 56 THEN 'int'
   WHEN 52 THEN 'smallint'
   WHEN 48 THEN 'tinyint'
  END AS 'DataType',
  IDENT_CURRENT(USER_NAME(t.uid)  + '.' + t.name) AS CurrentIdentityValue,
  CASE c.xtype
   WHEN 127 THEN (IDENT_CURRENT(USER_NAME(t.uid)  + '.' + t.name) * 100.) / 9223372036854775807
   WHEN 56 THEN (IDENT_CURRENT(USER_NAME(t.uid)  + '.' + t.name) * 100.) / 2147483647
   WHEN 52 THEN (IDENT_CURRENT(USER_NAME(t.uid)  + '.' + t.name) * 100.) / 32767
   WHEN 48 THEN (IDENT_CURRENT(USER_NAME(t.uid)  + '.' + t.name) * 100.) / 255
  END AS 'PercentageUsed' 
 FROM syscolumns AS c 
  INNER JOIN
  sysobjects AS t 
  ON t.id = c.id
 WHERE COLUMNPROPERTY(t.id, c.name, 'isIdentity') = 1
 AND OBJECTPROPERTY(t.id, 'isTable') = 1
 ORDER BY PercentageUsed DESC
END



/* The SQL Server 2000 version of the stored procedure. Uses INFORMATION_SCHEMA views. */


CREATE PROC dbo.CheckIdentities
AS
BEGIN
 SET NOCOUNT ON

 SELECT QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME)  AS TableName, 
  c.COLUMN_NAME AS ColumnName,
  c.DATA_TYPE AS 'DataType',
  IDENT_CURRENT(t.TABLE_SCHEMA  + '.' + t.TABLE_NAME) AS CurrentIdentityValue,
  CASE c.DATA_TYPE
   WHEN 'bigint' THEN (IDENT_CURRENT(t.TABLE_SCHEMA  + '.' + t.TABLE_NAME) * 100.) / 9223372036854775807
   WHEN 'int' THEN (IDENT_CURRENT(t.TABLE_SCHEMA  + '.' + t.TABLE_NAME) * 100.) / 2147483647
   WHEN 'smallint' THEN (IDENT_CURRENT(t.TABLE_SCHEMA  + '.' + t.TABLE_NAME) * 100.) / 32767
   WHEN 'tinyint' THEN (IDENT_CURRENT(t.TABLE_SCHEMA  + '.' + t.TABLE_NAME) * 100.) / 255
  END AS 'PercentageUsed' 
 FROM INFORMATION_SCHEMA.COLUMNS AS c 
  INNER JOIN
  INFORMATION_SCHEMA.TABLES AS t 
  ON c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME
 WHERE COLUMNPROPERTY(OBJECT_ID(t.TABLE_SCHEMA + '.' + t.TABLE_NAME), c.COLUMN_NAME, 'isIdentity') = 1
 AND c.DATA_TYPE IN ('bigint', 'int', 'smallint', 'tinyint')
 AND t.TABLE_TYPE = 'BASE TABLE'
 ORDER BY PercentageUsed DESC
END


Monday, December 31, 2012

TF30172: You do not have permission to create a new project.

TFS 2012 and Visual Studio 2010 have compatibility issues.
I recently installed TFS 2012 RC and able to create a Team Project Collection successfully. Then I Opened my 2010 visual studio to create team project, but I keep getting error message “TF30172: You do not have permission to create a new project.”. Then I went to double check my permission setting and I was a part of the Project Collection Administrators group. So naturally I should have enough privilege to create a new project.


 
Install the Visual Studio 2012 RC and Team explorer 2012 after that you will be able to create and delete a team project in VS 2012 RC with the same user account and privilege.

Friday, December 28, 2012

IIS - This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms

IIS - This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms

Have you ever got the "This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms." exception while trying to use some of the classes in the "System.Security.Cryptography" namespace?
The exception normally thrown is a "TargetInvocationException" exception and the message that accompanies it is usually the unhelpful "Exception has been thrown by the target of an invocation". It is only when you drill down into the InnerException that you see the "This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms." message. The reason that this exception is thrown is that you have tried to use a cryptographic algorithm that is not FIPS compliant.
What is FIPS compliance? FIPS stands for Federal Information Processing Standards. (link to more information) and are US Government standards that provide a benchmark for implementing cryptographic software.
WindowsXP and later operating systems have both FIPS compliant and non-compliant algorithms that can be used by developers. FIPS compliant algorithms are those that have been validated by the FIPS 140 program. One can call both the compliant and non-compliant algorithms as the check for FIPS compliance is by default turned off.

How do you turn on and off FIPS compliance checking:
Two methods:
1. Go to Control Panel -> Administrative Tools -> Local Security Policy
Enable the setting for "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing"
6jf244.tmp
2. Another method is to directly edit the registry by setting the following value to 0 (disable) or 1 (enable)
HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy
Alternatively you can copy the following lines into a registry script file (.reg) and run it.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"fipsalgorithmpolicy"=dword:00000001
Note: One thing that I am not certain off is that this option might be available only on Windows XP Professional OSs and not in the basic Windows XP OS. I havent been able to confirm this via documentation - but the option is not available on my home machine (Windows XP), but is available on my work machine (Windows XP Pro).


For Developers:
So what does this mean for developers? If you ever envision your software running on a government computer (especially in the US), you should turn on FIPS compliance checking. This way, your application that uses cryptography algorithms provided by the OS will work on all machines and you wont have to deal with the "Exception has been thrown by the target of an invocation".
For .NET Developers:
FIPS compliance checking (if turned on in the local security policy) I think was introduced starting in version 2.0 of .NET. Unfortunately, the MSDN documentation on FIPS compliance is pretty skimpy and there is no list of the algorithms in the "System.Security.Cryptography" namespace that are FIPS compliant. (Also there is no property that can be checked or an interface or base class that FIPS compliant algorithms implement - which would allow for runtime checking - hint, hint MS).
So here is a quick list that I obtained by using reflection (C# code is below)
FIPS compliant Algorithms:
Hash algorithms
HMACSHA1
MACTripleDES
SHA1CryptoServiceProvider
Symmetric algorithms (use the same key for encryption and decryption)
DESCryptoServiceProvider
TripleDESCryptoServiceProvider
Asymmetric algorithms (use a public key for encryption and a private key for decryption)
DSACryptoServiceProvider
RSACryptoServiceProvider
Algorithms that are not FIPS compliant
HMACMD5
HMACRIPEMD160
HMACSHA256
HMACSHA384
HMACSHA512
MD5CryptoServiceProvider
RC2CryptoServiceProvider
RijndaelManaged
RIPEMD160Managed
SHA1Managed

 

Monday, July 16, 2012

Copy Microsoft.ReportViewer.ProcessingObjectModel.dll from GAC

Scenarios:
-If you get the following errors:
Could not load file or assembly Microsoft.ReportViewer.Common
Could not load file or assembly Microsoft.ReportViewer. ProcessingObjectModel

You can follow the following steps to copy it from GAC (Global Assembly cache):

COPY Microsoft.ReportViewer.ProcessingObjectModel
1. Open a command prompt (select Start/Run and then enter "cmd" and press enter).

2. Type the following command and press enter:

cd C:\WINDOWS\assembly\GAC_MSIL\Microsoft.ReportViewer.ProcessingObjectModel

2 (i) Type 'dir' and press 'enter'. You would be able to see the following folder:
It depends on which version you have on your system. It can be either 8.0.0.0 OR 9.0.0.0.

8.0.0.0__b03f5f7f11d50a3a
OR
9.0.0.0__b03f5f7f11d50a3a


2(ii). Type "cd 8.0.0.0__b03f5f7f11d50a3a" if you have 8.0.0.0 version OR
"cd 9.0.0.0__b03f5f7f11d50a3a" if you have 9.0.0.0 and press 'enter'.

2(iii). You should be able to see the following DLL in this folder:
Microsoft.ReportViewer.ProcessingObjectModel.dll


2(iv). Now use the following command to copy the dll file to your bin directory:
copy *.dll d:\YourProject\bin



3. COPY Microsoft.ReportViewer.Common
cd C:\WINDOWS\assembly\GAC_MSIL\Microsoft.ReportViewer.Common

3 (i) Type 'dir' and press 'enter'. You would be able to see the following folder:
It depends on which version you have on your system. It can be either 8.0.0.0 OR 9.0.0.0.

8.0.0.0__b03f5f7f11d50a3a
OR
9.0.0.0__b03f5f7f11d50a3a


3(ii). Type "cd 8.0.0.0__b03f5f7f11d50a3a" if you have 8.0.0.0 version in step 3 OR
"cd 9.0.0.0__b03f5f7f11d50a3a" if you have 9.0.0.0 and press 'enter'.

3(iii). You should be able to see the following DLL in this folder:
Microsoft.ReportViewer.Common.dll


3(iv). Now use the following command to copy the dll file to your bin directory:
copy *.dll d:\YourProject\bin

Friday, November 25, 2011

SoapException: Server was unable to process request. Access denied

Server was unable to process request. Access denied


System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.UnauthorizedAccessException: Access to the path 'E:\XYZ\' is denied.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
   at System.IO.StreamWriter..ctor(String path)
  
   --- End of inner exception stack trace ---

Soln:

I recently had a problem that sounds similar. I had a program which was
trying to access "C:\XYZPath\", and got an access denied error.

This was because it only had the path, but no filename. It was, in effect,
trying to access the folder as though it were a file. This was just a matter
of a bad exception thrown by .NET. The real exception was that I was missing
the file name.

Thursday, November 10, 2011

HTTP Error 404.13 - Not Found : The request filtering module is configured to deny a request that exceeds the request content length


I was developing an application that allows user to upload files to the server using the <asp:FileUpload/> control. In order to make sure that users can upload large files, I configured the web.config as follows to allow larger files to be uploaded (The default setting is 4 MB):

<httpRuntime maxRequestLength="512000"/><!--To allow up to 500MB-->
?
While testing the file upload functionality from within the visual studio development server (Right clicking on the aspx file and selecting browse), I found it working quite fine. But surprisingly, after hosting the Asp.net web site onto IIS (IIS 7), I found the file uploading functionality was no longer working, and, it was broken while trying to upload large files (I was trying with a file over 40MB in size). Following is the screen shot of the error message that I got:



Figure : The error message from IIS while trying to upload a large file

The error page also suggested me to do the followings:

"Verify the configuration/system.webServer/security/requestFiltering/requestLimits@maxAllowedContentLength setting in the applicationhost.config or web.config file."

So, as suggested, I did the following configuration in the web.config of my Asp.net web site(By setting maxAllowedContentLength value in Bytes):

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true"/>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="512000"></requestLimits>
    </requestFiltering>
  </security>


Guess what, it didn't work out! After modification when I tried to upload the file again, the same problem occured again. What happened?

According to the error message, the web.config or applicationhost.config should be configured according to the above suggestion. Modifying web.config didn't work out. So, the applicationhost.config could be modified to see what happens.

The applicationhost.config is the configuration file of IIS (IIS7.0 or heigher). Does that mean IIS has a Request size validation? 



Yes it has. Until IIS 7.0 there was no Request size validation, but since IIS 7.0, the Request length is verified by IIS first, before deliverying the Request to Asp.net.

So, to be true, it doesn't really make any sense to increase the maxAllowedContentLength value in web.config. The Request dies even before reaching the Asp.net. So, whatever is to be configured, it has to happen at IIS.

Well, as I figured out, there are two ways you can configure this value in IIS:

1. Configuring the applicationhost.config

Open the %WINDIR%\System32\inetsrv\config\applicationHist.config in editor and specify the following configuration within the security/requestFiltering section(By setting maxAllowedContentLength value in Bytes):

<requestFiltering>
      <requestLimits maxAllowedContentLength="512000000"></requestLimits>
</requestFiltering>

?
Note:

Modifying the above configuration worked for me in one PC (Running Windows 7+IIS 7.0), but, didn't work on another one (Running Windows Vista + IIS 7.0). After configuring the applicationHost.config file, I tried to upload the large file and the same error message was appearing again. I don't know why, but, if you have the same experience, applying the following approach (Configuring via IISManager) would definitely work.

2. Configuring via IISManager

Open the IIS Manager and select the site or application you need to configure in the left panel

Select "Features View" and double click on the "Request Filtering" icon.


Figure : Request Filtering

Note :

If you can't find the "Request Filtering"icon, you need to install the IIS Administration Pack from this link :http://www.iis.net/download/AdministrationPack. This is a lightweight installation which shouldn't take too much time on a decent internet speed.

Double clicking on the "Request Filtering"icon will bring up the Request filtering configuration window. Right click on the window and select the "Edit Feature Settings" option:




Figure : Edit Feature Settings option in IIS

Finally, specify the Maximum allowable content length (In Byte) in the following window and click "OK" to save:


Figure : Specifying Maximum allowable content length in Bytes

This worked perfect for me and I was able to upload the large file now without any problem. Hope, this will work for you too :)