Showing posts with label Development. Show all posts
Showing posts with label Development. Show all posts

Friday, January 15, 2010

Pivot/Unpivot or Transpose in SQL 2005 and SSIS 2005

Lately I’ve been working on a project to bring a suite of Excel Reports to the new age, via SSIS and SSRS. (yeah, boring stuff, not mentioning the times spent to understand the user actions, VBA macros, cell formulae etc, such a pain!!!). Anyway, one of the existing manual actions from the users of the Excel which I need to emulate in the new system is the transpose copy paste action. At last, something that I haven’t done before and it’s interesting to me, in a sense.

After some research, there’s actually quite a lot of way to achieve the result, either using SSIS Data Flow task of Pivot/Unpivot, or just pure Transact-SQL approach.

The SSIS Method

Can’t explain better than what this blog has already mentioned. It involves a clever use of both Pivot and Unpivot Data Flow tasks. The example given provides the basic concept for me to tackle my slightly complex scenario.

Transact-SQL Method

Again, no point for me to reinvent the wheel. This blog has given the best options available. On top of that, MSDN also provide good examples on how to use the PIVOT and UNPIVOT command.

My Implementation

After the research, time to get the job done. So here’s I need to do:

I have an Excel table that looks like this:

Date: 15/1/2010

Category

Product A

Product B

Product C

Product D

In

Out

In

Out

In

Out

In

Out

Category 1

Category 2

Category 3

I need to transform it into this first:

Date

Product Name

Category

Balance

15/1/2010

Product A

Category 1

{In-Out}

15/1/2010

Product B

Category 2

{In-Out}

15/1/2010

Product C

Category 3

{In-Out}

Then into these tables for SSRS consumption:

Product A

Date

Category 1

Category 2

Category 3

15/1/2010

{Balance Value 1}

{Balance Value 2}

{Balance Value 3}

Product B

Date

Category 1

Category 2

Category 3

15/1/2010

{Balance Value 1}

{Balance Value 2}

{Balance Value 3}

Product C

Date

Category 1

Category 2

Category 3

15/1/2010

{Balance Value 1}

{Balance Value 2}

{Balance Value 3}

I decided to use both SSIS and Transact-SQL PIVOT for my solution. Reason is to avoid having to keep multiple Product tables. In the example shown above, I would need 3 tables for each product. Imagine having more than that…

Part A: SSIS Unpivot

First off, here’s my SSIS Data Flow:

1. Because I can’t Unpivot both [In] and [Out] columns at the same time (SSIS limitation), I have to Unpivot them separately, then join them back later through the Merge Join task.

2. Merge Join task requires all the data flow coming into it sorted with the same key(s). It will sort of being smart to detect if the data flow reaching it is sorted or not. If it is not, then it will not run and you'll get an error. This is typically solved by using the Sort task first, but since I know my data from the Excel is sorted, I avoid using the performance taxing Sort task. Instead, I set the Unpivot task’s output properties of IsSorted to True, then, in the Unpivot Output columns, set the SortKeyPosition of the sorted column to 1. (If more columns were used to sort, set the other columns with SortKeyPosition=2 or 3 or so forth). Screenshot below shows the Avanced Editor of the Unpivot task, where I set the IsSorted property.

3. The resultant join will have some invalid rows, due to merge columns in the Excel. Therefore, I’ve used the Conditional Split task (Get valid data) to exclude the unwanted columns.

4. The rest are simple stuff of adding the derived Date column, calculations of {In}-{Out} and data conversion, before loading into Production table.

Part B: SQL PIVOT

Next is the PIVOT SQL command (following the sample in MSDN)

SELECT Date, [Category 1], [Category 2], [Category 3] FROM

(

SELECT Date, Category, Balance

FROM Table01

WHERE ProductName = ‘Product A’

AND Date = ‘20100115’

) AS SourceTable

PIVOT

(

AVG(Balance)

FOR Category

IN ([Category 1], [Category 2], [Category 3])

) AS PivotTable;

So it’s done. Probably not the best apparoch, but hey, it works anyway J.

