Windows Azure Migration: Database Migration, Post 1

2. April 2011 18:14 by Mrojas in   //  Tags: , , , , , , , , , ,   //   Comments (0)

WheWhen you are doing an azure migration, one of the first thing you must do is
collect all the information you can about your database.
Also at some point in your migration process you might consider between migration to
SQL Azure or Azure Storage or Azure Tables.

Do do all the appropriate decisions you need to collect at least basic data like:

  • Database Size
  • Table Size
  • Row Size
  • User Defined Types or any other code that depends on the CLR
  • Extended Properties

Database Size

You can use a script like this to collect some general information:

create table #spaceused(
databasename varchar(255),
size varchar(255),
owner varchar(255),
dbid int,
created varchar(255),
status varchar(255),
level int)

insert #spaceused (databasename , size,owner,dbid,created,status, level)  exec sp_helpdb

select * from #spaceused for xml raw
drop table  #spaceused

When you run this script you will get an XML like:

<row databasename="master" 
size=" 33.69 MB" 
created="Apr 8 2003" 
status="Status=ONLINE, ..." 
<row databasename="msdb" 
size=" 50.50 MB" 
created="Oct 14 2005" 
status="Status=ONLINE, ..." 
<row databasename="mycooldb" 
size=" 180.94 MB" 
created="Apr 22 2010" 
status="Status=ONLINE, ..." 
<row databasename="cooldb" 
size=" 10.49 MB" 
created="Jul 22 2010" 
status="Status=ONLINE, ..." 
<row databasename="tempdb" 
size=" 398.44 MB" 
owner="sa" dbid="2" 
created="Feb 16 2011" 
status="Status=ONLINE, ..." 

And yes I know there are several other scripts that can give you more detailed information about your database
but this one answers simple questions like

Does my database fits in SQL Azure?
Which is an appropriate SQL Azure DB Size?

Also remember that SQL Azure is based on SQL Server 2008 (level 100).

80 = SQL Server 2000

90 = SQL Server 2005

100 = SQL Server 2008

If you are migrating from an older database (level 80 or 90) it might be necessary to upgrade first.

This post might be helpful:

Table Size

Table size is also important.There great script for that:

If you plan to migrate to Azure Storage there are certain constraints. For example consider looking at the number of columns:

You can use these scripts: (I just had to change the alter for create)

Row Size

I found this on a forum (thanks to Lee Dice and Michael Lee)

DECLARE @sql        VARCHAR (8000)
        , @tablename  VARCHAR (255)
        , @delim      VARCHAR (3)
        , @q          CHAR (1)

  SELECT @tablename = '{table name}'
       , @q         = CHAR (39)

  SELECT @delim = ''
       , @sql   = 'SELECT '

  SELECT @sql   = @sql
                + @delim
                + 'ISNULL(DATALENGTH ([' + name + ']),0)'
       , @delim = ' + '
  FROM   syscolumns
  WHERE  id = OBJECT_ID (@tablename)
  ORDER BY colid

  SELECT @sql = @sql + ' rowlength'
              + ' FROM [' + @tablename + ']'
       , @sql =  'SELECT MAX (rowlength)'
              + ' FROM (' + @sql + ') rowlengths'
  PRINT @sql
  EXEC (@sql)

Remember to change the {table name} for the name of the table you need

User Defined Types or any other code that depends on the CLR

Just look at your db scripts at determine if there are any CREATE TYPE statements with the assembly keyword.
Also determine if CLR is enabled with a query like:

select * from sys.configurations where name = 'clr enabled'

If this query has a column value = 1 then it is enabled.

Extended Properties

Look for calls to sp_addextendedproperty dropextendedproperty OBJECTPROPERTY and sys.extended_properties  in your scripts.

ORA-12154: TNS:could not resolve the connect identifier specified for application to oracle

18. November 2010 16:57 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

I had a Windows Server 2003 and I was trying to connect to Oracle with the System.Data.OracleClient provider.

I was able to connect from a console application but not from ASP.NET.
From ASP.NET I only got ORA-12154 errors.

I found that on Windows 2003 Server, ASP.NET applications run in the
security context of the “Network Service” user.

So I tried these two  things:

I first started following these steps:
1. Log on to Windows as a user with Administrator privileges.
2. Launch Windows Explorer from the Start Menu and and navigate to the
ORACLE_HOME folder. It is usually under the oracle instalation folder.
In my case that is C:\oracle\product\10.2.0\client_1
3. Right-click on the ORACLE_HOME folder and choose the "Properties" option
from the drop down list. A "Properties" window should appear.
4. Click on the "Security" tab of the "Properties" window.
5. Click on "Authenticated Users" item in the "Name" list (on Windows XP
the "Name" list is called "Group or user names").
6. Uncheck the "Read and Execute" box in the "Permissions" list under the
"Allow" column (on Windows XP the "Permissions" list is called
"Permissions for Authenticated Users").
7. Re-check the "Read and Execute" box under the "Allow" column (this is
the box you just unchecked).
8. Click the "Advanced" button and in the "Permission Entries" list make
sure you see the "Authenticated Users" listed there with:
Permission = Read & Execute
Apply To = This folder, subfolders and files
If this is NOT the case, edit that line and make sure the "Apply onto"
drop-down box is set to "This folder, subfolders and files". This
should already be set properly but it is important that you verify this.
9. Click the "Ok" button until you close out all of the security properties
windows. The cursor may present the hour glass for a few seconds as it
applies the permissions you just changed to all subfolders and files.
10. Reboot your computer to assure that these changes have taken effect.
(I thought that rebooting was not that important but it seems that you have to reboot to make changes effective)

