Drop orphan users – internal.object.permissions

I did a database restore from development to staging. Couldn’t connect to database using user login, Adam. Selected General tab on properties by clicking on Database->Security->User->Adam. The User type is “SQL user without login”. It seems restore process didn’t connect to the logins.

I try to drop the user;

DROP USER [qsadb]
GO

I keep getting this error;

  • Msg 208, Level 16, State 1, Procedure ddl_cleanup_object_permissions, Line 8 [Batch Start Line 2]
  • Invalid object name ‘internal.object_permissions’.

So, this is an orphan user and issue is with permissions. This needs to be fixed. But how?

Here are the steps that I have used;

The problem is that the user in the database is an “orphan”. This means that there is no login id or password associated with the user. This is true even if there is a login id that matches the user, since there is a GUID (called a SID in Microsoft-language) that has to match as well.

This used to be a pain to fix, but currently (SQL Server 2000, SP3 and up) there is a stored procedure that does the heavy lifting.

All of these instructions should be done as a database admin, with the restored database selected.

First, make sure that this is the problem. This will lists the orphaned users:

EXEC sp_change_users_login 'Report'

If you already have a login id and password for this user, fix it by doing:

EXEC sp_change_users_login 'AUTO_FIX', 'user'

If you want to create a new login id and password for this user, fix it by doing:

EXEC sp_change_users_login 'AUTO_FIX', 'user', 'login', 'password'

SSIS Script component – Get Blob Data column

Recently I have to move varbinary(max) data from one database to another database using script component.

When dealing with varbinary(max), there are two scenarios:

  • the length of the data is moderate
  • the length of the data is big

GetBytes() is intended for the this scenario, when we are using CommandBehaviour.SequentialAccess to ensure that we are streaming the data, not buffering it. In particular, in this usage we would usually be writing (for example) in a stream, in a loop. For example:

// moderately sized buffer; 8040 is a SQL Server page, note
byte[] buffer = new byte[8040]; 
long offset = 0;
int read;
while((read = reader.GetBytes(col, offset, buffer, 0, buffer.Length)) > 0) {
    offset += read;
    destination.Write(buffer, 0, read); // push downstream
}

However! If we are using moderately sized data, then use this code:

byte[] data = (byte[])reader[col];

Obviously the output column data type would be “image [DT_IMAGE]” in script component.

Finally to make it part of output;

OutputBuffer.FileData.AddBlobData((byte[])sqlReader["FileData"]);

Sources

https://stackoverflow.com/questions/11135245/what-length-parameter-should-i-pass-to-sqldatareader-getbytes

SSIS Excel Data Source Column overriding

When an excel data source is used in SSIS, the data types of each individual column are derived from the data in the columns. How do we override this behaviour?

Ideally we would like every column delivered from the excel source to be string data type, so that data validation can be performed on the data received from the source in a later step in the data flow.

Just go into the output column list on the Excel source and set the type for each of the columns. Let excel do its guessing game. We are interested in output column and type. This works.

To get to the input columns list right click on the Excel source, select ‘Show Advanced Editor’, click the tab labeled ‘Input and Output Properties’.

A potentially better solution is to use the derived column component where you can actually build “new” columns for each column in Excel. This has the benefits of

  1. You have more control over what you convert to.
  2. You can put in rules that control the change (i.e. if null give me an empty string, but if there is data then give me the data as a string)
  3. Your data source is not tied directly to the rest of the process (i.e. you can change the source and the only place you will need to do work is in the derived column)

This is another work around but it does not work at run time. You can see the data at design time though;

Write your SQL command and convert columns to text.

You can verify this on Advance tab / Input and Output Properties tab of Excel source. All of converted columns under External Column would be changed to “Unicode text stream” data type