Tuesday, December 23, 2008

Recommended SharePoint application pool settings

Joel Oleson has a great blog regarding the best practice when comes to application pool performance settings: http://blogs.msdn.com/joelo/archive/2007/10/29/sharepoint-app-pool-settings.aspx. Do refer the comments left by other readers as well.

Monday, July 14, 2008

Change AD Account Password via Coding

Found a few great articles on creating a custom page to allow user to change their AD login password through coding (cause I need to do one quickly here).

The new .NET Framework 3.5 provides new method from the System.DirectoryEntry.AccountManagement namespace to change password easily. Background information at here.

Steve Mushkat has a blog entry with code example on how this is done at http://glorix.blogspot.com/2007/10/ad-change-password-webpart.html. His example is base on SharePoint, but can be easily adapted for other flavours.

Update: I've tried the code on my SharePoint implementation. It worked fine on a single-box MOSS environment, but it didn't work on a small farm setup. Not sure why, but I'm suspecting the environment that didn't work did not have kerberos configured properly. I've modified the code slightly to make it workable:

string strADDomain = ConfigurationSettings.AppSettings["ChangePassword_Domain"]; string strADUser = ConfigurationSettings.AppSettings["ChangePassword_User"]; string strADPassword = ConfigurationSettings.AppSettings["ChangePassword_Password"]; string strLoginName = string.Empty; SPWeb web = SPControl.GetContextWeb(this.Context); strLoginName = web.CurrentUser.LoginName; PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, strADDomain, strADUser, strADPassword); UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, strLoginName); try { user.ChangePassword(this.txtOldPassword.Text, this.txtNewPassword.Text); this.lblMessage.Text = "Password changed. Please close this browser window and log back on with your new password."; } catch (Exception ex) { this.lblMessage.Text = String.Format("Password couldn't be changed due to restrictions: {0}", ex.Message); } finally { user.Dispose(); domainContext.Dispose(); }

Wednesday, June 4, 2008

SharePoint security cache AD Group?

There seem to be a funny problem where AD group names are cached by SharePoint. So far I've observed two scenarios

Scenario 1: Unable to set AD group into MOSS security

I’ve created my own AD group and added the some users into the AD group. Then I add the AD group directly into some SharePoint subsite and granting them some permissions. This works out fine. Then I remove the AD group from SharePoint , delete the group from AD, and repeat the process again. I use back the exact same AD group name. This time, the user will not have access, as though the AD group is not added into SharePoint at all.

This problem can be fixed by performing an iisreset before re-adding the newly created AD group (with identical name as the previously deleted one) back into SharePoint. I’ll be performing “iisreset”s in the future when I’m setting up user permissions.

Scenario 2: People picker does not have the AD group

The scenario is like this: from a web part properties page, under Advnaced section, click on the browse button to bring up the people picker. Switch to find under Distribution/Security groups and perform a search. The AD groups that suppose to be around are not.

To fix this problem, just perform a full user profile import from the Shared Service Provider administration. But, there's a catch: you MUST delete all existing user profile, by viewing all existing user profile, and select all to perform the delete. Yes, painful process as there's no option to delete all existing user profile data, and it didn't work if you just perform a full user profile import directly.

Update: I've written a small console application to quickly delete all user profiles:

/*Include the following namespaces*/ using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; using Microsoft.Office.Server.UserProfiles; using Microsoft.Office.Server; /*Here's the quick and dirty method*/ public void PurgeUserProfile(string url_) { using (SPSite site = new SPSite(url_)) { ServerContext context = ServerContext.GetContext(site); UserProfileManager profileManager = new UserProfileManager(context); foreach (UserProfile profile in profileManager) { System.Console.WriteLine("Deleting " + (String)profile[PropertyConstants.AccountName].Value); profileManager.RemoveUserProfile(profile.ID); } } }

Friday, May 23, 2008

SharePoint Tool Pane, where are you?

A colleague of mine are creating a new master page for an ECM site. Once all SharePoint controls were included into the new master page, we found that the tool pane (the one that shows web part properties) went off the grid, not restricted by the boundary of HTML tables etc.