It sometimes happens that it is not enough, because it seems that some oracle installations need the
the ASP.NET process to run with an account with sufficient privileges.

The second thing you can do in that case is.

1. First open the machine.config file. That will be usually in %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config

2. Look for something like:

    <processModel autoConfig="true" />

3. Add the userName=”System” attribute. For example

<processModel autoConfig="true" userName="System" />

4. Restart the IIS.

No more System.Data.OracleClient

7. August 2009 06:15 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

 Microsoft announced that they won’t support the System.Data.OracleClient anymore :(


The message says that it will still be available in .NET 4.0 but “deprecated” and that it wont impact existing applicatoions.


So what are my options?

Well you have to go to a third party. Not now but eventually.


Oracle Data Provider for .NET (ODP.NET) (Oracle states that ODP.NET is Free)

DataDirect ADO.NET Provider for Oracle

dotConnect for Oracle


Migration to ODP.NET


Microsoft OracleClient to ODP.NET Application Migration: Code Migration

Oracle provide general instructions. In summary you need to:

  1. Add the references to Oracle.DataAccess
  2. Change namespaces: System.Data.OracleClient by  Oracle.DataAccess.Client; and maybe add “using Oracle.DataAccess.Types”
  3. Update the connection String (most attributes are the same). Change Integrated Security by  "User Id=/", change “Server” attribute to “Data Source” and remove Unicode
  4. The following is anoying but you have to add after all OracleCommands something like OracleCommand1.BindByName = true;


  • Oracle Universal Installer (either in normal installation or Silent Install)
  • XCopy (I like this :) ) just remember to download the ODAC xcopy version

List Jobs in Oracle

21. May 2009 06:41 by Mrojas in General  //  Tags: ,   //   Comments (0)

If you have created any schedule jobs or you just need to see what jobs are available in a server you use the dba_jobs table.

The following links provides more details about this view:

Migrating RDS CreateRecordSet in .NET

19. June 2008 06:24 by Mrojas in General  //  Tags: , ,   //   Comments (0)

This is way a discused with a friend for migrating a VB6 RDS CreateRecordset


Private Function Foo(rs As ADOR.Recordset) As Boolean
    On Error GoTo Failed
    Dim ColumnInfo(0 To 1), c0(0 To 3), c1(0 To 3)
    Dim auxVar As RDS.DataControl
    Set auxVar = New RDS.DataControl
    ColInfo(0) = Array("Value", CInt(201), CInt(1024), True)
    ColInfo(1) = Array("Name", CInt(129), CInt(255), True)
    Set rs = auxVar.CreateRecordSet(ColumnInfo)
    Foo = True
    Exit Function
    Foo = False
    Exit Function
End Function


According to MSDN the CreateRecordset function takes a Varriant array with definitions for the columns. This definitions are made up of four parts

Attribute Description
Name Name of the column header.
Type Integer of the data type.
Size Integer of the width in characters, regardless of data type.
Nullability Boolean value.
Scale (Optional) This optional attribute defines the scale for numeric fields. If this value is not specified, numeric values will be truncated to a scale of three. Precision is not affected, but the number of digits following the decimal point will be truncated to three.

So if we are going to migrate to System.Data.DataColumn we will used a type translation like the following (for now I’m just putting some simple cases)

Length Constant Number DataColumn Type
Fixed adTinyInt 16 typeof(byte)
Fixed adSmallInt 2 typeof(short)
Fixed adInteger 3 typeof(int)
Fixed adBigInt 20  
Fixed adUnsignedTinyInt 17  
Fixed adUnsignedSmallInt 18  
Fixed adUnsignedInt 19  
Fixed adUnsignedBigInt 21  
Fixed adSingle 4  
Fixed adDouble 5  
Fixed adCurrency 6  
Fixed adDecimal 14  
Fixed adNumeric 131  
Fixed adBoolean 11  
Fixed adError 10  
Fixed adGuid 72 typeof(System.Guid)
Fixed adDate 7 Typeof(System.DateTime)
Fixed adDBDate 133  
Fixed adDBTime 134  
Fixed adDBTimestamp 135  
Variable adBSTR 8  
Variable adChar 129 typeof(string)
Variable adVarChar 200 typeof(string)
Variable adLongVarChar 201 typeof(string)
Variable adWChar 130  
Variable adVarWChar 202  
Variable adLongVarWChar 203  
Variable adBinary 128  
Variable adVarBinary 204  
Variable adLongVarBinary 205  
So the final code can be something like this: private bool Foo(DataSet rs)




