Monday, December 6, 2010
Cross Apply Data Source for SSRS R2 2008
Cross Apply Data Source Name for SSRS:
SELECT DISTINCT
ds.ItemID ,
Name = LEFT(dsl.list, LEN(dsl.list) - 1)
FROM
dbo.DataSource AS ds
CROSS APPLY ( SELECT
ds2.Name + ',' AS [text()]
FROM
dbo.DataSource AS ds2
WHERE
ds.ItemID = ds2.ItemID
ORDER BY
ds2.ItemID
FOR
XML PATH('')
) dsl ( list )
WHERE
ds.ItemID IS NOT NULL
AND LEN(ds.Name) > 0
Ref Link:
Monday, November 22, 2010
Spatial Convert Latitude/Longitude (Lat/Long) to Geography Point
Prior to SQL Server 2008, geography locations such as bank branches, restaurant locations and household locations, are usually stored as latitude and longitude coordinates in two separate columns. With the introduction of spatial data types in SQL Server 2008, particularly the GEOGRAPHY data type, this can now be stored as points in a single column stored as a spatial data object. This article will show the different ways of converting the latitude and longitude coordinates of geography locations into a geography POINT.
The GEOGRAPHY data type supports seven spatial data objects that you can create and work with, namely Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon and GeometryCollection. From these spatial data objects, we will be using the Point.
Let's say we have a table of famous international geographic landmarks where we store its latitude and longitude coordinates and we want to take advantage of SQL Server 2008's new geography data type. (Note: The latitude and longitude coordinates of these landmarks were taken from Google maps and not from Microsoft's Virtual Earth (or Bing Maps).)
CREATE TABLE [dbo].[Landmark] (
[ID] INT IDENTITY(1, 1),
[LandmarkName] VARCHAR(100),
[Location] VARCHAR(50),
[Latitude] FLOAT,
[Longitude] FLOAT
)
GO
INSERT INTO [dbo].[Landmark] ( [LandmarkName], [Location], [Latitude], [Longitude] )
VALUES ( 'Statue of Liberty', 'New York, USA', 40.689168,-74.044563 ),
( 'Eiffel Tower', 'Paris, France', 48.858454, 2.294694),
( 'Leaning Tower of Pisa', 'Pisa, Italy', 43.72294, 10.396604 ),
( 'Great Pyramids of Giza', 'Cairo, Egypt', 29.978989, 31.134632 ),
( 'Sydney Opera House', 'Syndey, Australia', -33.856651, 151.214967 ),
( 'Taj Mahal', 'Agra, India', 27.175047, 78.042042 ),
( 'Colosseum', 'Rome, Italy', 41.890178, 12.492378 )
GOUsing geography::STPointFromText
The first thing to do is to add the new column where we will store the geography point. This can easily be done by the ALTER TABLE statement and we will use the GEOGRAPHY data type for the new column.
ALTER TABLE [dbo].[Landmark]
ADD [GeoLocation] GEOGRAPHY
GO
To convert the latitude and longitude coordinates to a geography point, we will use the StPointFromText function. The STPointFromText returns a geography instance from an Open Geospatial Consortium (OGC) Well-Known Text (WKT) representation.
UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' +
CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
GOAs you can see from this UPDATE statement, the longitude is specified first before the latitude. The reason is because in the Open Geospatial Consortium (OGC) Well-Known Text (WKT) representation, the format is (x, y). Geographic coordinates are usually specified by Lat/Long but between these two, the X is the Longitude while the Y is the Latitude.
You may be wondering why the X-coordinate is the Longitude while the Y-coordinate is the Latitude. Think of the equator of the earth as the x-axis while the prime meridian is the Y-axis. Longitude is defined as the distance from the prime meridian along the x-axis (or the equator). Similarly, latitude is defined as the distance from the equator along the Y-axis.
If the latitude and longitude were accidentally interchanged in the parameter for the STPointFromText, you may get the following error message particularly for the Sydney Opera House landmark record:
Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.
Using geography::STGeomFromText
Another way of creating a geography POINT is with the use of the STGeomFromText OGC static method. Just like the STPointFromText OGC static method, the STGeomFromText returns a geography instance from an Open Geospatial Consortium (OGC) Well-Known Text (WKT) representation.
UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::STGeomFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' +
CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
GOUnlike the STPointFromText method, which only accepts a POINT, the STGeomFromText can accept any of the seven spatial data objects (POINT, POLYGON, LINESTRING, MULTIPOINT, MULTIPOLYGON, MULTILINESTRING and GEOMETRYCOLLECTION). If you try to pass any other spatial data object to the STPointFromText aside from a POINT, you will get the following error message:
Msg 6522, Level 16, State 1, Line 3
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.FormatException: 24142: Expected "POINT" at position 1. The input has "LINES".
Using geography::Point
Yet another way of creating a geography POINT spatial data object is with the use of the geography::Point extended static geography method. The geography::Point method constructs a geography instance representing a POINT instance from the latitude and longitude values.
UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::Point([Latitude], [Longitude], 4326)
GO
Unlike the STGeomFromText and STPointFromText geography static methods, which accepts as parameter the point coordinates in the Open Geospatial Consortium (OGC) Well-Known Text representation, the Point geography static methods accepts as parameters the Latitude and Longitude coordinates of the point in that order.
Using geography::Parse
Yet another way of creating a geography POINT spatial data object is with the use of the geography::Parse extended static geography method. The geography::Parse static method is similar to the STGeomFromText static method in the sense that it returns a geography instance from an Open Geospatial Consortium (OGC) Well-Known Text (WKT) representation.
UPDATE [dbo].[Landmark]
SET [GeoLocation] = geography::Parse('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' +
CAST([Latitude] AS VARCHAR(20)) + ')')
GOThe only difference between the geography::Parse method and the geography::STGeomFromText method is that in the Parse method, it assumes a spatial reference ID (SRID) of 4326, which is the second parameter of the geography::STGeomFromText method.
Reference link:
Tuesday, October 12, 2010
7 Free .NET Development and Architecture E-books
7 Free .NET Development and Architecture E-books
Tuesday, September 28, 2010
Sql Server Community Free Training Webinar Series Pragmatic Works
Featured Session
Past Webinars
SSIS Expression Cheat Sheet
Reference Link
Integration Sql Server 2008 R2 Reporting Service with SharePoint 2010
Reference Link:
Friday, August 13, 2010
SSIS Script Task Email with SqlConnection Logging / VB.Net
Sample Code:
Public Sub Main()
Dim EmailTypeID As Integer
Dim EmployeeID As String
Dim SalesID As String
Dim SamAccount As String
Dim RehireDate As String
Dim ServiceDate As String
Dim FromAddress As String
Dim ToAddress As String
Dim Subject As String
Dim Body As String
Dim Name As String
Try
' Log properties
EmailTypeID = Dts.Variables("User::EmailTypeID").Value
EmployeeID = Dts.Variables("User::EmployeeID").Value.ToString
SalesID = Dts.Variables("User::SalesID").Value.ToString
SamAccount = Dts.Variables("User::SAMAccount").Value.ToString
RehireDate = Dts.Variables("User::RehireDate").Value.ToString
ServiceDate = Dts.Variables("User::ServiceDate").Value.ToString
' Email properties
FromAddress = Dts.Variables("User::MailFromAddress").Value.ToString
ToAddress = Dts.Variables("User::MailToAddress").Value.ToString
Subject = Dts.Variables("User::MailSubject").Value.ToString
Body = Dts.Variables("User::MailBody").Value.ToString
Name = Dts.Variables("User::MailName").Value.ToString
If SendMail(FromAddress, ToAddress, Subject, Body, Name) = True Then
LogEmail(EmailTypeID, EmployeeID, SalesID, SamAccount, ToAddress, RehireDate, ServiceDate)
Dts.TaskResult = ScriptResults.Success
End If
Catch ex As Exception
ErrorEmail(ex)
Dts.TaskResult = ScriptResults.Failure
End Try
End Sub
Public Function SendMail(ByVal FromAddress As String, ByVal ToAddress As String, ByVal Subject As String, ByVal Body As String, ByVal Name As String) As Boolean
Dim myHtmlMessage As MailMessage
Dim mySmtpClient As SmtpClient
Dim Body2 As String
Dim NewHireUrl As String
'MsgBox("Send, started")
NewHireUrl = "http://msn.com"
Body2 = "Dear: " & Name & _
vbNewLine & vbNewLine & _
" message "
myHtmlMessage = New MailMessage(FromAddress, ToAddress, Subject, Body2)
mySmtpClient = New SmtpClient("smtp.server.com")
mySmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials
mySmtpClient.Send(myHtmlMessage)
'MsgBox("Send, completed")
Return True
End Function
Public Function LogEmail(ByVal EmailTypeID As Integer, ByVal EmployeeID As String, ByVal SalesID As String, ByVal SamAccount As String, ByVal ToAddress As String, ByVal RehireDate As String, ByVal ServiceDate As String) As Boolean
Dim oCnn As New Data.SqlClient.SqlConnection
Dim sSQL As String
oCnn.ConnectionString = "Server=xxxx;Database=xxxx;User ID=user;Password=pass;Trusted_Connection=False"
sSQL = "insert into dbo.EmployeeEmail (DimEmailTypeKey, EmployeeID, SalesID, SamAccount, EmailAddress, DateOfEmail, RehireDate, ServiceDate, AuditKey) "
sSQL += "Values (@EmailTypeID, @EmployeeID, @SalesID, @SamAccount, @EmaillAddress, @DateOfEmail, @RehireDate, @ServiceDate, @AuditKey) "
Dim oCmd As SqlCommand = New SqlCommand(sSQL, oCnn)
oCmd.Parameters.Add("@EmailTypeID", SqlDbType.Int).Value = EmailTypeID
oCmd.Parameters.Add("@EmployeeID", SqlDbType.VarChar).Value = EmployeeID
oCmd.Parameters.Add("@SalesID", SqlDbType.VarChar).Value = SalesID
oCmd.Parameters.Add("@SamAccount", SqlDbType.VarChar).Value = SamAccount
oCmd.Parameters.Add("@EmaillAddress", SqlDbType.VarChar).Value = ToAddress
oCmd.Parameters.Add("@DateOfEmail", SqlDbType.VarChar).Value = Date.Now.ToString()
oCmd.Parameters.Add("@RehireDate", SqlDbType.VarChar).Value = RehireDate
oCmd.Parameters.Add("@ServiceDate", SqlDbType.VarChar).Value = ServiceDate
oCmd.Parameters.Add("@AuditKey", SqlDbType.VarChar).Value = 1
oCmd.CommandType = CommandType.Text
oCmd.Connection = oCnn
oCnn.Open()
oCmd.ExecuteNonQuery()
oCnn.Close()
Return False
End Function
Public Sub ErrorEmail(ByVal Exception As Exception)
Dim myHtmlMessage As MailMessage
Dim mySmtpClient As SmtpClient
myHtmlMessage = New MailMessage("admin@email.com", "admin@email.com", "Email Error", Exception.ToString())
mySmtpClient = New SmtpClient("smtp.server.com")
mySmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials
mySmtpClient.Send(myHtmlMessage)
End Sub
Tuesday, August 10, 2010
SSRS ReportExecution2005.asmx call with code/ C# / https
Report Server Web Service Endpoints
Sample of Code:
private MemoryStream FormSubmitGetReportAttachment()
{
try
{
// Render arguments
byte[] result = null;
string reportPath = "http://moss/Reports/Sales/Review.rdl";
string format = "PDF";
string historyID = null;
string devInfo = @"
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "ApptKey";
parameters[0].Value = ApptKey.ToString();
//DataSourceCredentials[] credentials = null;
//string showHideToggle = null;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
//ParameterValue[] reportHistoryParameters = null;
string[] streamIDs = null;
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
//rs.Credentials = new NetworkCredential(user, pass, domain);
rs.Url = "https://moss/Forms/_vti_bin/ReportServer/ReportExecution2005.asmx";
rs.ExecutionHeaderValue = new ExecutionHeader();
ExecutionInfo execInfo = rs.LoadReport(reportPath, historyID);
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
rs.SetExecutionParameters(parameters, "en-us");
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
MemoryStream ms = new MemoryStream();
ms.Write(result, 0, result.Length);
ms.Position = 0;
return ms;
}
catch (SoapException e)
{
ErrorMessage(e, true, e.Detail.OuterXml);
return null;
}
catch (Exception ex)
{
ErrorMessage(ex);
return null;
}
}
UserProfileService.asmx in MOSS 2007/ https
The solution was to change the url in the web service call from :
https://moss/_vti_bin/userprofileservice.asmx
to:
https://moss/sites/forms/_vti_bin/userprofileservice.asmx
Code Examples of Local and Code only solutions:
Local Data Connection inside Form:
private void GetProfileInfo2()
{
try
{
XPathNavigator Label = Root.SelectSingleNode("/my:myFields/my:Label", NamespaceManager);
XPathNavigator Name = Root.SelectSingleNode("/my:myFields/my:UserName", NamespaceManager);
XPathNavigator ErrorMesageLabel = Root.SelectSingleNode("/my:myFields/my:MessageLabel", NamespaceManager);
WebServiceConnection UserSvc = (WebServiceConnection)DataConnections["GetUserProfileByName"];
XPathNavigator xnDoc = DataSources["GetUserProfileByName"].CreateNavigator();
UserSvc.Execute();
XPathNavigator xnAcctEmail = xnDoc.SelectSingleNode("dfs:myFields/dfs:dataFields/s0:GetUserProfileByNameResponse/s0:GetUserProfileByNameResult/s0:PropertyData/s0:Values[../s0:Name = \"WorkEmail\"]", NamespaceManager);
XPathNavigator xnAcctName = xnDoc.SelectSingleNode("dfs:myFields/dfs:dataFields/s0:GetUserProfileByNameResponse/s0:GetUserProfileByNameResult/s0:PropertyData/s0:Values[../s0:Name = \"PreferredName\"]", NamespaceManager);
if (xnAcctEmail != null)
{
Label.SetValue(xnAcctEmail.Value);
Name.SetValue(xnAcctName.Value);
}
}
catch (Exception exception)
{
ErrorMessage(exception);
Root.SelectSingleNode("/my:myFields/my:MessageLabel", NamespaceManager).SetValue(exception.ToString());
}
}
Code Only Call:
private void GetProfileInfo()
{
try
{
XPathNavigator RemoteEmail = Root.SelectSingleNode("/my:myFields/my:RemoteEmail", NamespaceManager);
XPathNavigator RemoteName = Root.SelectSingleNode("/my:myFields/my:RemoteName", NamespaceManager);
UserProfileService Profile = new UserProfileService();
Profile.Credentials = new System.Net.NetworkCredential("User", "Pass", "Domain");
//Profile.UseDefaultCredentials = true;
//Profile.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
Web_Service_Validation.UserProfile.PropertyData[] properties = Profile.GetUserProfileByName(UserName);
if (properties.Length > 0)
{
RemoteEmail.SetValue(properties[36].Values[0].Value.ToString()); // WorkEmail
RemoteName.SetValue(properties[4].Values[0].Value.ToString()); //name
}
}
catch (Exception exception)
{
ErrorMessage(exception);
Root.SelectSingleNode("/my:myFields/my:MessageLabel", NamespaceManager).SetValue(exception.ToString());
}
}
Thursday, July 29, 2010
SSIS Execute SQL Task into an object variable / For each ADO Enumerator
I ended up using the Execute Sql Task with a Result Set of "Full result set" and returned the Result Set to a single Variable Object. This allows you to process multiple columns/rows into a single variable. Just need to make sure its a Object variable. Then in the For Each Loop Container Collection I used the Foreach ADO Enumerator. This allowed me to reference the Object variable I setup earlier. Next, I mapped each of the variables in the mapping section based on the order of the columns in the extract proc. Very similar to an array in .net. Finally, I used a script task to fire off an email for each row.
I have used the For Each Loop Containers in the past for processing/imports of data files. This is the first time I have worked with the Object variable in SSIS and agree this is a very power trick to have in your toolbox.
Thanks
Bryan
Thursday, July 8, 2010
SSRS 2008 Inscope / Percent to Total
Here is an example of how to use Inscope:
Territory Total of 2500 appts
District Total of 125 appts
what is the percent total?
=iif(iif(InScope("Territory", count(Fields!.Appts.Value,"Territory"),0) = 0 , 0,
count(Fields.Appts.Value) / iif(InScope("Territory"), count(Fields.Appts.Value, "Territory"),0))
Result = 5%
Tuesday, June 8, 2010
SharePoint Gantt Chart Formatting
What this code does:
- change the images width from 16 to 2 pixels.
- remove the display of weekdays
- rotate the dates to display them vertically
Reference: Link
If you are looking for a zoom slider with JQuery:Link
Thursday, June 3, 2010
Submit InfoPath 2007 with Code (SharePoint list & Email)
- In InfoPath, design a browser-compatible InfoPath form template
- On the Data Source task pane, add a Text Field node named formName under the myFields node.
- On the Tools menu, choose Data Connections.
- On the Data Connections dialog box, click Add, and create a new Submit data connection As an e-mail message. Fill in any email address in the To field; you will be changing this in code anyway. Accept the default name of Email Submit for the data connection.
- On the Data Connections dialog box, click Add, and create a new Submit data connection To a document library on a SharePoint site. Fill in a valid URL to a Document Library. Select the formName node from the Main data source to be the File name for the form. Accept the default name of SharePoint Library Submit for the data connection.
- On the Tools menu, choose Submit Options.
- On the Submit Options dialog box, select Allow users to submit this form, deselect the Show the Submit menu item and the Submit toolbar button check box, click Advanced and select Close the form from the After submit drop-down list box, select Perform custom action using Code, and click Edit Code.
- This will add a FormEvents_Submit event handler to the InfoPath form template.
- In Microsoft Visual Studio Tools for Applications, add the following C# code to the FormEvents_Submit event handler:
Wednesday, June 2, 2010
Split Comma Delimited String
Link to video:
http://www.sqlshare.com/SplittingDelimitedStrings_774.aspx
Link to Andy's example:
http://www.sqlshare.com/references.774.zip
Here is another example of the split function:
GO
/****** Object: UserDefinedFunction [dbo].[fn_Split] Script Date: 06/02/2010 17:05:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fn_Split]
(
@sText VARCHAR(8000) ,
@sDelim VARCHAR(20) = ' '
)
RETURNS @retArray TABLE
(
idx SMALLINT PRIMARY KEY ,
value VARCHAR(8000)
)
AS
BEGIN
DECLARE
@idx SMALLINT ,
@value VARCHAR(8000) ,
@bcontinue BIT ,
@iStrike SMALLINT ,
@iDelimlength TINYINT
IF @sDelim = 'Space'
BEGIN
SET @sDelim = ' '
END
SET @idx = 0
SET @sText = LTRIM(RTRIM(@sText))
SET @iDelimlength = DATALENGTH(@sDelim)
SET @bcontinue = 1
IF NOT ( ( @iDelimlength = 0 )
OR ( @sDelim = 'Empty' )
)
BEGIN
WHILE @bcontinue = 1
BEGIN
--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.
IF CHARINDEX(@sDelim, @sText) > 0
BEGIN
SET @value = SUBSTRING(@sText, 1,
CHARINDEX(@sDelim,
@sText) - 1)
BEGIN
INSERT @retArray
( idx, value )
VALUES
( @idx, @value )
END
--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET @iStrike = DATALENGTH(@value)
+ @iDelimlength
SET @idx = @idx + 1
SET @sText = LTRIM(RIGHT(@sText,
DATALENGTH(@sText)
- @iStrike))
END
ELSE
BEGIN
--If you can’t find the delimiter in the text, @sText is the last value in
--@retArray.
SET @value = @sText
BEGIN
INSERT @retArray
( idx, value )
VALUES
( @idx, @value )
END
--Exit the WHILE loop.
SET @bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE @bcontinue = 1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(@sText) > 1
BEGIN
SET @value = SUBSTRING(@sText, 1, 1)
BEGIN
INSERT @retArray
( idx, value )
VALUES
( @idx, @value )
END
SET @idx = @idx + 1
SET @sText = SUBSTRING(@sText, 2,
DATALENGTH(@sText) - 1)
END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT @retArray
( idx, value )
VALUES
( @idx, @sText )
SET @bcontinue = 0
END
END
END
RETURN
END
Thursday, May 27, 2010
InfoPath 2007 Bind Drop Down List with C#.Net
private void BindDistrictList(string username, string HomeDistrict)
{
string xpListBox = "/my:myFields/my:listDistrict/my:listDistrictItem";
ClearListBox(xpListBox, Root);
try
{
string data = string.Empty;
using (SqlConnection conn = new SqlConnection(_SqlCon))
{
SqlCommand command = new SqlCommand("IPGetDistrictbyUser", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@UserName", SqlDbType.Char).Value = UserName;
command.Parameters.Add("@hd", SqlDbType.Char).Value = HomeDistrict;
conn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
XmlDocument doc = new XmlDocument();
XmlNode group = doc.CreateElement("listDistrictItem", NamespaceManager.LookupNamespace("my"));
XmlNode field = doc.CreateElement("listDistrictItemName", NamespaceManager.LookupNamespace("my"));
XmlNode node = group.AppendChild(field);
node.InnerText = reader["DistrictName"].ToString();
field = doc.CreateElement("listDistrictItemValue", NamespaceManager.LookupNamespace("my"));
node = group.AppendChild(field);
node.InnerText = reader["DistrictID"].ToString();
doc.AppendChild(group);
MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:listDistrict", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
}
conn.Close();
}
}
catch (Exception ex)
{
ErrorMessage(ex);
}
}
InfoPath 2007 Clear Databound Drop Down List with C#.Net
Call from your method:
ClearListBox("/my"myFields/my:listLocations/my:listLocationsItem", Root);
Here is the ClearListBox method:
public void ClearListBox(string xp_ListBox, XPathNavigator xNav)
{
//clear list box of items
XPathNodeIterator lstClear = xNav.Select(xp_ListBox, NamespaceManager);
if (lstClear.Count > 0)
{
for (int i = lstClear.Count; i > 0; i--)
{
XPathNavigator reList = MainDataSource.CreateNavigator();
XPathNavigator reListItems = reList.SelectSingleNode(xp_ListBox + "[" + i + "]", NamespaceManager);
reListItems.DeleteSelf();
}
}
}
I am using a Property for Root:
private XPathNavigator Root
{
get
{
return MainDataSource.CreateNavigator();
}
}
Monday, April 26, 2010
InfoPath - Get the current user without writing code
http://blogs.microsoft.co.il/blogs/itaysk/archive/2007/04/05/InfoPath-_2D00_-Get-the-current-user-without-writing-code.aspx
Tuesday, April 20, 2010
Active Directory using SSIS, LDAP, ADHelper.dll and C#.Net
Here is a good article on the basic fields that can be queried using SSIS Active Directory Services.
http://agilebi.com/cs/blogs/jwelch/archive/2007/04/07/retrieving-information-from-active-directory-with-ssis.aspx
Here is a good article on the ADHelper.dll that can be referenced in SSIS
http://www.mssqltips.com/tip.asp?tip=1657
I will post the code to query the Group Description infomation.
Friday, March 26, 2010
Week of Business Intelligence with Pragmatic Works Webinars
Some of my favorite:
- Designing a Data Warehouse
- Loading a Data Warehouse with SQL Server Integration Services (SSIS)
- Report Design Recipes for BI Solutions
SSAS 2008 Time Calculation Dimension (Calculated Members)
- Go to your dsv of the cube and add a new Named Calculation field to your time dimension, Make sure to call it PeriodID and the expression should be " N'Current Period' " (make sure to drop the double quotes
- Create a new Dimension with the Dimension Wizard
- Select use an existing table
- tap into your current time dimension, in my case I am using DimWeek
- Make sure to have the primary key of the dimension selected and no other fields
- Name the new dimension "Time Calculation"
- Now that the dimension is created bring it up
- Drag over the PeriodID (the Name Calculation you created on step 1) to the Attributes section of the Dimension Structure tab
- Rename the field to Time Calculation and you should have something like this
- Now open the cube up and go to the Calculation
- Create a new Calculated Member
- Name: [Prior Year]
- Parent hierarchy: Time Calculation. Time Calculation
- Expression: (parallelperiod([Week].[FiscalCalendar].[Fiscal Year], 1, [Week].[FiscalCalendar].CurrentMember), [Time Calculation].[Time Calculation].&[Current Period])
- Now you need to setup your Dimension Usage
- Setup the Measure Group, Referenced, Intermediate Dimension (Week in this case), Reference Dimension attribute (Time Calculation), Intermediate Dimension attribute (PeriodID)
- Build and deploy cube
- Now in your cube browser you will see a new dimension call Time Calculation
- Add the new dimension and drag a metric and the time dimension and you will see the power of the Time Calculation Dimension
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Prior Year]
AS (parallelperiod([Week].[FiscalCalendar].[Fiscal Year], 1, [Week].[FiscalCalendar].CurrentMember), [Time Calculation].[Time Calculation].&[Current Period]),
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Year to Date]
AS aggregate(crossjoin([Time Calculation].[Time Calculation].&[Current Period], PeriodsToDate([Week].[FiscalCalendar].[Fiscal Year], [Week].[FiscalCalendar].CurrentMember))),
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Year to Year Change]
AS [Time Calculation].[Current Period] - [Time Calculation].[Prior Year],
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Year to Year Change %]
AS Case
When ISEMPTY([Time Calculation].[Prior Year]) Or [Time Calculation].[Prior Year] = 0
Then IIF([Time Calculation].[Current Period] > 0, 1, 0)
Else
[Time Calculation].[Year to Year Change] / [Time Calculation].[Prior Year]
End,
FORMAT_STRING = "Percent",
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Prior 3 Periods]
AS Aggregate({[Week].[FiscalCalendar].CurrentMember.Lag(3) :
[Week].[FiscalCalendar].CurrentMember.Lag(1)}, [Time Calculation].[Current Period]),
VISIBLE = 1 ;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Prior 6 Periods]
AS Aggregate({[Week].[FiscalCalendar].CurrentMember.Lag(7) :
[Week].[FiscalCalendar].CurrentMember.Lag(1)}, [Time Calculation].[Current Period]),
VISIBLE = 1 ;
CREATE MEMBER CURRENTCUBE.[Time Calculation].[Time Calculation].[Year to Date %]
AS [Time Calculation].[Time Calculation].&[Current Period] /[Time Calculation].[Time Calculation].[Year to Date],
FORMAT_STRING = "Percent",
VISIBLE = 1;
Friday, March 12, 2010
Cross Site List RSS Feed with SharePoint DataView (No need for Anonymous Access)
- Lets start out by pulling up SharePoint Desinger 2007
- Open up your site (in my case I am using MySite)
- On the Data Source Library tab on the right portion of the designer
- Connect another library in the lower right
- Now that you have created a connection to another library you need to "Refresh library" to get the objects to appear
- Now your Data Source Library should look like this (image)
- We now move on to the list you are trying to hook into. On the Date Source Library select "Connect to a script or RSS feed.."
- On the General tab give it a name, in my case "BI Calendar"
- On the Source tab the default values are good
- Just add the URL for the List RSS feed you want to view
- Go to the list, select the action, select "View RSS Feed"
- Take the URL and drop it into the "Enter the URL to a server-side script" field
- At this
point if you a specific view that you want to reference you are going to need to
add the GUID to the view in the above step as well. This was difficult step to figure
out and I hope I can help save someone else the time I spent on it. Open up the
view, modify the view and pull out the "&View=" from the URL. This parameter will be used in the server-side script connection to the List RSS Feed. The next step is to add a parameter to the DataView properties. A URL with out the View will look like this: "http://MyServer/_layouts/listfeed.aspx?List=a4a88bd0%2Ddf29%2D4f54%2Da924%2D195be47346ed" and a URL with the View will look like this: "http://MyServer/_layouts/listfeed.aspx?List=a4a88bd0%2Ddf29%2D4f54%2Da924%2D195be47346ed&View=%7B9F3ACEAB%2D75DF%2D4C04%2D83C2%2D3A5733A6CA31%7D"
Go to the the Login tab, in my case we are using the Kerberos so "Use Windows Auth"
works, not sure what other cases this will work. You may have to play this depending
on the type of Auth you have setup on your farm. Keep in mind if you enter your
creds they will be stored in plain text. This is the point in which you get around
the Anonymous Access part of a List RSS Web Part .- Now we need to add a SharePoint DateView to the page. Insert, SharePoint Controls,DateView
- The next step is to link the Server-Side Scripts to the SharePoint DataView web part we just
added. Right click on the server side scrip you just created in the Data Source
Library and select "Show Data". This will allow you to do two things, validate the
the connection is working correctly and view the list of RSS fields that come over
in the feed
- Now scroll down on the Data Source Details tab to the "Item" section. Then select "title &
pubDate" by holding down your CRTL key. - Then select the "Insert Selected Fields
as.." drop down at the top of the Date Source Details tab
This step binds the fields from the RSS feed to the DataView - Go to the DataView and right click edit properties. We want to edit the title and
convert it into a hyper link.
Make sure the "Text to display" is {title} and the "Address" is {link}.
- Next I clean up the headers on the webpart and the columns
- Finally save and deploy.
You may first see an error page but just select the "refresh page" link and you
are done (image)
SharePoint Data View Web Part
Link to article
Tuesday, March 9, 2010
Deploying a Business Intelligence Solution Using SharePoint, Reporting Services, and PerformancePoint Monitoring Server with Kerberos
Make sure to check out the original article from sqlcal.com: Link
Wednesday, February 17, 2010
Sharepoint Wakeup/Sharepoint List Adapters
So I decided to setup a Sharepoint WakeUp process to warm the site prior to loading the records. If you have not explored this simple process you need to look into it. By setting up a simple scheduled task on the web front end of your site you can wakeup miltiple sites. The process even has the ability to exclude some sites like "mysites"
The only catch is that you must setup the exe on the actual MOSS/WSS webfront end. It references a sharepoint.dll that is needed to wake the site.
Simple command:
spwakeup.exe -site:http://portal.mycompany.com -exclude:http://portal.mycompany.com/MySites -log:c:\log.txt
Concatenating rows as a alternative to using a cursor
declare @table table (id int, [name] varchar(10), gender char(1))
declare @MaleNames varchar(255)
insert into @table values (1,'John','M')
insert into @table values (2,'Sue','F')
insert into @table values (3,'Jane','F')
insert into @table values (4,'Mark','M')
insert into @table values (5,'Bill','M')
select @MaleNames = IsNull(@MaleNames + ', ','') + [name] from @table where gender = 'M'
Select @MaleNames as MalePatients
Friday, January 29, 2010
DBA Check List
Link to full pdf version
- General DBA Best Practices
- Best Practices for Becoming an Exceptional SQL Server DBA
- Day-to-Day
- Installation
- Upgrading
- Security
- Job Maintenance
SQL Server Configuration Settings - Database Settings
- Replication
- High Availability Best Practices
- General High Availability
- Disaster Recovery
- Backup
- Clustering
SQL Server Mirroring - Log Shipping
- General High Availability
- Performance Tuning Best Practices
- Performance Monitoring
- Hardware Performance Tuning
- Indexing
- SQL Server 2008 Compression Best Practices
- SQL Server 2008 Data Collector Best Practices
Best Practices for Resource Governor
- Performance Monitoring
- Application Design and Coding Best Practices
- Database Design
- Queries and Stored Procedures
- Transact-SQL
- SQL Server CLR
- XML
- Database Design
- SQL Server Component Best Practices
- SSIS
- Reporting Services
- Analysis Services
- Service Broker
- SSIS
Monday, January 25, 2010
XML Web Part/ RSS / Content Query Web Part Replacement in Windows SharePoint Services
- Add an XML Web Part to a page.
- Edit the XML Web Parts properties
- In the XML Link field, enter the URL of the RSS feed.
- In the XSL Link field, enter the URL of an XSL file that you've written to transform the feed, or alternatively, in the “XSL Editor“, enter the following XSL code:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:template match="/">
<table width="100%" border="0" cellspacing="0" cellpadding="1">
<tr>
<td class="tablebg"><table border="0" cellpadding="3" cellspacing="0" bgcolor="#FFFFFF">
<tr>
<td><img src="images/spcacer.gif" width="163" height="1" /></td>
</tr>
<tr valign="middle">
<td><h2>Recent Articles</h2>
</td>
</tr>
<xsl:for-each select="rss/channel/item">
<tr>
<td><a href="{link}"><xsl:value-of select="title"/></a></td>
</tr>
</xsl:for-each>
<tr>
<td><a href="/allarticles.aspx">More...</a></td>
</tr>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
It wasn't too long ago that I was trying to get my favorite Web Part (Content Query Web Part) to pull an RSS feed form a SharePoint list. Web Part was giving me a lot of grief, repeatedly giving me the error:
Cannot retrieve the URL specified in the XML Link property. For more assistance, contact your site administrator.
It took me a while to piece together that this Web Part does NOT run in the context of my given SharePoint credential when it comes to fetching this RSS. In fact I don't know of ANY RSS able Web Parts that support authenticated feeds.
As a work around I had to enable Anonymous Access for the given list. I was quite surprised when after some research I discovered that SharePoint allows you to turn on annonymous access for any of the following:
- Everything on a site (ie. 3 sites out of a site collection)
- Any combination of Lists and Libraries on a given site
- No anonymous access at all
For my needs I wanted to turn it on for just ONE list (the one I wanted to expose and consume the RSS feed for). Here's how to do it.
Enabling Anonymous Access for a Single List
- The first thing you need to do is turn on anonymous access for the web application, this is done through the Central Administration UI. Open up the Central Administration web page, go to the Application Management tab and click on Authentication Providers under Application Security (see below).
- Now that this application allows anonymous access we need to turn it on for the given site. Go to the site you want to turn on anonymous access on, navigate to Site Actions->Site Settings->Modify All Site Settings. From here click on Advanced Permissions. Open up the Settings menu on the tool bar and then click Anonymous Access. Finally choose (for this example) "Lists and libraries". We're going to turn on anonymous access for exactly one list.
- Finally go to the list you want to turn on anonymous access for and in the List Settings, Permissions for this List and then expand the Settings menu and click Anonymous Access. From here you simply select the rights you want to give anonymous users for this list. In this case we simply choose View Items.
- That's it, that RSS feed should now be working!
Friday, January 22, 2010
Synchronise SQL table with SharePoint List
I wanted to share how I was able to get synchronization of a SharePoint List through
SSIS. Below I have provided an outline of the steps I took.
- First, I had an OLE DB Source, then a Data Conversion to convert those strings and
then Sort it on its key.
- Second, I had the SharePoint List Source that has to be synchronized, Data Conversion
to match the key type and then Sort it on the key. - Third, Merge Join this 2 sorted data using Full Outer Join.
- Fourth, add a Conditional Split with the ff output:
- Output Name: Create Condition: ISNULL( ID )
- Output Name: Delete Condition: ISNULL([Your Key])
- Default output name: Update
- Lastly, Add 3 SharePoint List Destination for Create Delete and Update with the
ff note:
- For Create, do not map the column "ID" and Batch Type should be "Modification"
- For Update, map the column ID to the ID you got from merging, Batch Type should
be "Modification" - For Delete, you only need to map the ID, and Batch Type should be "Deletion"
Free Tools for the SQL Server DBA
http://www.sqlservercentral.com/articles/Tools/64908/
Wednesday, January 20, 2010
Excel 2007 connection to SSAS 2008: "The message or signature supplied for verification has been altered
Installed the hotfix and the issue has been resolved:
http://support.microsoft.com/kb/969083
Link to similar issues:
http://social.msdn.microsoft.com/forums/en-US/sqlanalysisservices/thread/f285e2dd-bd3f-455c-b8b3-808d73a25a75/
Friday, January 15, 2010
Repeat Header / Keep Header Visible in Tables in RS 2008
You selected "Repeat header rows on each page" or "Keep header rows visible while scrolling" in the tablix properties dialog, but it doesn't seem to work as expected? You might want to try the following four steps if you are using a "table"-style layout:
- in the grouping pane, click on the small triangle and select "Advanced Mode" to show static members:
- verify that you have the properties grid turned on (in BI Development Studio use F4, in Report Builder go to the "View" tab and select "Properties")
- select the corresponding (static) item in the row group hierarchy
- in the properties grid:
- set KeepWithGroup to After
- set RepeatOnNewPage to true for repeating headers
- set FixedData to true for keeping headers visible
Reference link:
Thursday, January 14, 2010
Automated Index Maintenance
Link