After some research, it is concluded that the mater page need to include a PlaceHolder tag with an ID of “MSO_ContentDiv”. Followed by the PlaceHolder is a HTML table tag with an id of “MSO_ContentTable”. Both of these tags can be found in OOB SharePoint master pages. Once these two tags are in place, the tool pane attaches itself to the left side of this HTML table when it is summoned.

Thursday, May 15, 2008

Extending SharePoint Page Layout

Found this blog entry from Janne Mattila's regarding extending page layout to include your own funky stuff. The example given are for custom language change, dynamic master page change and dynamic page layout swapping. For my case, I needed to do this to capture statistics of page hits for specific pages. Refer to here for more details.

Monday, March 31, 2008

SharePoint: Adding Custom Field in Content Query Webpart

Found this article at MSDN and ECM Team Blog which describe how to add a custom field into the presentation of content query webpart. The process involve two major work:

1. Export content query webpart into a dwp file, and add the custom fields.

2. Modify the XSLT to define the presentation for the custom field. The XSLT file is located in the folder Style Library à XSL Style Sheet àItemStyle.xsl, which you’ll need SharePoint Designer to access and modify.

Ref: http://msdn2.microsoft.com/en-us/library/bb850574.aspx http://blogs.msdn.com/ecm/archive/2006/10/25/configuring-and-customizing-the-content-query-web-part.aspx http://paulgalvin.spaces.live.com/blog/cns!1CC1EDB3DAA9B8AA!491.entry

Adding custom property into SharePoint Advance Search

It is not that difficult to add a property to be filterable in advance search, as long as you know how in the first place!

Ok, let’s say if you built a custom content type with custom column, and you want to make it searchable (must be index-able as well up front) in advance search, these are roughly the things you need to do:

1. Built your content type properly. Don’t simply add a field on the fly to your document library etc, as those don’t seem to be able to be indexed.

2. Make it indexed. Add the custom property into part of the index regime of the index service. This is done from SSP administration à Search Settings à Metadata Property Mapping. Take note of the property name, as it will be referenced in putting the field into the advance search property drop down list. Perform a crawl when you’re done.

3. Add into the Advance Search’s Properties. Go to the advance search page and edit the advance search web part. Under the Properties setting, add the custom property into the properties XML.

The XML should be pretty straight forward, but do refer to this blog for more information about it: http://www.sharepoint-tips.com/2006/07/found-it-how-to-add-properties-to.html

Hiding field controls in a page layout from presentation

I’ve been looking around on hiding some fields from the content page, and allowing editing only during edit mode. Finally found it on this blog, which states that there’s an EditModePanel under the SharePoint Server Controls in the Toolbox of SharePoint Designer. Everything that you drop into it will only be visible during edit mode of the page. So simple actually!

http://www.andrewconnell.com/blog/archive/2006/12/23/5535.aspx

Friday, March 7, 2008

Where is the Language Switcher? (MOSS Variation Label)

I’ve been following the guide in this article for a while, but I just don’t seem to get the nice little language switcher drop down list to appear on my SharePoint publishing site. After some additional research:

  • This other how-to article pointed out that you will have to assign the variation(s) to your master page before the variation label drop down list appears. In short, this is done by going into the Site Settings à Master Page Gallery. Check out the master page your publishing site is using and edit its properties. Under Variations section, pick the language you want to appear on the variation label drop down list.
  • Apparently the variation label drop down is disabled to improve performance. You'll need to modify the VariationsLabelMenu.ascx file in the CONTROLTEMPLATES folder to remove the commented line of code. (I wonder why we have to find this information from some blogs instead of from a proper MS documentation...)

Friday, December 28, 2007

Custom page in "_layouts" that switches master page depending on site context

Ok, that’s a long title. Let me explain what I’m trying to do here. I have a custom ASP.NET 2.0 pages deployed on the “_layouts” folder. What I want to do is have the master page setting of these custom pages to change according to the SharePoint site context.