DataColumn dtCol1 = new DataColumn("Value",typeof(string));
dtCol1.AllowDBNull = true;
dtCol1.MaxLength = 1024;

DataColumn dtCol2 = new DataColumn("Name",typeof(string));

dtCol2.AllowDBNull = true;
dtCol2.MaxLength = 255;
DataTable dt = rs.Tables.Add();



return true;




return false;





My friend Esteban also told my that I can use C# 3 syntax and write something even cooler like:

DataColumn dtCol1 = new DataColumn()


ColumnName = "Value",

DataType = typeof (string),

AllowDBNull = true,

MaxLength = 1024


Dataset save columns as Attributes

5. June 2008 11:07 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

This code is so handy that I'm posting it just to remember. I preffer to serialize my datasets as attributes instead of elements. And its just a matter of using a setting. See: 

Dim cnPubs As New SqlConnection("Data Source=<servername>;user id=<username>;" & _
"password=<password>;Initial Catalog=Pubs;")
Dim daAuthors As New SqlDataAdapter("Select * from Authors", cnPubs)

Dim ds As New DataSet()
daAuthors.Fill(ds, "Authors")

Dim dc As DataColumn
For Each dc In ds.Tables("Authors").Columns
dc.ColumnMapping = MappingType.Attribute


Console.WriteLine("Completed writing XML file, using a DataSet")

Case Sensitive SQL Server

26. October 2007 06:29 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)
Recently a friend at work had a problem querying a SQL server that indicated that the column name was wrong.

The only thing wrong was the the case. For example he had COLUMN1 instead of Column1. I had never seen that problem in SQLServer.
I had seed that in Sybase but not in SQLServer. He solved that by changing the database collating sequence to something like this:

alter database database1 collate SQL_Latin1_General_CP1_CI_AI

the CI in the collating indicates Case Insensitive

For more information on SQL Server collations check:

And you determine your current database collation use a code like this:

USE yourdb>

print 'My database [' + db_name() + '] collation is: ' + cast( DATABASEPROPERTYEX ( db_name(), N'Collation' ) as varchar(128) )

print 'My tempdb database collation is: ' + cast( DATABASEPROPERTYEX ( 'tempdb', N'Collation' ) as varchar(128) )


Get IP Address for Db2 clients

26. April 2007 09:14 by Mrojas in General  //  Tags: ,   //   Comments (0)

Source IP for connected applications in DB2

Usually when there are performance problems you need to track who is connected to the database. Especially in development environments because production environments are more restricted with who has access to the DB.

You can easily list the applications connected to your DB2 database using the control center application or from the command line.

From the control center:

  1. First check that the Objects Detail Pane is active

  1. In the Objects Details Pane, click the application list link

  1. This will open a window like this:

From the command window just do something like:


Now to get the real juicy and useful information execute from the command line:


And use the number that is under the Appl. Handle column, this will show the ip address and other info.

57016 or the Unavailable table

17. January 2007 06:57 by Mrojas in General  //  Tags: ,   //   Comments (0)
The idea was to create a harry potter like title jeje.
Today I had a new issue with DB2 (everyday you learn something new).
I got to work and we had some tables that you could not query or do anything. The system reported something like:
SQL0668N  Operation not allowed for reason code "1" on table "MYSCHEMA.MYTABLE".
So I started looking what is an 57016 code????

After some googling I found that the table was in an "unavailable state". OK!!
But how did it got there? Well that I still I'm not certain. And the most important. How do I get it out of that state?????
Well I found that the magic spell is somehting like
>db2 set integrity for myschema.mytable immediate checked

After that statement everything works like a charm.
DB2 Docs state that:
"Consider the statement:

Situations in which the system will require a full refresh, or will check the whole table
for integrity (the INCREMENTAL option cannot be specified) are:
  • When new constraints have been added to T itself
  • When a LOAD REPLACE operation against T, it parents, or its underlying tables has taken place
  • When the NOT LOGGED INITIALLY WITH EMPTY TABLE option has been activated after the last integrity check on T, its parents, or its underlying tables
  • The cascading effect of full processing, when any parent of T (or underlying table, if T is a materialized query table or a staging table) has been checked for integrity non-incrementally
  • If the table was in check pending state before migration, full processing is required the first time the table is checked for integrity after migration
  • If the table space containing the table or its parent (or underlying table of a materialized query table or a staging table) has been rolled forward to a point in time, and the table and its parent (or underlying table if the table is a materialized query table or a staging table) reside in different table spaces
  • When T is a materialized query table, and a LOAD REPLACE or LOAD INSERT operation directly into T has taken place after the last refresh"
But I really dont know what happened with my table.
Hope this help you out.