For example, viewing http://server/SiteA/_layouts/custom.aspx will use materpage from http://server/SiteA/_catalogs/masterpage/default.master, while viewing http://server/SiteB/_layouts/custom.aspx will use materpage from http://server/SiteB/_catalogs/masterpage/default.master.

Lots of information are already on the web, such as http://www.sharepointblogs.com/dwise/archive/2007/01/08/one-master-to-rule-them-all-two-actually.aspx, http://weblogs.asp.net/soever/archive/2006/11/14/SharePoint-2007_3A00_-using-the-masterpage-from-your-site-in-custom-_5F00_layouts-pages.aspx and http://blogs.msdn.com/bgeoffro/archive/2007/11/12/branding-a-moss-corporate-intranet-portal-part-3-layouts-pages.aspx. The most promising method mentioned are by building a custom httpModule class which can be applied to the whole MOSS web application.

Below is my simplistic take that fits my scenario:

CustomPage.aspx

<%@ Page Language="C#" MasterPageFile="~/_layouts/default.master" AutoEventWireup="true" CodeBehind="CustomPage.aspx.cs" Inherits="CustomMaster. CustomPage" %>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

</asp:Content>

<asp:Content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

</asp:Content>

CustomPage.aspx.cs

public partial class CustomPage : System.Web.UI.Page

{

protected void Page_PreInit(object sender, EventArgs e)

{

Page page = sender as Page;

if (page != null)

{

if (page.MasterPageFile != null)

{

SPWeb mySite = SPContext.Current.Web;

page.MasterPageFile = mySite.CustomMasterUrl.ToString();

}

}

}

}

Now, the master page of my CustomPage will change dynamically depending on the site context. All I need to do now is to make this a base class for my custom application to inherit, and all the pages will have this behavior.

Thursday, October 18, 2007

Cannot acquire connection to Excel when executing SSIS package via SQL Agent Job

My current work involves building ETL solution using Microsoft SQL Server SSIS. All has been working well in development until we moved the SSIS packages into production environment (don’t that always happen?).

Anyway, our SSIS packages that has Excel file as data source hits the following problem:

Description: SSIS Error Code DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER. The AcquireConnection method call to the connection manager “Excel Connection Manager” failed with error code 0xC0202009

Eventually, it seems that the issue is due to account privilege. Our packages are executed via SQL Agent Job, in which the job step is configured to Run as a one of the designated AD account, that was setup as the proxy for the job. According to this Microsoft kb article , the particular AD account does not have rights to the Temp folder of SQL Server Agent proxy account. It would be logical to assume that this temp folder is used as a working folder by the SQL Agent job if required, such as putting the Excel file there for execution perhaps?

We solve this issue by using the default Run as account, which is SQL Agent Service Account. This Microsoft KB article has the detail: http://support.microsoft.com/kb/933835/

Friday, April 13, 2007

Enabling Ajax in MOSS 2007

Ajax greatly enhance any web application by reducing postback of ASP.NET pages. This instantly gives better user experience with the Ajax-enabled web application. Best of all, implementing it is fairly straight forward. That is, if SharePoint 2007 is not in the picture.

If you're building a ajax web application that sits on top of MOSS 2007, there's a couple of things you need to set:

If your custom app uses any of the SharePoint master page (such as default.master), ensure the wss user control Welcome is removed:

<wssuc:welcome id="IdWelcome" runat="server" enableviewstate="false"></wssuc:Welcome> This affects Ajax postbacks. Removing it will partially fix the problem. One-time ajax postback works, subsequently, it will fail. Secondly, the other change required is at LAYOUTS\1033\init.js file 1. Look for javascript function _spFormOnSubmitWrapper. 2. Under “if (_spFormOnSubmitCalled)” code block, remove/comment the “return false;” code. I'm not sure whether making this change would affect SharePoint, but so far seems ok. Do use this at your own risk though. Hopefully there's a fix for this in SharePoint soon so that Ajax will work without this kind of hack.

Reference made to Vincent Rothwell's blog: http://blog.thekid.me.uk/2007/01/19/using-aspnet-ajax-with-sharepoint-moss-2007-2/