<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-35862303</id><updated>2009-12-29T02:52:53.220-05:00</updated><title type='text'>Business Intelligence and SQL Server</title><subtitle type='html'>Discussing business intelligence and database technologies, data warehousing, and performance management</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default?start-index=26&amp;max-results=25'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>144</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-35862303.post-8934392907858869488</id><published>2009-10-30T15:41:00.000-04:00</published><updated>2009-10-30T15:41:33.575-04:00</updated><title type='text'>Business Intelligence Seminar Series</title><content type='html'>Do more with what you already have. Leverage the products you already own and the data your systems produce to gain operational efficiencies and improve your company's business intelligence capabilities!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Baltimore&lt;/strong&gt;&lt;br /&gt;Tuesday, Nov. 3 (9:00 a.m. – 11:30 a.m. EST)&lt;br /&gt;Hyatt Place&lt;br /&gt;4730 Painters Mill Road&lt;br /&gt;Owings Mills, MD 21117 &lt;br /&gt;&lt;a href="http://info.rdacorp.com/forms/BIFall09MDreg"&gt;Register&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Reston, VA&lt;/strong&gt;&lt;br /&gt;Wednesday, Nov. 18 (9:00 a.m. – 11:30 a.m. EST)&lt;br /&gt;Microsoft Corporation&lt;br /&gt;12012 Sunset Hills Rd.&lt;br /&gt;Reston, VA 20190 &lt;br /&gt;&lt;a href="http://info.rdacorp.com/forms/BIFall09VAreg"&gt;Register&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Washington, D.C.&lt;/strong&gt;&lt;br /&gt;Tuesday, Dec. 1 (9:00 a.m. – 11:30 a.m. EST)&lt;br /&gt;Microsoft Corporation&lt;br /&gt;5404 Wisconsin Ave.&lt;br /&gt;Chevy Chase, MD 20815&lt;br /&gt;&lt;a href="http://info.rdacorp.com/forms/BIFall09DCreg"&gt;Register&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Philadelphia&lt;/strong&gt;&lt;br /&gt;Wednesday, Dec. 2 (9:00 a.m. – 11:30 a.m. EST)&lt;br /&gt;Philadelphia Marriott West&lt;br /&gt;111 Crawford Avenue &lt;br /&gt;West Conshohocken, PA 19428&lt;br /&gt;&lt;a href="http://info.rdacorp.com/forms/BIFall09Phillyreg"&gt;Register&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-8934392907858869488?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/8934392907858869488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=8934392907858869488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8934392907858869488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8934392907858869488'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/10/business-intelligence-seminar-series.html' title='Business Intelligence Seminar Series'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-4702852731990710854</id><published>2009-10-30T13:08:00.000-04:00</published><updated>2009-10-30T13:08:58.433-04:00</updated><title type='text'>Hosting SQL Server on VMWare</title><content type='html'>One of our clients was investigating the logistics of running SQL Server on VMWare. In discussions with Microsoft, the response included&amp;nbsp;four (4) important links. I personally have seen various SQL Server performance issues when virtualizing especially in a SharePoint environment and I would never trust that configuration. There have been many enhancements with SQL Server 2005 and now SQL Server 2008 in order to consolidate servers and take advantage of reducing hardware needs and license costs. A good SQL Server 2008 consolidation white paper can be found &lt;a href="http://download.microsoft.com/download/6/9/D/69D1FEA7-5B42-437A-B3BA-A4AD13E34EF6/SQLServer2008Consolidation.docx"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is the info from the Microsoft technician:&lt;br /&gt;&lt;br /&gt;If you are running ESX V3.5 the latest hotfixes from VMware to disable write-caching are included in update3 and update 4.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;897613"&gt;The Microsoft Virtual Server support policy&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. &lt;a href="http://kb.vmware.com/kb/1008542"&gt;The VMware knowledge base article that you can contact VMware about for hosting SQL Server &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. &lt;a href="http://sqlsolutions.com/articles/articles/SQL_Server_and_VMware-A_Potentially_Fatal_Combination.htm"&gt;This article that explains the issue&amp;nbsp;and&amp;nbsp;discusses&amp;nbsp;the problem domain&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. &lt;a href="http://download3.vmware.com/vmworld/2006/dvt4696.pdf"&gt;Here is an presentation from VMWare about how to disable the disk write issue.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-4702852731990710854?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/4702852731990710854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=4702852731990710854' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4702852731990710854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4702852731990710854'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/10/hosting-sql-server-on-vmware.html' title='Hosting SQL Server on VMWare'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-6503224145134010482</id><published>2009-10-29T11:03:00.001-04:00</published><updated>2009-10-29T11:07:19.124-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='MERGE Statement'/><category scheme='http://www.blogger.com/atom/ns#' term='WHERE in MERGE'/><category scheme='http://www.blogger.com/atom/ns#' term='WHEN Clause'/><title type='text'>To MERGE or not to MERGE in SQL Server 2008</title><content type='html'>I was reviewing some demo material for the MERGE statement that Jim Pletscher put together. It was a standard scenario where we wanted to UPDATE, DELETE, or INSERT rows from a source table to a target table. A general overview of this is available &lt;a href="http://sqlserver-indo.org/blogs/kasimwirama/archive/2009/07/22/merge-statement-in-sql-server-2008.aspx"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Inserting is harmless&amp;nbsp;but what if sometimes we don't want to&amp;nbsp;update or delete&amp;nbsp;something from our target table? &lt;br /&gt;&lt;br /&gt;My first step was to add a new column to the target table. I named this column "DoNotTouch" and made it a bit defaulting to zero (0). I then set this value to one (1) on one of the target table rows. &lt;br /&gt;&lt;br /&gt;So now how do we tell the MERGE statement to not touch anything where this bit is flipped on? You cannot use a WHERE clause in the MERGE statement. The answer is within the WHEN clause of the MERGE statement. All you need to do is add an additional condition to each WHEN for the update and delete operations:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;(TargetTable is the name of the target table and SourceTable is the name of the source table)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;WHEN MATCHED &lt;strong&gt;&lt;span style="color: blue;"&gt;AND &lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: blue;"&gt;TargetTable&lt;/span&gt;.DoNotTouch&amp;lt;&amp;gt; 1&lt;/span&gt;&lt;/strong&gt; THEN&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UPDATE SET TargetTable.FirstName = SourceTable.firstname,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TargetTable.LastName = SourceTable.lastname&lt;br /&gt;&lt;br /&gt;WHEN NOT MATCHED BY SOURCE &lt;span style="color: blue;"&gt;&lt;strong&gt;AND TargetTable.DoNotTouch&amp;lt;&amp;gt; 1 &lt;/strong&gt;&lt;/span&gt;THEN&lt;br /&gt;DELETE&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So that worked! It did not touch the row where I set the DoNotTouch flag to one (1).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-6503224145134010482?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/6503224145134010482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=6503224145134010482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6503224145134010482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6503224145134010482'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/10/to-merge-or-not-to-merge-in-sql-server.html' title='To MERGE or not to MERGE in SQL Server 2008'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-1948879463852750604</id><published>2009-10-22T16:12:00.021-04:00</published><updated>2009-10-23T10:24:08.408-04:00</updated><title type='text'>Introduction to Change Data Capture</title><content type='html'>The Change Data Capture feature is a new feature in SQL Server 2008 that allows processes to&lt;br /&gt;quickly and easily identify changes to a table in SQL Server 2008. It primarily works by watching the SQL server transaction logs, and running processes that pull changes from the logs and moving them into tables.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Change Data Capture Setup&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enabling Change Data Capture is a two step process. First, you must enable it at the database level, then you must enable it for &lt;strong&gt;&lt;em&gt;each &lt;/em&gt;&lt;/strong&gt;table for which changes must be recorded.&lt;br /&gt;&lt;br /&gt;The first step in setting up Change Data Capture is to enable the option at the Database Level. The easiest way to do this is to use the system stored procedure &lt;em&gt;&lt;strong&gt;sys.sp_cdc_enable_db.&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;Simply execute this stored procedure from the desired database, and it will enable change data capture for the database. This stored procedure requires sysadmin privilege in order to execute it.&lt;br /&gt;&lt;br /&gt;(click to enlarge)&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDFKy0PXyI/AAAAAAAAAGw/fB7WeXThN0E/s1600-h/query6.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 400px; FLOAT: left; HEIGHT: 186px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395529142820101922" border="0" alt="" src="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDFKy0PXyI/AAAAAAAAAGw/fB7WeXThN0E/s400/query6.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once it is enabled at the database level, the Capture Change Data option must be enabled for each table for which changes should be captured. Use the &lt;strong&gt;&lt;em&gt;sys.sp_cdc_enable_table&lt;/em&gt;&lt;/strong&gt; stored procedure to enable the feature, passing the table name as an argument in order to enable the feature. By default, all of the columns in the source table are identified as captured columns. If only a subset of columns need to be tracked, such as for privacy or performance reasons, use the &lt;em&gt;&lt;strong&gt;@captured_column_list&lt;/strong&gt;&lt;/em&gt; parameter to specify the subset of columns.&lt;br /&gt;&lt;br /&gt;(click to enlarge)&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_-3dA1VkFWb8/SuDFD3N5PVI/AAAAAAAAAGo/qF08p6vVokg/s1600-h/query5.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 400px; FLOAT: left; HEIGHT: 250px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395529023742360914" border="0" alt="" src="http://3.bp.blogspot.com/_-3dA1VkFWb8/SuDFD3N5PVI/AAAAAAAAAGo/qF08p6vVokg/s400/query5.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once Change Data Capture (CDC) is enabled for a table, several things occur. First, an associated capture instance is created to support the collection of the change data in the source table. The capture instance consists of a change table and up to two query functions.&lt;br /&gt;&lt;br /&gt;All inserts, updates, and deletes to the source table are stored in the change table. The two query functions are specific to the source table, and can be used to fetch changes from the change table.&lt;br /&gt;&lt;br /&gt;The first five columns of a change data capture change table are metadata columns. These provide additional information that is relevant to the recorded change. The remaining columns mirror the identified captured columns from the source table in name. These columns hold the captured column data that is gathered from the source table.&lt;br /&gt;&lt;br /&gt;Each insert or delete operation that is applied to a source table appears as a single row within the change table. The data columns of the row that results from an insert operation contain the column values after the insert. The data columns of the row that results from a delete operation contain the column values before the delete. An update operation requires one row entry to identify the column values before the update, and a second row entry to identify the column values after the update.&lt;br /&gt;&lt;br /&gt;In additon to the Change instance, two SQL Agent Jobs are created: one that is used to populate the database change tables, and one that is responsible for change table cleanup. Both jobs consist of a single step that runs a Transact-SQL command. The Transact-SQL command that is invoked is a change data capture defined stored procedure that implements the logic of the job.&lt;br /&gt;&lt;br /&gt;(click to enlarge)&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDE_Xwp4AI/AAAAAAAAAGg/BtvOYy-9pg8/s1600-h/query4.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 368px; FLOAT: left; HEIGHT: 250px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395528946578743298" border="0" alt="" src="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDE_Xwp4AI/AAAAAAAAAGg/BtvOYy-9pg8/s400/query4.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The jobs are created when the first table of the database is enabled for change data capture. The Cleanup Job is always created. The capture job will only be created if there are no existing transactional publications for the database.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;span style="font-size:130%;"&gt;Using Change Capture Data&lt;/span&gt;&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Change data is made available to change data capture prcoesses via the two functions that are created when the change instance is created. Both functions require Log Sequence Numbers (LSNs) to help define the date range of change data to return in the resultset.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The function &lt;strong&gt;&lt;em&gt;cdc.fn_cdc_get_all_changes_&lt;capture_instance&gt;&lt;/em&gt;&lt;/strong&gt; returns all changes that occurred for the specified interval. Entries are always returned sorted, first by the transaction commit LSN of the change, and then by a value that sequences the change within its transaction.&lt;br /&gt;&lt;br /&gt;The function &lt;strong&gt;&lt;em&gt;cdc.fn_cdc_get_net_changes_&lt;capture_instance&gt;&lt;/em&gt;&lt;/strong&gt; returns one change per modified source table row. If more than one change is logged for the row during the specified time period, the column values will reflect the final contents of the row.&lt;br /&gt;&lt;br /&gt;Several functions are provided to help determine appropriate LSN values for use in querying the change data capture functions. For example, the functions &lt;strong&gt;&lt;em&gt;sys.fn_cdc_map_time_to_lsn&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;sys.fn_cdc_map_lsn_to_time&lt;/em&gt;&lt;/strong&gt; are available to help place LSN values on a conventional timeline.&lt;br /&gt;&lt;br /&gt;To illustrate, insert a single record into sample table created earlier, then update the columns.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_-3dA1VkFWb8/SuDCUeD64iI/AAAAAAAAAGQ/Wi6Gh7BuiWw/s1600-h/Query2.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 400px; FLOAT: left; HEIGHT: 250px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395526010512532002" border="0" alt="" src="http://2.bp.blogspot.com/_-3dA1VkFWb8/SuDCUeD64iI/AAAAAAAAAGQ/Wi6Gh7BuiWw/s400/Query2.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we can use the cdc.fn_cdc_get_all_changes to set how the change table is populated:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_-3dA1VkFWb8/SuDhqVPG3tI/AAAAAAAAAHY/mkZJTg71yM0/s1600-h/Query8.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 400px; FLOAT: left; HEIGHT: 250px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395560470961118930" border="0" alt="" src="http://2.bp.blogspot.com/_-3dA1VkFWb8/SuDhqVPG3tI/AAAAAAAAAHY/mkZJTg71yM0/s400/Query8.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note that the resulting change table contains four records, with the source table columns populated with the table data surrrounding the change. The first record reflects the initial insert. The 2nd and 3rd records reflect the update (a delete followed by new insert), while the fourth record reflects the final delete.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note that running the cdc.fn_cdc_get_&lt;strong&gt;&lt;em&gt;net&lt;/em&gt;&lt;/strong&gt;_changes returns only a single row, which represents the newest version of any modified row. This procedure will only return one change table record per source record changed, regardless of how many changes were made to the source record.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDCCXflivI/AAAAAAAAAGI/0BEOHLeJtUk/s1600-h/Query1.JPG"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 400px; FLOAT: left; HEIGHT: 278px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5395525699511880434" border="0" alt="" src="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDCCXflivI/AAAAAAAAAGI/0BEOHLeJtUk/s400/Query1.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDAx8P7vvI/AAAAAAAAAFw/-VK54jqnH2E/s1600-h/Query1.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-1948879463852750604?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/1948879463852750604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=1948879463852750604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1948879463852750604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1948879463852750604'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/10/introduction-to-change-data-capture.html' title='Introduction to Change Data Capture'/><author><name>Rich Cargile</name><uri>http://www.blogger.com/profile/15219630895270441765</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15445340444450413506'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-3dA1VkFWb8/SuDFKy0PXyI/AAAAAAAAAGw/fB7WeXThN0E/s72-c/query6.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-1893034238270632117</id><published>2009-09-28T23:26:00.002-04:00</published><updated>2009-09-28T23:30:42.268-04:00</updated><title type='text'>Business Intelligence and Silverlight</title><content type='html'>Looking forward to an upcoming book on two of my favorite areas of interest:  Business Intelligence and Silverlight.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://silverlighthack.com/post/2009/09/20/Announcing-Next-Generation-Business-Intelligence-Software-with-Silverlight.aspx"&gt;http://silverlighthack.com/post/2009/09/20/Announcing-Next-Generation-Business-Intelligence-Software-with-Silverlight.aspx&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-1893034238270632117?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/1893034238270632117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=1893034238270632117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1893034238270632117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1893034238270632117'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/09/business-intelligence-and-silverlight.html' title='Business Intelligence and Silverlight'/><author><name>Brian McCullough</name><uri>http://www.blogger.com/profile/03631616681884901656</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05882228528124432664'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-349817789531973185</id><published>2009-09-28T22:33:00.003-04:00</published><updated>2009-09-28T23:23:08.944-04:00</updated><title type='text'>SQL Server 2005 vs 2008 Query Performance</title><content type='html'>I was recently working on a transactional web application for a client.  This web application had some "operational" type reports included within it that required aggregations of, what will eventually be, millions of rows of data.  This meant I'd be writing queries directly against the transactional tables doing the aggregations (SUMs and COUNTs mostly) "on demand".  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note: In more heavily used applications, aggregating as much data as we were on demand might not be acceptable, but in this case we were measuring in transactions "per minute" and "per hour" rather then "per second", so we did not anticipate any blocking of our queries by database writes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These queries were going to be used on the landing page for web application seen by every employee within the company.  The landing page receives 20,000 hits per day over roughly 17 hours of operation a day.  This is about 19 hits per minute or 1 hit every 3 seconds.  Not all that much compared to many applications I've seen, but definitely enough to warrant some sort of load/performance testing under a larger data load.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I set up some SQL scripts to, somewhat randomly, load a data sample that was representative of about 2 years worth of data.  My initial query times were awful, and as I suspected, there was some room for improvement.  I did some refactoring (with some help from a friend) and had things running at about 1-2 seconds per query.  I thought there was still some room for improvement, but this was within an acceptable range.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thinking things were fine, I promoted my code from my local development environment to our integration environment.  I then ran my data load script to test in that environment, and suprisingly, was seeing query times in the 20-25 second range.  WHAT?!?  I just tuned things.  After some tinkering, and reloading of data, I was seeing the inconsistencies in my query times.  Sometimes in the 20-25 second range, other times in the 3-5 second range.  What was going on?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My initial thought was that there was something different in the query processing between my local development environment (SQL Server &lt;b&gt;2008 Developer&lt;/b&gt; Edition) and the integration environment (SQL Server &lt;b&gt;2005 Standard&lt;/b&gt; edition).  Some quick searches found that I might be using the &lt;a href="http://msdn.microsoft.com/en-us/library/ee410012.aspx"&gt;Star Join Query Optimization&lt;/a&gt; available in 2008 Developer/Enterprise editions.  There are &lt;a href="http://blogs.msdn.com/sqlqueryprocessing/archive/2007/04/09/how-to-check-whether-the-final-query-plan-is-optimized-for-star-join.aspx"&gt;ways that I could have confirmed this assumption&lt;/a&gt;, but I did not spend the time to do so.  Regardless if I was or wasn’t using this optimaztion, I still didn’t want to take a chance that there might have been something else in the query processor that was making things more “efficient” on 2008 Developer vs 2005 Standard.  I thought it’d be more reliable if I just set up a more representative environment and did my testing/tuning there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I built a 2005 Standard virtual machine, built my application, loaded sample data, and ran the queries.  Started seeing query times similar to our integration environment.  OK, so it was reproduceable.  Now let's tune it.  I went straight to an indexed view I was using for the query, made a minor tweak.  As I ran the script to rebuild the indexed view, it hit me.  I had just loaded 2 years worth of data, and had done no database maintenance that would "normally" be done gradually, such as rebuilding indexes and defragging the hard drive.  I rebuilt my indexes, defragged the drive, and sure enough my query times were back down in the 1-2 second range.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After tweaking just a bit more by including my numeric columns used in my query aggregations in an index, I redeployed to our integration environment and finally started getting consistent and performant results.&lt;/div&gt;&lt;p class="MsoNormal"&gt;&lt;span style="color:#1F497D"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;A few important take-aways here...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;In order to truly gauge/test performance, perform maintenance on your development/test environment just as you would in a “normal” environment, especially after large data loads.  That is rebuild your indexes, defrag the hard drive, etc.&lt;/li&gt;&lt;li&gt;Always (or to the extent possible) develop and/or test on machines that are representative of the environment you are actually going to deploy to, especially with regards to versions/editions of applications being used.  There are many features within SQL Server that are only available in the Enterprise Edition of the product, including some query optimizations.  I usually do this, but for a long period of time on my current project, the client couldn’t give a definitive answer on what our environments would look like, so we continued development with what we originally started with (which was no longer valid).  Once I built a more representative environment of what I was actually deploying to, then deployed my application and test data there, I was able to troubleshoot and fix the issue more quickly.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-349817789531973185?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/349817789531973185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=349817789531973185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/349817789531973185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/349817789531973185'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/09/sql-server-2005-vs-2008-query.html' title='SQL Server 2005 vs 2008 Query Performance'/><author><name>Brian McCullough</name><uri>http://www.blogger.com/profile/03631616681884901656</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05882228528124432664'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-8124521977573377947</id><published>2009-09-10T12:54:00.007-04:00</published><updated>2009-09-15T19:10:59.435-04:00</updated><title type='text'>Excel Services Part Deux - Excel Web Services</title><content type='html'>In an earlier blog entry, I discussed in very broad terms Microsoft Excel Services – a server side calculation engine that can be leveraged for SharePoint Business Intelligence solutions. Excel Services, you may recall, is divided into three components; Excel Calculation Services (ECS), Excel Web Access (EWA), and Excel Web Services (EWS). Excel Web Services allows access to the Excel Calculation Engine via Web Service calls, and is today’s focus.&lt;br /&gt;&lt;br /&gt;Excel Web Services utilizes SOAP over http and acts as an interface between custom client programs and Excel Services. In order to call the service, it is necessary to establish a reference to the Excel Web Services WSDL, accessed through ExcelService.asmx?wsdl. However, if you are writing code within SharePoint Services (for example, developing custom web parts), Microsoft recommends linking directly to Microsoft.Office.Excel.Server.WebServices.dll and making local calls rather than using loop-back SOAP calls.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;EWS - What is it good for?&lt;/strong&gt;&lt;br /&gt;Absolutely nothing (say it again…)? No, there are a number of practical examples where utilizing Excel Web Services comes in handy. One common scenario occurs when a company’s business logic is embedded in Excel spreadsheets. These spreadsheets can be maintained on a corporate server, and custom applications developed to utilize the logic in the spreadsheet without having to recode it in a “conventional” programming language. This also means that the spreadsheet logic can be maintained by business Subject Matter Experts (SMEs) who are comfortable working in Excel. Custom code can be developed to set values to cells and ranges, process the workbook, and retrieve calculated values (or even the entire workbook).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Coding Steps 101&lt;/strong&gt;&lt;br /&gt;Dealing with EWS is relatively straightforward, and numerous code examples can be found in the literature and on the web, such as here: &lt;a href="http://blogs.msdn.com/excel/archive/2005/11/21/495454.aspx"&gt;http://blogs.msdn.com/excel/archive/2005/11/21/495454.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Typical steps involved in coding against EWS are as follows:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Instantiate the web service via creation of &lt;span style="font-family:courier new;"&gt;ExcelService&lt;/span&gt; object&lt;br /&gt;2. Set the URL via &lt;span style="font-family:courier new;"&gt;ExcelWebService&lt;/span&gt; property&lt;br /&gt;3. Set the credentials via&lt;span style="font-family:courier new;"&gt; Credentials&lt;/span&gt; property. Default credentials (using applications own credentials) can be used by setting this property to &lt;span style="font-family:courier new;"&gt;System.Net.CredentialCache.DefaultCredentials&lt;/span&gt;.&lt;br /&gt;4. Start the Session by calling &lt;span style="font-family:courier new;"&gt;OpenWorkbook()&lt;/span&gt; method&lt;br /&gt;5. Set Cell Parameters via &lt;span style="font-family:courier new;"&gt;SetCell()&lt;/span&gt; method&lt;br /&gt;6. Calculate Spreadsheet (if workbook not set to auto-recalculate) via&lt;span style="font-family:courier new;"&gt; Calculate() &lt;/span&gt;or &lt;span style="font-family:courier new;"&gt;CalculateWorkbook()&lt;/span&gt; method&lt;br /&gt;7. Retrieve the Results via &lt;span style="font-family:courier new;"&gt;GetCell()&lt;/span&gt; method&lt;br /&gt;8. Close Session via call to &lt;span style="font-family:courier new;"&gt;CloseWorkbook()&lt;/span&gt; method&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Other methods are available as well, including the ability to set a range of cells and read an entire workbook into memory.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Business Example&lt;/strong&gt;&lt;br /&gt;An RDA client manages a customer support system that utilizes a custom authorization engine that controls which support agents have access to specific functionality within the application. For example, agents that support a specific product line do not have access to workflows supporting other product lines, and only agents of a certain tier level have the rights to issue refunds to customers. Although this authorization data is stored in a relational database, an Excel Spreadsheet on a SharePoint site is used by both the business and application support personnel to maintain and modify this information. When changes are made, the spreadsheet is loaded into the relational database through custom software.&lt;br /&gt;&lt;br /&gt;This approach has a number of benefits:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. SharePoint is used as a means of version control, to maintain a historical record of changes made.&lt;br /&gt;2. Anyone with access to the SharePoint site can view the details surrounding the current authorization hierarchy, without the need for special software or reports.&lt;br /&gt;3. The spreadsheet itself contains business logic to help organize the information and maintain data integrity.&lt;br /&gt;4. The spreadsheet is easy to use and modify for subject matter experts who may not have a programming background.&lt;br /&gt;&lt;br /&gt;However, as initially conceived there are some difficulties associated with this approach:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Making changes and deploying to the relational database involves a number of time-intensive manual steps, including downloading the spreadsheet, exporting to XML, applying an XSLT transform, and executing a custom application.&lt;br /&gt;2. In addition to the labor involved, the manual steps are prone to error.&lt;br /&gt;3. In the event that the changes made are not what were desired, either through human error or a change in business strategy, rollback of the changes can be difficult.&lt;br /&gt;&lt;br /&gt;Excel Web Services can provide an ideal platform to address these shortcomings. A SharePoint web part or other custom application can be developed that, utilizing Excel Services, can recalculate and read the latest spreadsheet data, generate the necessary output, and load the relational database in (from an end users point of view) a single step. No modifications to the existing spreadsheet logic would be necessary, and the business users can use and maintain the spreadsheet as before. SharePoint security can be leveraged to restrict access to the Web Part. In addition, custom rollback functionality can be added via code.&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;Finally…&lt;/strong&gt;&lt;br /&gt;As indicated in my last installment, relying on business logic residing in an Excel spreadsheet may not be considered “ideal” from an architectural standpoint – but is often a necessity when practical considerations such as time, budget, staff experience, and maintainability come into play. Excel Web Services provides an IT organization a valuable tool to leverage that platform for maximum benefit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-8124521977573377947?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/8124521977573377947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=8124521977573377947' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8124521977573377947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8124521977573377947'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/09/excel-services-part-deux-excel-web.html' title='Excel Services Part Deux - Excel Web Services'/><author><name>Michael Izsak</name><uri>http://www.blogger.com/profile/02118212636031296004</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12732906831074538978'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-6391846834014828481</id><published>2009-08-24T08:20:00.008-04:00</published><updated>2009-08-24T08:52:18.811-04:00</updated><title type='text'>SSIS Data Flow Task – OleDBCommand Task on ORACLE database throwing “Provider cannot derive parameter information” error</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;strong&gt;Problem&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;We were trying to update a table in Oracle database within a dataflow task. OleDbCommand transformation task is used for the purpose. The update statement takes some parameters. SSIS could not resolve the parameter information and throw error “Provider cannot derive parameter information”. We are using SSIS 2005 and Oracle 10G .NET drivers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;Analysis&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;Typically, OleDbCommand transformation task automatically resolves the parameters based on the SQL statement. For example, let’s try updating a same table in SQL Server database and Oracle database&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SQL Statement:&lt;/strong&gt; UPDATE Employee SET Bonus = ? WHERE EmpID = ?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;With SQL Server &lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Set the SQL Server connection in “Connection Managers” tab. Fill the SQL statement in the “Component Properties” tab as shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_NszYjBYumWY/SpKJkwPlUPI/AAAAAAAAASY/6YEYMDMW0cU/s1600-h/1.JPG"&gt;&lt;img style="WIDTH: 312px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373508569924980978" border="0" alt="" src="http://1.bp.blogspot.com/_NszYjBYumWY/SpKJkwPlUPI/AAAAAAAAASY/6YEYMDMW0cU/s320/1.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 1 - Adding SQL Statement to OleDbCommand Task&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you check the “Column Mapings” tab in the OleDBCommand transformation task, you would see the parameters list as follows. SSIS automatically resolves the parameters needed. Map the columns appropriately and the Data Transformation task is ready&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_NszYjBYumWY/SpKJkROSpZI/AAAAAAAAASQ/sFo6va47u2s/s1600-h/2.JPG"&gt;&lt;img style="WIDTH: 312px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373508561598064018" border="0" alt="" src="http://4.bp.blogspot.com/_NszYjBYumWY/SpKJkROSpZI/AAAAAAAAASQ/sFo6va47u2s/s320/2.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 2 - Parameters List (SSIS automatically resolved) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;With Oracle&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;When the same SQL is tried on Oracle database, SSIS throws the following exception. SSIS cannot figure out the parameters automatically.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Validation error. Update Oracle Table: UPDATE Employee [60]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E51. An OLE DB record is available. Source: "OraOLEDB" Hresult: 0x80040E51 Description: "Provider cannot derive parameter information and SetParameterInfo has not been called.".&lt;br /&gt;Validation error. Update Oracle Table: UPDATE Employee [60]: Unable to retrieve destination column descriptions from the parameters of the SQL command.&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_NszYjBYumWY/SpKJkGdjFJI/AAAAAAAAASI/ZeBlPf784iw/s1600-h/3.JPG"&gt;&lt;img style="WIDTH: 320px; HEIGHT: 237px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373508558709265554" border="0" alt="" src="http://4.bp.blogspot.com/_NszYjBYumWY/SpKJkGdjFJI/AAAAAAAAASI/ZeBlPf784iw/s320/3.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 3 - SSIS failed to resolve the parameters with Oracle database&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:180%;"&gt;Solution&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;Do not know if this is bug in SSIS. But one way to resolve is to add the parameters manually. Go to the “Input and Output Properties” tab and add the parameters manually. Add the parameters with the appropriate data type and in the same order as they appear in the SQL statement. This resolves the error and you can map the input columns to parameters.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_NszYjBYumWY/SpKJj9zVQpI/AAAAAAAAASA/JBhKsTLARj4/s1600-h/4.JPG"&gt;&lt;img style="WIDTH: 311px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373508556384715410" border="0" alt="" src="http://1.bp.blogspot.com/_NszYjBYumWY/SpKJj9zVQpI/AAAAAAAAASA/JBhKsTLARj4/s320/4.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 4 - Adding parameters manually&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_NszYjBYumWY/SpKJjaOVdoI/AAAAAAAAAR4/qB7aPc7Uc00/s1600-h/5.JPG"&gt;&lt;img style="WIDTH: 312px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373508546834298498" border="0" alt="" src="http://3.bp.blogspot.com/_NszYjBYumWY/SpKJjaOVdoI/AAAAAAAAAR4/qB7aPc7Uc00/s320/5.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 5 - Parameters added manually&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_NszYjBYumWY/SpKIgJlwCQI/AAAAAAAAARI/m_RNa3oeZyQ/s1600-h/6.JPG"&gt;&lt;img style="WIDTH: 312px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373507391317870850" border="0" alt="" src="http://1.bp.blogspot.com/_NszYjBYumWY/SpKIgJlwCQI/AAAAAAAAARI/m_RNa3oeZyQ/s320/6.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Figure 6 - Map the parameters to Input columns&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-6391846834014828481?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/6391846834014828481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=6391846834014828481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6391846834014828481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6391846834014828481'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/08/ssis-data-flow-task-oledbcommand-task.html' title='SSIS Data Flow Task – OleDBCommand Task on ORACLE database throwing “Provider cannot derive parameter information” error'/><author><name>Sarma Musty</name><uri>http://www.blogger.com/profile/04450720434203290103</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10041158569501359167'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_NszYjBYumWY/SpKJkwPlUPI/AAAAAAAAASY/6YEYMDMW0cU/s72-c/1.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-4391623713362113387</id><published>2009-08-21T13:04:00.009-04:00</published><updated>2009-08-21T14:07:10.414-04:00</updated><title type='text'>Reporting Services 2008 Parameter Dependencies &amp; Choosing Multiple Parameter Values</title><content type='html'>As was the case with prior versions, Reporting Services 2008 allows you to establish parameter dependencies and to allow mutiple parameter values be chosen. This means that parameter values provided to the end user can be dependent upon or driven by prior parameter value choices. In this example we’ll see how this can be done using a very simple AdventureWorks2008 Sales Data example report.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The AdventureWorks Sales Detail Report displays line-item sales details for a given product category, product subcategory and product. Our goal is to allow the end-user to specify the product category from the following available list (Accessories, Bikes, Clothing, Components). Once a Product Category choice is made, the available Product SubCategory choices for the chosen Product Categories are determined and displayed in the Product SubCategory drop-down list. In the screen snapshot below we chose Bikes and Clothing as our Product Category choices. For our Product Subcategory choices we chose Mountain Bikes (Bikes), Road Bikes (Bikes) and Caps (Clothing). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_k60MffeGnb4/So7YiDtvvsI/AAAAAAAAADg/i2otZdET_Ww/s1600-h/Full+Report.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5372469485123911362" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 250px" alt="" src="http://4.bp.blogspot.com/_k60MffeGnb4/So7YiDtvvsI/AAAAAAAAADg/i2otZdET_Ww/s400/Full+Report.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;a href="http://3.bp.blogspot.com/_k60MffeGnb4/So7W01kfSJI/AAAAAAAAADQ/_2j9Afn_7ZE/s1600-h/Full+Report.jpg"&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Notice that our Product Category is displayed along with the Product Subcategory in the following format: Product SubCategory (Product Category)&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Our product subcategory choices are below:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Mountain Bikes (Bikes)&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Touring Bikes (Bikes)&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Caps (Clothing)&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;This was done just to tell the report viewer what category a subcategory belongs to. This was done because the subcategory / category relationship was not always obvious by name! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Parameters and Dependencies&lt;/strong&gt;&lt;br /&gt;Our sample report uses two parameters: Product Category and Product SubCategory. The subcategory choices are driven by or dependent upon the product category choice. In this section we’ll see exactly how this is done and also look at how we provide both the category and subcategory names to the end-user.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Product Category Parameter&lt;/strong&gt;&lt;br /&gt;The Product Category choices are provided by selecting the Name column form the ProductCategory table in the AdventureWorks2008 database. Below is the SQL code to provide the ProductCategory choices:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;SELECT distinct&lt;br /&gt;Name as ProductCategoryName&lt;br /&gt;FROM&lt;br /&gt;Production.ProductCategory&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Notice that this parameter does not include any parameter dependencies since it is our initial choice. The Report Data window below allows us to define the parameter specifics such as the parameter name, parameter label, parameter data type, where the available values come from, what default value should be used, …&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Below we see the Report Data window which allows us to create and fine-tune our parameters.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_k60MffeGnb4/So7WW1oGLKI/AAAAAAAAADI/M8fw5_czvig/s1600-h/Report+Data.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5372467093340302498" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 329px; CURSOR: hand; HEIGHT: 271px" alt="" src="http://2.bp.blogspot.com/_k60MffeGnb4/So7WW1oGLKI/AAAAAAAAADI/M8fw5_czvig/s400/Report+Data.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;If we double-click on our highlighted parameter entry we see the Parameter Name, label and data type specified below. Notice that we also allow end-users to choose more than a single parameter value.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_k60MffeGnb4/So7X1y-YSPI/AAAAAAAAADY/9QvFC-OR-Co/s1600-h/Report+Params+Props.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5372468724716030194" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 373px; CURSOR: hand; HEIGHT: 303px" alt="" src="http://4.bp.blogspot.com/_k60MffeGnb4/So7X1y-YSPI/AAAAAAAAADY/9QvFC-OR-Co/s400/Report+Params+Props.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;In the Available Values tab we specify how the parameter choices are driven by a query. Since this is the case, we specify the DataSet name that is used to provide the available Product Category values. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_k60MffeGnb4/So7ZioZeNTI/AAAAAAAAADo/u8v_lFmVa6E/s1600-h/Avail+Values.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5372470594482615602" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 364px; CURSOR: hand; HEIGHT: 316px" alt="" src="http://1.bp.blogspot.com/_k60MffeGnb4/So7ZioZeNTI/AAAAAAAAADo/u8v_lFmVa6E/s400/Avail+Values.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/div&gt;&lt;div&gt;&lt;strong&gt;Product SubCategory Parameter&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The Product SubCategory choices are provided by selecting both the Name column from the ProductCategory table and the Name column from the ProductSubCategory table both in the AdventureWorks2008 database. Using the SQL below, end-users are provided with a list of SubCategory names with the corresponding category name in the following format: &lt;/div&gt;&lt;div&gt;subcategory (category) &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;SELECT&lt;br /&gt;PSC.Name + ' (' + PC.Name + ')' as productsubcategorynameandcategoryname,&lt;br /&gt;PSC.Name as ProductSubCategoryName&lt;br /&gt;FROM&lt;br /&gt;Production.ProductSubCategory PSC&lt;br /&gt;INNER JOIN&lt;br /&gt;Production.ProductCategory PC&lt;br /&gt;ON&lt;br /&gt;PSC.ProductCategoryID = PC.ProductCategoryID&lt;br /&gt;WHERE&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;PC.Name IN ( @ProductCategoryName)&lt;/span&gt;&lt;br /&gt;GROUP BY&lt;br /&gt;PSC.Name, PC.Name&lt;br /&gt;ORDER BY&lt;br /&gt;PC.Name, productsubcategorynameandcategoryname&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Notice this SQL references the ProductCategory parameter using the ‘@’ parameter designator. (This entry was highlighted) This is like saying : “Provide us with Subcategory values given the product category choice that was already made and stored in the &lt;span style="color:#ff0000;"&gt;@ProductCategoryname&lt;/span&gt; parameter.” This is exactly how one can introduce parameter dependencies in reports -- your SQL code can reference one or more report parameters.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;Extracting the Report Data&lt;/strong&gt;&lt;/div&gt;&lt;strong&gt;&lt;/strong&gt;&lt;div&gt;&lt;br /&gt;So far, we've looked at the SQL-code used to create parameter choices. The following SQL Code is used to extact the actual reporting data:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;SELECT&lt;br /&gt;P.Name as ProductName,&lt;br /&gt;PC.Name as ProductCategoryName,&lt;br /&gt;PSC.Name as ProductSubCategoryName,&lt;br /&gt;SOD.OrderQty,&lt;br /&gt;SOD.UnitPrice,&lt;br /&gt;SOD.OrderQty * SOD.UnitPrice as LineTotal&lt;br /&gt;FROM &lt;/div&gt;&lt;div&gt;Sales.SalesOrderHeader SOH&lt;br /&gt;INNER JOIN&lt;br /&gt;Sales.SalesOrderDetail SOD&lt;br /&gt;ON&lt;br /&gt;SOH.SalesOrderID = SOD.SalesOrderID&lt;br /&gt;INNER JOIN&lt;br /&gt;Production.Product P&lt;br /&gt;ON&lt;br /&gt;SOD.ProductID = P.ProductID&lt;br /&gt;INNER JOIN&lt;br /&gt;Production.ProductSubcategory PSC&lt;br /&gt;ON&lt;br /&gt;PSC.ProductSubcategoryID = P.ProductSubcategoryID&lt;br /&gt;INNER JOIN&lt;br /&gt;Production.ProductCategory PC&lt;br /&gt;ON&lt;br /&gt;PC.ProductCategoryID = PSC.ProductCategoryID&lt;br /&gt;WHERE&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;PC.Name in ( @ProductCategoryName)&lt;br /&gt;and PSC.Name + ' (' + PC.Name + ')' in &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color:#ff0000;"&gt;(@productsubcategorynameandcategoryname)&lt;/span&gt;&lt;br /&gt;ORDER BY&lt;br /&gt;ProductName,&lt;br /&gt;ProductCategoryName,&lt;br /&gt;ProductSubCategoryName&lt;br /&gt;&lt;br /&gt;Notice in the highlighted section we are referencing both the Product Category and the Product SubCategory parameters. In fact, we are actually building the string that include the SubCategory Name and Category Name (i.e. Mountain Bikes (Bikes) ) so this filter matches the choice format the end-user is provided with.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;It seems as though things have gotten easier in Reporting Services 2008. I’ve authored reports in both SQL Server 2000 and SQL Server 2005 and I remember using a Transact-SQL function (Split) to slice and dice values from a comma separate string. &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-4391623713362113387?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/4391623713362113387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=4391623713362113387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4391623713362113387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4391623713362113387'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/08/reporting-services-2008-parameter.html' title='Reporting Services 2008 Parameter Dependencies &amp; Choosing Multiple Parameter Values'/><author><name>JoeToscano</name><uri>http://www.blogger.com/profile/07204175337920001823</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17007756081573154900'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k60MffeGnb4/So7YiDtvvsI/AAAAAAAAADg/i2otZdET_Ww/s72-c/Full+Report.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-400731220084229146</id><published>2009-08-17T15:52:00.023-04:00</published><updated>2009-08-17T16:55:52.238-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSIS Extract Dynamic Data Driven Package Variables Expressions'/><title type='text'>SSIS Dynamic Data Driven Extracts</title><content type='html'>&lt;strong&gt;Extracting data from multiple tables: a dynamic SSIS Data-Driven Approach&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;This blog entry looks at how you can use SSIS to extract data from multiple tables leveraging a ‘source table’ that provides the table names to extract data from. This solution utilizes a For Each Container, Package Variables, Package Expressions applied to a package variabe along with an OLEDB Source whose SQL Extract Command is stored in a package variable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;In our sample scenario we receive sales data in tables from a 3’d party. This data is delivered on an unpredictable schedule and when received we’d rather not have to modify our SSIS solution. Instead, we rely on inserting a new row into the source table that tells SSIS what it needs to know about the new source table.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;Our Source Table / data driven approach&lt;/strong&gt;&lt;br /&gt;Our dynamic approach involves the use of a source table to drive the SSIS Extract process and designate the tables to extract. &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;The Source Table SSIS utilizes is &lt;strong&gt;dbo.SalesSource&lt;/strong&gt; and its schema is below:&lt;br /&gt;&lt;br /&gt;CREATE TABLE [dbo].[SalesSource] (&lt;br /&gt;[SalesSourceID] [int] IDENTITY(1,1) NOT NULL,&lt;br /&gt;[SourceTableName] [varchar](64) NOT NULL,&lt;br /&gt;[ExtractProcessedFlag] [int] default (0) NULL,&lt;br /&gt;[ExtractProcessingOrder] [int] NULL,&lt;br /&gt;[RowsExtracted] [int] NULL,&lt;br /&gt;[DateTimeExtracted] [datetime] NULL&lt;br /&gt;) &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Initially, we have 2 source files to work with so, we start out inserting the following two rows into our &lt;strong&gt;dbo.SalesSource&lt;/strong&gt; table (Notice we really only need to supply values for 3 columns). The SSIS package updates the &lt;em&gt;ExtractProcessedFlag&lt;/em&gt;, &lt;em&gt;RowsExtracted&lt;/em&gt; and &lt;em&gt;DateTimeExtracted&lt;/em&gt; columns upon sucessful completion.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_k60MffeGnb4/Som1u93flNI/AAAAAAAAAB4/bHbHLAtB0S8/s1600-h/Source+Table+Contents.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371023849101956306" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 479px; CURSOR: hand; HEIGHT: 65px" alt="" src="http://2.bp.blogspot.com/_k60MffeGnb4/Som1u93flNI/AAAAAAAAAB4/bHbHLAtB0S8/s400/Source+Table+Contents.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The ExtractProcessingOrder column allows us to specify the order in which we would like to extract data from in our Source Tables. The reason this was required was that our source data may very well contain duplicate data. We specify the order in which we extract and load and have our SSIS packages flag the duplicate rows based on a business key and keep only the most recent data from our duplicates. (In our scenario, new data trumps old data) &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Let’s take a look at our SSIS Solution and then dissect each component: &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_k60MffeGnb4/Som2iibpBHI/AAAAAAAAACA/vFv59C1hD8w/s1600-h/Full+SSIS+Package.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371024735090574450" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 373px" alt="" src="http://3.bp.blogspot.com/_k60MffeGnb4/Som2iibpBHI/AAAAAAAAACA/vFv59C1hD8w/s400/Full+SSIS+Package.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;div&gt;The SSIS package uses the following Package Variables.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_k60MffeGnb4/Som3NX1sD0I/AAAAAAAAACQ/KI6MkMdMqj4/s1600-h/Package+Variables.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371025470981410626" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 129px" alt="" src="http://1.bp.blogspot.com/_k60MffeGnb4/Som3NX1sD0I/AAAAAAAAACQ/KI6MkMdMqj4/s400/Package+Variables.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;As we progress and dissect each SSIS task, we will look at each package variable it utilizes. The SSIS package uses a For Each container to cycle through each row present in the Source Table with the CurrentTable package variable holding the current table that needs to be extracted. Notice that we supplied an initial value for the CurrentTable. This way we can preview data in this table from the OLE DB Source connection we will see in the Data Flow task. &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The package is fairly simple. It contains a highest level Sequence Container along with an inner For each Container. The For Each Container specifies an ADO Enumerator as its ‘Collection Type.’ The result set that feeds this container is below is produced by the Exec SQL Find Tables to Extract SSIS Task. The SQL Extract code is below:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;select SourceTableName&lt;br /&gt;from dbo.SalesSource&lt;br /&gt;where ExtractProcessedFlag = 0&lt;br /&gt;order by ExtractProcessingOrder&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Notice that we are only extracting source tables where the ExractProcessedFlag is set to 0. The SSIS package sets this flag column to 1 when a source table is extracted. This EXEC SQL Task specifies the ResultSet Package Variable to ‘hold’ the results of the above select statement. (ResultSet is of type object)&lt;br /&gt;&lt;br /&gt;The For Each Container Specifies a ‘For each ADO Enumerator’ as the Collection type and points the ResultSet package variable as the result set holder. ( Notice the setting for the Enumerator and the ADO object Source variable choice)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_k60MffeGnb4/Som34FBPVLI/AAAAAAAAACY/XenBj6skmsY/s1600-h/foreachloopeditor.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371026204663960754" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 302px" alt="" src="http://3.bp.blogspot.com/_k60MffeGnb4/Som34FBPVLI/AAAAAAAAACY/XenBj6skmsY/s400/foreachloopeditor.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Also, the CurrentTable package variable is specified in the Variable Mappings tab. This allows our CurrentTable variable to essentially hold the current table being processed each time we cycle through the For Each loop. We'll see this package variable used in the expression that assigns a value to the SQLExtractCommand package variable.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_k60MffeGnb4/Som4mZ3w-ZI/AAAAAAAAACg/n4tSP7fB2JQ/s1600-h/for+each+variable+mapping.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371027000535349650" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 300px" alt="" src="http://1.bp.blogspot.com/_k60MffeGnb4/Som4mZ3w-ZI/AAAAAAAAACg/n4tSP7fB2JQ/s400/for+each+variable+mapping.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;The Data Flow task specifies that the SQL to extact data is present in a Package Variable. While this choice if probably not the most common Data Access Mode choice, it does provide us with the flexiblity we need. This package variable has its value dynamically set using Expressions. If you choose a package variable and display its properties (F4 will provide the properties) you will notice that by default the &lt;em&gt;Evaluate As Expression&lt;/em&gt; property is False. This was changed to True as is seen below: &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_k60MffeGnb4/Som43GnQMGI/AAAAAAAAACo/9tx054TtBUA/s1600-h/SQLExtractComandProperties.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371027287423594594" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 300px" alt="" src="http://4.bp.blogspot.com/_k60MffeGnb4/Som43GnQMGI/AAAAAAAAACo/9tx054TtBUA/s400/SQLExtractComandProperties.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;If you click on the the ellipse in the Expression value, you will be provided with the expression builder dialog box. The SQLExtactCommand’s contents are created using the quoted string along with the CurrentTable package variable as seen below. (Notice I did specify square brackets to surrount the table name since the table name may include non-alphabetical or other strange characters) &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_k60MffeGnb4/Som5MciMBCI/AAAAAAAAACw/kkZmiuzySOw/s1600-h/Expression+Builder.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371027654085182498" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 304px" alt="" src="http://1.bp.blogspot.com/_k60MffeGnb4/Som5MciMBCI/AAAAAAAAACw/kkZmiuzySOw/s400/Expression+Builder.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I found it helpful to click on Evaluate Expression and then paste the results into a Management Studio window. This way you can execute and validate the actual code. &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The Data Flow Task that specifies the SQLExtractCommand package variable is below. You will notice that you are able to view columns and even preview data because we supplied an initial value for our CurrentTable package variable.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_k60MffeGnb4/Som6PpEe_CI/AAAAAAAAAC4/7pwA7WR941Q/s1600-h/OLE+DB+Source+Editor.bmp"&gt;&lt;img id="BLOGGER_PHOTO_ID_5371028808501492770" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 400px; CURSOR: hand; HEIGHT: 329px" alt="" src="http://4.bp.blogspot.com/_k60MffeGnb4/Som6PpEe_CI/AAAAAAAAAC4/7pwA7WR941Q/s400/OLE+DB+Source+Editor.bmp" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The final step in our SSIS package is a EXEC SQL statement that updates the source table to designate the SourceTable as being sucessfully processed. &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;UPDATE&lt;br /&gt;dbo.SalesSource&lt;br /&gt;SET&lt;br /&gt;ExtractProcessedFlag = 1,&lt;br /&gt;DateTimeExtracted = getdate(),&lt;br /&gt;RowsExtracted = ?&lt;br /&gt;WHERE&lt;br /&gt;SourceTableName = ?&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Parameters used in this update statement include the number of rows extracted from the source table along with the source table name.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;What we left with is a SSIS package that extracts the tables to process from a source table. As new source tables arrive, we insert the rows into our source table without having to modify our SSIS package. &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-400731220084229146?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/400731220084229146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=400731220084229146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/400731220084229146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/400731220084229146'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/08/ssis.html' title='SSIS Dynamic Data Driven Extracts'/><author><name>JoeToscano</name><uri>http://www.blogger.com/profile/07204175337920001823</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17007756081573154900'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_k60MffeGnb4/Som1u93flNI/AAAAAAAAAB4/bHbHLAtB0S8/s72-c/Source+Table+Contents.bmp' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-2240238788681770804</id><published>2009-08-04T15:46:00.002-04:00</published><updated>2009-08-04T15:48:21.898-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='SSMS'/><title type='text'>SQL 2008 SSMS Table Save Error</title><content type='html'>&lt;p&gt;Using SQL Server Management Studio (SSMS) for SQL 2008, I had to make a change to one of my tables to add a column. However, I did not want to add the column at the end of the table, I wanted to add the column between two other columns. When I attempted to Save the table change, I had the following error appear:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_Bb_dqfXVtDU/SniP-sp24gI/AAAAAAAAAFM/JJM_FC99b_0/SSMS_Table_Save_Error%5B3%5D.jpg"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="113" alt="SSMS_Table_Save_Error" src="http://lh3.ggpht.com/_Bb_dqfXVtDU/SniP_AHufSI/AAAAAAAAAFQ/OJrKHt-d2Lg/SSMS_Table_Save_Error_thumb%5B1%5D.jpg" width="453" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;In order to resolve this issue, I had to update the following setting in SSMS. Go to Tools--&amp;gt;Designers--&amp;gt;Table and Database Designers and uncheck the "Prevent saving changes that require table re-creation" checkbox:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Bb_dqfXVtDU/SniP_0X7PjI/AAAAAAAAAFU/e87X7BGHAkI/SSMS_Table_Designer_Option%5B10%5D.jpg"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="301" alt="SSMS_Table_Designer_Option" src="http://lh5.ggpht.com/_Bb_dqfXVtDU/SniQAAR4fZI/AAAAAAAAAFY/iMkku8SfYb4/SSMS_Table_Designer_Option_thumb%5B8%5D.jpg" width="515" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-2240238788681770804?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/2240238788681770804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=2240238788681770804' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/2240238788681770804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/2240238788681770804'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/08/sql-2008-ssms-table-save-error.html' title='SQL 2008 SSMS Table Save Error'/><author><name>Chuck Rivel</name><uri>http://www.blogger.com/profile/05290272415899934531</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02532501760416550527'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-3285391714945256743</id><published>2009-07-24T15:36:00.001-04:00</published><updated>2009-07-24T15:36:56.420-04:00</updated><title type='text'>Retrieve Web Page Results Using SSIS</title><content type='html'>&lt;h5&gt;Scenario&lt;/h5&gt;  &lt;p&gt;A client is wanting to use the web to retrieve coordinate information from Google Maps to store the information for a Marketing campaign.&lt;/p&gt;  &lt;h5&gt;Solution&lt;/h5&gt;  &lt;p&gt;The SSIS Script task can connect to the web page and return the results. The following script provides sample code on how to get the Script Task to perform the action. The script task was developed in SQL SSIS 2008 using VB, the 2005 version is similar but the guts of the HTTP code remains the same (thanks to my colleague Andrew Crowder for putting together the main syntax):&lt;/p&gt;  &lt;p&gt;First, a package is created with two variables of type String. The variables are passed into the script task in the following manner:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ReadOnly: User::URL &lt;/li&gt;    &lt;li&gt;ReadWrite: User::HTML &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now, the script itself:&lt;/p&gt;  &lt;p&gt;Imports System    &lt;br /&gt;Imports Microsoft.SqlServer.Dts.Runtime     &lt;br /&gt;Imports System.IO     &lt;br /&gt;Imports System.Net &lt;/p&gt;  &lt;p&gt;&amp;lt;System.AddIn.AddIn(&amp;quot;ScriptMain&amp;quot;, Version:=&amp;quot;1.0&amp;quot;, Publisher:=&amp;quot;&amp;quot;, Description:=&amp;quot;&amp;quot;)&amp;gt; _    &lt;br /&gt;&amp;lt;System.CLSCompliantAttribute(False)&amp;gt; _     &lt;br /&gt;Partial Public Class ScriptMain     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; Enum ScriptResults    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Enum     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub Main()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Try &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 'setup the variables, URL is set in the package as a var and read    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim URL As String = Dts.Variables(&amp;quot;URL&amp;quot;).Value     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim request As HttpWebRequest = WebRequest.Create(URL)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim response As HttpWebResponse = request.GetResponse()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim reader As StreamReader = New StreamReader(response.GetResponseStream()) &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 'read the http data into a string to be used later in the package    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim str As String = reader.ReadToEnd() &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dts.Variables(&amp;quot;HTML&amp;quot;).Value = str.ToString() &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dts.TaskResult = ScriptResults.Success    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 'fire the info event and return as error from the task     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dts.Events.FireInformation(0, &amp;quot;Web Script Task&amp;quot;, ex.Message.ToString(), &amp;quot;&amp;quot;, 0, 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dts.TaskResult = ScriptResults.Failure     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Try     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub&lt;/p&gt;  &lt;h5&gt;Execution&lt;/h5&gt;  &lt;p&gt;The following URL value is set and returns the coordinate information into the HTML variable:&lt;/p&gt;  &lt;p&gt;URL: &lt;a href="http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&amp;amp;output=csv&amp;amp;oe=utf8&amp;amp;sensor=false&amp;amp;key=ABQIAAAAP6yK9BJ44wmvT1Dd7V5cKRQz9eeYvRAhuPGO19pGZUf7Pj2DYxRZ0Zbtz0o1UAkk17kmD6xk5qDnzg"&gt;http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&amp;amp;output=csv&amp;amp;oe=utf8&amp;amp;sensor=false&amp;amp;key=ABQIAAAAP6yK9BJ44wmvT1Dd7V5cKRQz9eeYvRAhuPGO19pGZUf7Pj2DYxRZ0Zbtz0o1UAkk17kmD6xk5qDnzg&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;HTML: 200,8,37.4219720,-122.0841430&lt;/p&gt;  &lt;p&gt;The script task can also return the HTML from a page, for example &lt;a href="http://www.rdacorp.com"&gt;http://www.rdacorp.com&lt;/a&gt;, and allow for other SSIS tasks to manipulate the HTML variable as per the requirements and design of the package as it would like any other variable within the package.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-3285391714945256743?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/3285391714945256743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=3285391714945256743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3285391714945256743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3285391714945256743'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/07/retrieve-web-page-results-using-ssis.html' title='Retrieve Web Page Results Using SSIS'/><author><name>Chuck Rivel</name><uri>http://www.blogger.com/profile/05290272415899934531</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02532501760416550527'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-6889378823343392077</id><published>2009-07-22T13:14:00.003-04:00</published><updated>2009-07-22T23:11:18.451-04:00</updated><title type='text'>Introduction to Excel Services</title><content type='html'>Microsoft and other software vendors offer a dizzying array of BI, business productivity, and data management tools from powerful relational databases on up. Yet research (and personal experience) has shown that a large number of corporations still maintain a significant quantity of business logic in plain-old Excel spreadsheets . Logic stored in spreadsheets can lead to a proliferation of cut-and-paste in an attempt at reuse that can become a maintenance nightmare. Responding to the needs of its customers, Microsoft introduced Excel Services for SharePoint Server 2007.&lt;br /&gt;&lt;br /&gt;Basically, Excel Services is a server-side version of the Excel calculation engine. Some common usage scenarios to Excel Services are:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A set of SharePoint web parts. This allows anyone with access to a SharePoint site to interact with Excel Data stored on a server without necessarily having full control to modify the data or change how it is presented. A Business Intelligence Dashboard showing KPIs (Key Performance Indicators) would be a common application. &lt;/li&gt;&lt;li&gt;An interactive spreadsheet viewer. Even if a customer has Excel installed on their workstation, this allows the user to view up-to-date Excel data without having to leave their browser when accessing their corporate SharePoint site &lt;/li&gt;&lt;li&gt;Maintaining “one version of the truth” of data (such as quarterly sales, etc.) on a server without having to worry about changes to multiple copies floating around individual users desktops. &lt;/li&gt;&lt;li&gt;A set of APIs for developers to leverage the calculation abilities of Excel from within their own applications. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;Architecturally, Excel Services is also divided into three components: &lt;/p&gt;&lt;ol&gt;&lt;li&gt; Excel Calculation Services (ECS) – handles the spreadsheet refresh and recalculation &lt;/li&gt;&lt;li&gt;Excel Web Access (EWA) – handles the rendering of the spreadsheet to the client, e.g. SharePoint site &lt;/li&gt;&lt;li&gt;Excel Web Services (EWS) – allows access to the Excel calculation engine via web service calls. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;Alas, Excel Services does not provide you with 100% of the full power of Excel to your SharePoint site; limitations include lack of support for VBA Macros, references to other Excel workbooks, ActiveX controls, and most graphical elements. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Excel Services may not be the most glamorous technology, and on the surface might seem like a “hack” – using a lowly spreadsheet to manage your important business data, and to provide the calculation engine for custom applications that might be better served by interfacing with a commercial or homegrown software library. However, in the real world of legacy systems and shrinking budgets, Excel Services has its place. In future blog entries, I will be diving in and exploring the different components of Excel Services in greater detail.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-6889378823343392077?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/6889378823343392077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=6889378823343392077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6889378823343392077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6889378823343392077'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/07/introduction-to-excel-services.html' title='Introduction to Excel Services'/><author><name>Michael Izsak</name><uri>http://www.blogger.com/profile/02118212636031296004</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12732906831074538978'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-3016888080225801738</id><published>2009-07-22T10:46:00.003-04:00</published><updated>2009-07-22T10:49:26.173-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='excel'/><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>Default Cube Action in Excel</title><content type='html'>&lt;h5&gt;Scenario&lt;/h5&gt;&lt;p&gt;When using Excel 2007 to connect to a SQL 2005\2008 SSAS cube, double-clicking a cell, or right clicking the cell and selecting Show Details, within a Pivot table brings up details about the specific sliced cell within the Pivot table. However, the default nature of the cube is to bring up the raw Fact table data for that slice, which displays all fields within the Fact table for the records that make up the cell. The fields within a Fact table are often surrogate keys that point to the Dimensions that join to the Fact table as well as all Measurements stored within the Fact table. This default nature is not the most helpful information to business analysts since the keys have no business meanings to the users.&lt;/p&gt;&lt;p&gt;The question then is how to change this default behavior to bring back information to supply meaningful details to a business analyst when using the cube. The answer is to create a Drillthrough Action with the SSAS cube and set the Default property to True. The Drillthrough Action will return the information that the business defines as meaningful when wanting to see the details within the cube.&lt;/p&gt;&lt;p&gt;The following lists out the steps on how to create the Drillthrough Action within the SSAS project for the cube and then demonstrates how to use the Drillthrough Action in an Excel Pivot Table.&lt;/p&gt;&lt;h5&gt;Setup the Drillthrough Action&lt;/h5&gt;&lt;p&gt;In the SSAS cube, navigate to the Action table and select the icon for the New Drillthrough Action:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_Bb_dqfXVtDU/SmcmJ3NRuUI/AAAAAAAAAEk/v2NNhVbKUPk/SSAS_Drillthrough_Action%5B5%5D.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="77" alt="SSAS_Drillthrough_Action" src="http://lh6.ggpht.com/_Bb_dqfXVtDU/SmcmKDRGJNI/AAAAAAAAAEo/TvSS61_TIVg/SSAS_Drillthrough_Action_thumb%5B3%5D.jpg" width="611" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;After selecting the New Drillthrough Action, setting up the what the Action should do is the next step. For this example, the AdventureWorks cube is being used to build the action and the example will return the following fields for the sliced cell as its default:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reseller Sales Amount, Reseller Order Quantity &lt;/li&gt;&lt;li&gt;Date &lt;/li&gt;&lt;li&gt;City, State, Country &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The following screen prints lays out these fields and sets up the Default property to True:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Bb_dqfXVtDU/SmcmKrs9GvI/AAAAAAAAAEs/lnfvlLnB08I/SSAS_Drillthrough_Action_Setup%5B9%5D.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="405" alt="SSAS_Drillthrough_Action_Setup" src="http://lh6.ggpht.com/_Bb_dqfXVtDU/SmcmK7aX12I/AAAAAAAAAEw/FXLVrRnH6SY/SSAS_Drillthrough_Action_Setup_thumb%5B7%5D.jpg" width="560" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h5&gt;&lt;/h5&gt;&lt;h5&gt;Using the SSAS Action&lt;/h5&gt;&lt;p&gt;After creating the action and processing the cube, an analyst can now connect to the cube via Excel 2007 and create a Pivot table as its starting report. For the example, the report is going to select Sales Territory by Calendar Year for Reseller Sales Amount. &lt;/p&gt;&lt;p&gt;With the Pivot setup, the following methods will display the the SSAS action, note these actions can only be performed on Non Calculated Members within the cube:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Double click the cell within the Pivot Table &lt;/li&gt;&lt;li&gt;Right click on the cell to drill into and select Show Details &lt;/li&gt;&lt;li&gt;Right click on the cell and select Additional Actions--&amp;gt;AW Default Action (this is the name of our Drillthrough Action in this example). &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Right Click--&amp;gt;Show Details Menu&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_Bb_dqfXVtDU/SmcmLG5AjgI/AAAAAAAAAE0/Py0tehGkJsI/Excel_Show_Details%5B4%5D.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="241" alt="Excel_Show_Details" src="http://lh6.ggpht.com/_Bb_dqfXVtDU/SmcmLU9d6KI/AAAAAAAAAE4/Ol710nF6GGo/Excel_Show_Details_thumb%5B2%5D.jpg" width="494" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Right Click--&amp;gt;Additional Actions Menu:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_Bb_dqfXVtDU/SmcmLjoHM4I/AAAAAAAAAE8/ZGslQxja8lM/Excel_Additional_Actions%5B5%5D.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="204" alt="Excel_Additional_Actions" src="http://lh6.ggpht.com/_Bb_dqfXVtDU/SmcmL7aTLuI/AAAAAAAAAFA/GAKd64PBY3A/Excel_Additional_Actions_thumb%5B3%5D.jpg" width="299" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h5&gt;Excel Report&lt;/h5&gt;&lt;p&gt;Regardless of the method chosen, Excel will create a new Tab within the Excel workbook and display the data as defined within the Drillthrough Action:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_Bb_dqfXVtDU/SmcmMCyyXwI/AAAAAAAAAFE/RNUx4B7nmW0/Excel_Show_Details_Tab%5B10%5D.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="380" alt="Excel_Show_Details_Tab" src="http://lh5.ggpht.com/_Bb_dqfXVtDU/SmcmMVTwCdI/AAAAAAAAAFI/FM4-GNa3n-E/Excel_Show_Details_Tab_thumb%5B8%5D.jpg" width="763" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h5&gt;Conclusion&lt;/h5&gt;&lt;p&gt;As demonstrated, a Drillthrough Action within a SSAS cube is another tool for a business analyst to dive into their data and answer questions that is pertinent for the question at hand. Setting up a Drillthrough Action with the Default behavior set to True allows for the users to not see data that is meaningless to the users, since the users will not be able to translate surrogate keys to actual dimension text, but instead provides useful information to the analyst to help make business decisions. The tool of providing of this useful information is the point of developing the cube in the first place.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-3016888080225801738?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/3016888080225801738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=3016888080225801738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3016888080225801738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3016888080225801738'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/07/default-cube-action-in-excel.html' title='Default Cube Action in Excel'/><author><name>Chuck Rivel</name><uri>http://www.blogger.com/profile/05290272415899934531</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02532501760416550527'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-4469252810541024386</id><published>2009-07-21T10:43:00.003-04:00</published><updated>2009-07-21T10:53:37.103-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips and Tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><category scheme='http://www.blogger.com/atom/ns#' term='BI'/><category scheme='http://www.blogger.com/atom/ns#' term='SSRS'/><category scheme='http://www.blogger.com/atom/ns#' term='business intelligence'/><title type='text'>A Toolkit book for your BI Toolbox</title><content type='html'>As part of a ramp-up plan to get more familiar with the latest Microsoft stack of BI tools and products, a colleague suggested I take a look at The Data Warehouse Toolkit by Ralph Kimball and  Margy Ross (ISBN 978-0471200246, on &lt;a href="http://www.amazon.com/Data-Warehouse-Toolkit-Complete-Dimensional/dp/0471200247/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1247601250&amp;amp;sr=8-1"&gt;Amazon&lt;/a&gt;). I am not going to provide a detailed synopsis of each chapter, you can check the key concepts listed in the text for that, but I want share some thoughts on how I found it useful and an interesting read as well. The book follows a case study format, which helps provide real-world context to the concepts being explained.&lt;br /&gt;&lt;br /&gt;If you are new to data warehousing, the first chapter provides all the background and vocabulary you need to get started. This chapter contains explanations and descriptions of facts, dimensions, measures, etc and draws parallels to relational concepts as well.&lt;br /&gt;&lt;br /&gt;A four-step design process is laid out early in Chapter 2 and referred to throughout the book. Key here is the notion to select a business process to model. Similar to other database or software development efforts, you need to start with the business requirements first. This is no different in a data warehouse design. The concepts of a data warehouse bus architecture and bus matrix are introduced in Chapter 3. While it’s not exactly the same as an Enterprise Service Bus, occasionally seen in a software solution, there are definitely some parallel ideas.&lt;br /&gt;&lt;br /&gt;The case studies in the early chapters start out simple and somewhat generic, but they help illustrate the basic design principals. The more complex case studies in later chapters still provide a good reference for more complex models, techniques, and industry specific scenarios.&lt;br /&gt;&lt;br /&gt;A chapter near the end of the book pulls it all together with a project lifecycle description to design and build a data warehouse. Here again, not too different from any other software development effort: gather requirements, design, implement, test, communicate with stakeholders, etc.&lt;br /&gt;&lt;br /&gt;Overall, I found the book very useful and plan to keep it handy as a companion reference. I was able to apply some of the modeling techniques directly in a solution leveraging Microsoft SQL Server 2008 Analysis Services, Integration Services and Reporting Services.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-4469252810541024386?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/4469252810541024386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=4469252810541024386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4469252810541024386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/4469252810541024386'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/07/toolkit-book-for-your-bi-toolbox.html' title='A Toolkit book for your BI Toolbox'/><author><name>Chris</name><uri>http://www.blogger.com/profile/06517951200558072779</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='00771666188430706849'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-5441067636453366919</id><published>2009-07-17T11:08:00.002-04:00</published><updated>2009-07-17T11:12:11.111-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>Using a View for a Fact Table in SSAS Project</title><content type='html'>&lt;p&gt;I recently was involved in building a custom data warehouse and 2005 SSAS cubes which contained many financial calculations off of the original data. Many of the calculations needed to be at the grain level of the warehouse before aggregations could be applied and therefore it made sense to perform these calculations as Named Calculations in the Data Source View (DSV). After the fields were added to the DSV, the new fields were added to the cube and then MDX calculated members were created in the cube for the final calculations to be consumed by the business users.&lt;/p&gt;&lt;p&gt;However, after many Named Calculations were added to the DSV, the performance of processing the SSAS partitions was becoming very poor and from looking at the SQL that the SSAS project was generating, it was clearly not optimized.&lt;/p&gt;&lt;p&gt;The solution was to create a database view that had the optimized SQL code containing the granular calculations and then within the DSV, replace the Fact table with the view. The following screen print displays the menu that appears by right clicking on the table to be replaced within the DSV and then navigating to the Replace Table\With Other Table option:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Bb_dqfXVtDU/SmCT7T3NBNI/AAAAAAAAAEU/DQUzxD0_5Ts/DS_Replace_Table%5B2%5D.jpg"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="89" alt="DS_Replace_Table" src="http://lh5.ggpht.com/_Bb_dqfXVtDU/SmCT7pkCXWI/AAAAAAAAAEY/cWhXe-XgKJY/DS_Replace_Table_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;The view also provided a benefit for the SSAS partitions that were created by being able to setup each partition as a SELECT * from VIEW WHERE &lt;em&gt;condition&lt;/em&gt;. The SELECT * allowed for more fields to be added to the view without having to go back into each SSAS partition and recreate the SQL that made up the partition for the additional field. Originally, all of the SSAS cube partitions had the non-optimized SQL code as the source and any additions to the FACT table would require going back to each partition and adding the new field to each and every partition created. Considering were had 150 partitions, this was not an enviable position to be going forward.&lt;/p&gt;&lt;p&gt;However, one property within the DSV needed to be changed to ensure that the DSV did not lose all of the relationships that were previously defined when originally using the Fact table itself. The warehouse had FK relationships amongst the Fact table and the many dimensions that joined to the Fact table. When the DSV was originally created, the relationships were read from the data source and automatically created. When replacing the table with a view, the relationships are not pointing to the view within the database and when you hit OK, you see all of your relationships disappear! &lt;/p&gt;&lt;p&gt;The fix for this problem is to change the DSV RetrieveRelationships property to False. The plus, you do not lose your relationships already defined in the DSV. The minus, you must manually create any new relationships that exist going forward, which is an acceptable task considering the many relationships that would have been lost and any future refreshing of the DSV would eliminate the relationships that were recreated.&lt;/p&gt;&lt;p&gt;The following screen print displays the location of the RetrieveRelationships property to update:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_Bb_dqfXVtDU/SmCT76do9pI/AAAAAAAAAEc/BdKFGh8OnJ4/DSV_Properties%5B2%5D.jpg"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="244" alt="DSV_Properties" src="http://lh5.ggpht.com/_Bb_dqfXVtDU/SmCT8MVIIVI/AAAAAAAAAEg/6fKIyDX80oM/DSV_Properties_thumb.jpg" width="234" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;The final result of changing the Fact table from the warehouse with Named Calculations to a SQL Database View was being able to update the processing time for each partition from the SSAS generated query that was taking minutes to return to retrieving the same data within seconds by using the SQL Database View. In addition, we were able to improve the maintenance of the partitions for field updates from a painstaking manual update procedure and then a cube process to simply reprocessing the cube when field changes were made.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-5441067636453366919?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/5441067636453366919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=5441067636453366919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/5441067636453366919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/5441067636453366919'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/07/using-view-for-fact-table-in-ssas.html' title='Using a View for a Fact Table in SSAS Project'/><author><name>Chuck Rivel</name><uri>http://www.blogger.com/profile/05290272415899934531</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02532501760416550527'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-3667541700582912788</id><published>2009-06-23T10:18:00.003-04:00</published><updated>2009-06-23T10:31:23.142-04:00</updated><title type='text'>Reporting Services and SharePoint - Context Expired Exception</title><content type='html'>&lt;strong&gt;Problem&lt;/strong&gt;&lt;br /&gt;At one of our client locations, developers and users complained of issues in accessing reports within SharePoint. The error was not occurring consistently. We quickly decided that since it wasn't happening every time, it may be a web-front-end (WFE) issue (as there are three WFEs  load-balanced together) . After thinking about this, we narrowed it down to one of the WFEs.&lt;br /&gt;&lt;br /&gt;When trying to open a report or even looking at a data source, SharePoint would throw an exception: "&lt;em&gt;Report Server has encountered a SharePoint error. ---&gt; Microsoft.SharePoint.SPException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317)&lt;/em&gt; " . The full error message is at the bottom of this post.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br /&gt;I tried the usual remedy steps such as IISRESET and rebooting the server. I then tried to repair the RS Add-In and even run the SharePoint Configuration Wizard. Nothing was working but I did notice in the logs that the timestamps were not the right time.&lt;br /&gt;&lt;br /&gt;After several other (almost) drastic actions, I decided to fix the clock on the server to have the correct time. Voila! This resolved the context issue and everything started working. The clock was so much different than any client machine that the security context was assumed to be expired.&lt;br /&gt;&lt;br /&gt;Sometimes a simple thing can cause major problems and sometimes major problems can be fixed by a simple solution.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Full Error Message&lt;/strong&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;System.Web.Services.Protocols.SoapException: Report Server has encountered a SharePoint error. ---&gt; Microsoft.ReportingServices.Diagnostics.Utilities.SharePointException: Report Server has encountered a SharePoint error. ---&gt; Microsoft.SharePoint.SPException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317) ---&gt; System.Runtime.InteropServices.COMException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317)   --- End of inner exception stack trace ---   at Microsoft.ReportingServices.WebServer.ReportingService2005Impl.GetDataSourceContents(String DataSource, DataSourceDefinition&amp;amp; Definition)   at Microsoft.ReportingServices.WebServer.ReportingService2006.GetDataSourceContents(String DataSource, DataSourceDefinition&amp;amp; Definition) &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-3667541700582912788?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/3667541700582912788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=3667541700582912788' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3667541700582912788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/3667541700582912788'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/06/reporting-services-and-sharepoint.html' title='Reporting Services and SharePoint - Context Expired Exception'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-371641895734647973</id><published>2009-06-05T11:42:00.002-04:00</published><updated>2009-06-05T12:06:45.276-04:00</updated><title type='text'>PerformancePoint Connection issues</title><content type='html'>I have been troubleshooting some PerformancePoint connection issues in setting up a new instance of PPS and, as you may or may not know, getting the configuration right can be a challenge. There's lots of good info online about setting up the Application Pool (&lt;a href="http://nickbarclay.blogspot.com/2007/11/pps-data-source-connection-problems.html"&gt;Nick Barclay has a particularly good post&lt;/a&gt;), but for those not familiar with certain applications, sometimes what's NOT said can give you fits.&lt;br /&gt;&lt;br /&gt;Case in point - when making identity changes to the App Pool, BE SURE TO RESET IIS or those changes aren't in effect. (Recycling the App Pool is not sufficient.)&lt;br /&gt;&lt;br /&gt;For those not familiar, the easiest way to cycle IIS is to open a command prompt and enter IISRESET. It's a quick process, but as always, be sure to coordinate with anyone else that may be using web services at that time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-371641895734647973?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/371641895734647973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=371641895734647973' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/371641895734647973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/371641895734647973'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/06/performancepoint-connection-issues.html' title='PerformancePoint Connection issues'/><author><name>Jim Pletscher</name><uri>http://www.blogger.com/profile/10792906609505822758</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13067548512495526067'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-8673712347295648234</id><published>2009-06-02T10:13:00.008-04:00</published><updated>2009-06-02T11:18:31.641-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting Services'/><category scheme='http://www.blogger.com/atom/ns#' term='sharepoint'/><category scheme='http://www.blogger.com/atom/ns#' term='Report Viewer'/><category scheme='http://www.blogger.com/atom/ns#' term='HTTP Handlers'/><category scheme='http://www.blogger.com/atom/ns#' term='SSRS 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='MOSS 2007'/><title type='text'>Coexistence of Report Viewer Versions 8.x and 9.x in SharePoint</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:verdana;"&gt;In one of our clients' SharePoint environments, both Report Viewer version 8.x and Report Viewer 9.x were installed. The assemblies can live together in the Global Assembly Cache (GAC) because of the different versions. The development team had created a custom reporting interface solution using the Report Viewer 9.x version(s) of the assemblies and controls. In order for the pages to render properly, an entry under HTTP Handlers within the web configuration (web.config) was required:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;add verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, &lt;strong&gt;Version=9.0.0.0&lt;/strong&gt;, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /&gt;&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;This was fine. However, the SharePoint usage report page would not render because it requires the Version 8.0.0.0 HTTP Handler entry. The error message actually stated that that the line was missing. It wasn't missing, it was in there:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;add verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, &lt;strong&gt;Version=8.0.0.0&lt;/strong&gt;, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;It came first in the HTTP Handler section and we quickly realized that the last entry for the same path wins the battle. There seems to be no way of having two HTTP Handlers for the same path (which make sense). So in our case, either the custom reporting solution was broken or the Site Usage reports would not work; this would not be acceptable for long. &lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:verdana;"&gt;I needed to find away to have both Version 8.0.0.0 and Version 9.0.0.0 work within the same web application. I tried various configuration settings and "hacks" in attempt to get it to work until finally I noticed something in the Reporting Services web config. There was some sort of an assembly redirect to tell IIS (ultimately) to use a different version of an assembly. It wasn't the assembly I was dealing with but I figured I may be able to use the same approach.&lt;br /&gt;&lt;br /&gt;Therefore, within the SharePoint web.config for port 80, I entered the following within the &amp;lt;runtime&amp;gt; &amp;lt;assembly binding&amp;gt; section under the &amp;lt;system.web&amp;gt; settings :&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;dependentAssembly&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;assemblyIdentity name="Microsoft.ReportViewer.WebForms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;bindingRedirect &lt;strong&gt;oldVersion="8.0.0.0" &lt;/strong&gt;&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;newVersion="9.0.0.0"/&lt;/strong&gt;&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;/dependentAssembly&gt;&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;add type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" path="Reserved.ReportViewerWebControl.axd" verb="*"&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Essentially, this was telling SharePoint that "if you are looking for the 8.0.0.0 version, use the 9.0.0.0 instead". This allowed the Site Usage page to at least render! It rendered with all of the web parts however the web parts all contained the same error message. They were now looking for the 9.0.0.0 version of the Microsoft.ReportViewer.ProcessingObjectModel assembly which didn't exist. I looked in the GAC and there was only the Version 8.0.0.0 in there. So I figured this was probably deprecated with the latest Report Viewer updates for SharePoint.&lt;br /&gt;&lt;br /&gt;So I decided to be tricky and use the same redirect for the Microsoft.ReportViewer.ProcessingObjectModel assembly but using the opposite version settings:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;dependentAssembly&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;assemblyIdentity name="Microsoft.ReportViewer.ProcessingObjectModel" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;bindingRedirect &lt;strong&gt;oldVersion="9.0.0.0"&lt;/strong&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;newVersion="8.0.0.0"&lt;/strong&gt;/&gt; &lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;/dependentAssembly&gt;&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;This actually worked! The Site Usage reports rendered and the development team's custom reporting interfaces were still functioning. We thought we were going to have to apply MOSS 2007 SP2 and/or SQL Server SP3 and worse case open a case ticket with Microsoft Support - not anymore!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-8673712347295648234?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/8673712347295648234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=8673712347295648234' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8673712347295648234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/8673712347295648234'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/06/coexistence-of-report-viewer-versions.html' title='Coexistence of Report Viewer Versions 8.x and 9.x in SharePoint'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-6173850691490248351</id><published>2009-05-14T16:47:00.001-04:00</published><updated>2009-05-14T16:47:25.848-04:00</updated><title type='text'>SSAS and Dynamic Excel Reports</title><content type='html'>&lt;p&gt;Excel can be a very powerful tool for allowing power users to analyze data in cubes.&amp;#160; However it is also possible to create dynamic reports using Excel.&amp;#160; This can be accomplished using &lt;a href="http://office.microsoft.com/en-us/excel/HA100830261033.aspx"&gt;Excel Cube functions&lt;/a&gt;.&amp;#160; Cube functions allow you to create the same type of functionality achieved in a pivot table but in a individual cell.&amp;#160; Then utilizing other Excel functions it is possible to parameterize the report making it dynamic.&lt;/p&gt;  &lt;p&gt;For this example, I will use one of the Adventures Works Cubes.&amp;#160; The first step is to create a pivot table that contains the information we want.&amp;#160; For this example I created a comparison of Internet Gross Profit sales for current month, prior month and the same month a year ago.&amp;#160; This data is further divided by primary sales territory.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_88umxTZ-ciA/SgyDURnsJ9I/AAAAAAAAAHk/e3JTEZ-yWIM/s1600-h/PivotTable3.jpg"&gt;&lt;img title="PivotTable" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="213" alt="PivotTable" src="http://lh4.ggpht.com/_88umxTZ-ciA/SgyDUlEpJVI/AAAAAAAAAHo/VeMdNeRlhu8/PivotTable_thumb1.jpg?imgmax=800" width="377" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Personally I found that using the Cube Functions in the formula editor to be complicated.&amp;#160; Thankfully there is a menu option in Excel 2007 that can help.&amp;#160; It is called ‘Convert to Formulas’ and is found in the PivotTable Tools –&amp;gt; OLAP Tools menu.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_88umxTZ-ciA/SgyDVu6J3NI/AAAAAAAAAHs/I1Z3kNUqVGg/s1600-h/ConvertToFormulas3.jpg"&gt;&lt;img title="ConvertToFormulas" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="148" alt="ConvertToFormulas" src="http://lh5.ggpht.com/_88umxTZ-ciA/SgyDWUKj_cI/AAAAAAAAAHw/QcKjNq5Nugg/ConvertToFormulas_thumb1.jpg?imgmax=800" width="427" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Once this table has been converted we can analyze a few key cells to understand what is going on. The first is A3 where the measure is located. (All cell references relate to the image of the pivot table above.) This cell now contains the formula:&lt;/p&gt;  &lt;p&gt;=CUBEMEMBER(&amp;quot;AdventureWorksDW&amp;quot;,    &lt;br /&gt;&amp;quot;[Measures].[Internet Gross Profit]&amp;quot;)&lt;/p&gt;  &lt;p&gt;The function CUBEMEMBER allows you to select the measure.&amp;#160; If you edit the text you can select other measures, just delete all the text inside quote after this ‘[Measures].[’ and Excel will offer other options.&lt;/p&gt;  &lt;p&gt;The second cell we want to inspect is B8 (or any other value cell.)&lt;/p&gt;  &lt;p&gt;=CUBEVALUE(&amp;quot;AdventureWorksDW&amp;quot;,$A$3,$A8,B$7)&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You can see that this cell just contains the name of the data source and references to other cells.&amp;#160; One thing to note is that not all cells that were in the pivot table are used by the cube functions so they can be deleted.&amp;#160; Here is my cleaned up table.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_88umxTZ-ciA/SgyDWkCPaHI/AAAAAAAAAH0/OpP77fA2xtc/s1600-h/ConvertedTable3.jpg"&gt;&lt;img title="ConvertedTable" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="200" alt="ConvertedTable" src="http://lh5.ggpht.com/_88umxTZ-ciA/SgyDW4tZOaI/AAAAAAAAAH4/85fu0l6mjG4/ConvertedTable_thumb1.jpg?imgmax=800" width="445" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The next step is to parameterize the dates reference in my converted table so that we can make the report dynamic.&amp;#160; Evaluating the cell D4 will help us do that.&lt;/p&gt;  &lt;p&gt;=CUBEMEMBER(&amp;quot;AdventureWorksDW&amp;quot;,&amp;quot;[Date].[Calendar].[Month].&amp;amp;[2004]&amp;amp;[5]&amp;quot;)&lt;/p&gt;  &lt;p&gt;You can see that the year and month number are used, however this will vary depending on how the time dimension in your cube is setup.&amp;#160; The first step is to place the date to drive the report into cell B1.&amp;#160; Then change the formulas in B4, C4, and D4 to use this date.&lt;/p&gt;  &lt;p&gt;I replaced the formulas in cells B4 and D4 with the ones below.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;B4: &lt;/strong&gt;=CUBEMEMBER(&amp;quot;AdventureWorksDW&amp;quot;, CONCATENATE(&amp;quot;[Date].[Calendar].[Month].&amp;amp;[&amp;quot;,YEAR(B1)-1,&amp;quot;]&amp;amp;[&amp;quot;,MONTH(B1),&amp;quot;]&amp;quot;))&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;D4: &lt;/strong&gt;=CUBEMEMBER(&amp;quot;AdventureWorksDW&amp;quot;,     &lt;br /&gt;CONCATENATE(&amp;quot;[Date].[Calendar].[Month].&amp;amp;[&amp;quot;,YEAR(B1),&amp;quot;]&amp;amp;[&amp;quot;,MONTH(B1),&amp;quot;]&amp;quot;))&lt;/p&gt;  &lt;p&gt;The only difference is we subtract 1 year from cell B4.&amp;#160; Cell C4 is a little more difficult because when the current month is January the prior month is December of the prior year.&amp;#160; If it is January the we need to add an if statement to see if we need to subtract 1 form the the year and set the month to 12.&amp;#160; If not we can just subtract 1 from the month number.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;C4: &lt;/strong&gt;=CUBEMEMBER(&amp;quot;AdventureWorksDW&amp;quot;, CONCATENATE(&amp;quot;[Date].[Calendar].[Month].&amp;amp;[&amp;quot;,IF(MONTH(B1)=1,YEAR(B1)-1,YEAR(B1)),&amp;quot;]&amp;amp;[&amp;quot;,IF(MONTH(B1)=1,12,MONTH(B1)-1),&amp;quot;]&amp;quot;))&lt;/p&gt;  &lt;p&gt;The final spreadsheet now looks like the image below but now the data in the table, which is pulled from the cube can be updated by changing the date in cell B2.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_88umxTZ-ciA/SgyDXCsoZOI/AAAAAAAAAH8/SbroKXqfVJo/s1600-h/PivotFinal3.jpg"&gt;&lt;img title="PivotFinal" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="192" alt="PivotFinal" src="http://lh3.ggpht.com/_88umxTZ-ciA/SgyDXcLtL9I/AAAAAAAAAIA/RmGDW42zOPc/PivotFinal_thumb1.jpg?imgmax=800" width="446" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is a straightforward example but could easily be expanded to handle more complex cases.&amp;#160; Graph data can also be updated using the same methodology.&amp;#160; So it is possible to see that this now gives you a complete report authoring environment that you can give to Excel power users and allow them to build their own reports from the cubes your organization has built.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-6173850691490248351?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/6173850691490248351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=6173850691490248351' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6173850691490248351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6173850691490248351'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/05/ssas-and-dynamic-excel-reports.html' title='SSAS and Dynamic Excel Reports'/><author><name>Andrew Crowder</name><uri>http://www.blogger.com/profile/03742717900986525365</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07243691811963446706'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-1277428816036876839</id><published>2009-05-12T13:53:00.001-04:00</published><updated>2009-05-12T13:53:20.575-04:00</updated><title type='text'>Connecting to DB2 on AS/400 via OLE DB</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;To connect to a DB2 database via OLE DB, you’ll need the&amp;#160; &lt;a href="http://go.microsoft.com/fwlink/?LinkId=123713&amp;amp;clcid=0x409" target="_blank"&gt;Microsoft OLEDB Provider for DB2&lt;/a&gt; (IBM also has one), which is part of the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=228DE03F-3B5A-428A-923F-58A033D316E1&amp;amp;displaylang=en" target="_blank"&gt;Microsoft SQL Server 2008 Feature Pack&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;After installing the provider, there are several ways you can test connectivity: creating a &lt;a href="http://msdn.microsoft.com/en-us/library/e38h511e(VS.71).aspx" target="_blank"&gt;UDL&lt;/a&gt; file, using the “Data Access Tool” that ships with the Microsoft provider, or creating an OLE DB Connection in BIDS to name a few.&amp;#160; Below is a screen shot of the test connection’s property grid.&amp;#160; As you might expect, I’ve replaced the values of user id, IP address, schema, etc., with fake ones.&amp;#160; Properties to note are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;DBMS Platform: in my case, this is DB2\AS400 &lt;/li&gt;    &lt;li&gt;Default Schema: same as the library name in DB2.&amp;#160; Ex., the library name in the following query is “LIBNAME”: “SELECT * FROM LIBNAME.FILENAME” &lt;/li&gt;    &lt;li&gt;Package Collection: same as above &lt;/li&gt;    &lt;li&gt;Initial Catalog: Your AS/400 DBA should be able to provide this.&amp;#160; Or, if you have access to a linked server, expand it in SSMS and you should see the catalog name. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;At this point, my test connections were unsuccessful.&amp;#160; But the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=123713&amp;amp;clcid=0x409" target="_blank"&gt;Microsoft OLEDB Provider for DB2&lt;/a&gt; ships with a handy “SNA Trace Utility” that revealed more information:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_VWZZ_o4YP0g/Sgm3hC9bPAI/AAAAAAAAAO4/3Q_2WHS5v-U/s1600-h/DB2PropertyGrid13.jpg"&gt;&lt;img title="DB2PropertyGrid" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="697" alt="DB2PropertyGrid" src="http://lh6.ggpht.com/_VWZZ_o4YP0g/Sgm3h-3NK5I/AAAAAAAAAO8/77_xQJ9FRrI/DB2PropertyGrid_thumb9.jpg?imgmax=800" width="304" align="right" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;|00000f50.000008b0 DDM&amp;#160;&amp;#160; 001B1153 E4E2C5D9 40C5E7C9 E340C4C5 D5C9C5C4 40C1C3C3 C5E2E2&amp;#160; &lt;br /&gt;|00000f50.000008b0 DRDA AR message: Name: RDBATHRM, Severity: Error, Diagnostic: USER EXIT DENIED ACCESS, Database: S1033BC1     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Notice the DRDA “DENIED ACCESS” message. Interestingly, the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=123713&amp;amp;clcid=0x409" target="_blank"&gt;Microsoft OLEDB Provider for DB2&lt;/a&gt; uses the &lt;a href="http://msdn.microsoft.com/en-us/library/ms945194.aspx" target="_blank"&gt;DRDA&lt;/a&gt; protocol.&amp;#160; Below is a screenshot from a 5250 session with the AS/400.&amp;#160; Notice the configuration setting “DDM / DRDA request access”, which is configured to reject all DDM / DRDA connections.&amp;#160; Changing this value to “*OBJAUT” resolved the issue.&amp;#160; For more information, see the &lt;a href="http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/cl/chgneta.htm" target="_blank"&gt;CHGNETA Command Description&lt;/a&gt; and look for DDMACC&amp;#160; (DDM / DRDA request access).&amp;#160; See also &lt;a href="http://support.microsoft.com/kb/246714" target="_blank"&gt;Microsoft KB article 246714&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_VWZZ_o4YP0g/Sgm3i3hlczI/AAAAAAAAAPA/YWNSsg2xU-o/s1600-h/WIN5250.jpg"&gt;&lt;img title="WIN5250" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="499" alt="WIN5250" src="http://lh4.ggpht.com/_VWZZ_o4YP0g/Sgm3jy3neRI/AAAAAAAAAPE/pMmpOUDsltE/WIN5250_thumb.jpg?imgmax=800" width="705" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-1277428816036876839?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/1277428816036876839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=1277428816036876839' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1277428816036876839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/1277428816036876839'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/05/connecting-to-db2-on-as400-via-ole-db.html' title='Connecting to DB2 on AS/400 via OLE DB'/><author><name>Ben Black</name><uri>http://www.blogger.com/profile/14280449779781344832</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03990576817957315526'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-6782173006801096012</id><published>2009-05-01T16:29:00.002-04:00</published><updated>2009-05-01T16:36:05.201-04:00</updated><title type='text'>Non-Standard uses for SSIS Package Configurations</title><content type='html'>&lt;strong&gt;&lt;em&gt;by Joe Toscano, RDA&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;SQL Server Integrations Services Package Configurations: Much more than dynamic connections &lt;/strong&gt;&lt;br /&gt;Package Configurations in SSIS allow you to dynamically change object property values such as a connection’s ConnectString simply by changing a row in a SSIS Package Configuration table or an XML Configuration File. They make your SSIS solution much more flexible in many ways and while connection strings are tops on the package configuration hit list, this blog entry discusses additional ways one can take advantage of SSIS Package Configurations.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why do we need Package Configurations?&lt;br /&gt;&lt;/strong&gt;Think about how this feature can be used. As your SSIS packages moves up the food chain from Development to Test and eventually to Production, you may need to change many package attributes along the way. Maybe while in TEST, your packages extracted sample data from a partial copy of the production data. Maybe while in TEST your package wrote to a TEST destination (SQL Instance), or FTP-ed files to a ftp development folder from an FTP TEST Site. Finally, maybe while in TEST your solution emailed a group of developers if there were any package failures. What if you thoroughly tested your SSIS solution in this environment and you are ready to move your solution into production?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scary memories of DTS and package promotion / deployment&lt;br /&gt;&lt;/strong&gt;If you worked with SQL Server 2000’s DTS, one of the only ways to do deploy a package to a new server was while in the DTS Package Editor issue a Package à Save As and change the SQL Instance where the Package physically resides. Once this was done, in many cases you had to then manually change all of the connections to point to the correct product-mode sources and destinations. This was a painstakingly manual process. In many cases, many other package attributes needed to change in addition to sources and destinations. Enter SSIS Package Configurations. They allow you to modify rows in a Package Configuration Table or XML configuration file to achieve the same end-result.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How Package Configurations Work&lt;/strong&gt;&lt;br /&gt;While there are several types of Package Configurations in this example we have chosen to store our package configuration / dynamic values in a SQL Server table. Further, we have chosen to create a database called SSIS that contains our package configuration tables along with some other tables and stored procedures used by our auditing subsystem. SSIS allows you to define a Package Configuration Environment Variable, and we use this to store a connect string to the SQL Instance that houses this SSIS database. Our environment variable was called SSISPACKAGECONFIGURATIONS. We maintain multiple copies of the PackageConfiguration table each with different values to support the different environment. For example – we have one package configuration table that is used in my local development environment to point to my local SQL 2005 Developers Edition, while another was created for our shared test SQL Instance and yet another for our official production SQL Instance.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Both standard and non-standard Package Configuration Examples&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;SSIS package Configurations are easily created in Business Intelligence Development Studio. (SSIS -&gt; Package Configurations)&lt;br /&gt;Let’s look at our package configuration categories and provide a typical Business Intelligence Development Studio (BIDS) Solution that utilizes them:&lt;br /&gt;&lt;br /&gt;1. &lt;strong&gt;Source and Destination Connections and directories&lt;br /&gt;&lt;/strong&gt;SSIS Package configurations can be used to hold the connection strings for our connections to our SSIS, Stage and SalesDW databases which are databases used by our solution. In this solution, we are extracting monthly sales data from a FTP Site, so we can dynamically store the directories used to support this operation along with the FTP security credentials.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;a. SSIS, Stage and SalesDW OLEDB Connections&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;These represent standard OLEDB connections used by packages as either a source or destination. This may the most common use for package configurations. For these package configurations we choose to designate the ConnectString property of these connections making it the dynamic property we can easily change.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;b. FTP Working Directory&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;Our solution uses an ftp .bat file and ftp scripts to drive the FTP get and put commands. We’ve found this gave us more flexibility than using the SSIS FTP task. This package variable designates the directory that houses the .bat and script files used by the FTP command. We had one location while our solution was in development, but in production our servers were clustered so we couldn’t reference a server’s local drive.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;c. FTP Local Directory, FTP Remote Directory&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;Once connected to the FTP site you can change your local and remote directories using the lcd the cd commands. The local directory setting determined where files resided after they were gotten using the FTP mget command. As packages moved from development to test to production these did need to change so creating package variables whose values were package configuration items saved us on package maintenance.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;d. SSIS Package Directory&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;Initially this was set to the ‘working directory’ while we were working with the SSIS Solution in the Business Intelligence Development Studio. (In our case, the working directory was a SourceSafe local working directory setting) Once the packages were deployed to a production server, this changed in the package configuration table present in the production server to the actual deployment path on the production server. (for our solution, we stored our package files in the file system as opposed to in SQL Server)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. FTP Attributes&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;We’ve found that while in development mode we relied on a test FTP instance, but once our solution was deployed to production we were asked to use the official production site. All security credentials changed; therefore, storing these as package variables whose values were package configuration items saved us on package maintenance.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;a. FTP Site Name, FTP Login, FTP Password &lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;The FTP Security credentials were stored in package variables as package configuration items. This allows us to easily make changes without having to modify our SSIS Solution. Instead, we modified rows in the package configuration table.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;b. FileToExtract&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;Our FTP site supported the use file wildcards (% matched any single character) and we were able designate the file to extract making the Year and Month (YYMM) portion of the file match any year and month. This way no matter what files were dropped to our FTP Site, our solution would auto-discover them and then extract and load them.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;c. ParentTraceMode&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;We’ve found that while in development mode we actually wanted to the FTP results. What files did FTP get or what files did FTP move/rename. At first, this wasn’t possible because the FTP window appeared and disappeared too quickly since we were working with very small files. We decided to create a package variable called ParentTraceMode whose value is obtained from the calling parent using the Parent Package Configuration. If this value is set to 1, SSIS Precedence Constraints force the execution of a trace mode FTP command that simply does not provide the ending FTP quit statement. Sounds simple, but without the quit command the FTP window stays displayed for us to visually inspect. I found this trace flag also useful to direct the flow of the package to enable other tasks such as Script Tasks the display useful information via message boxes. Also, our FTP processing normally cleans up after itself by removing the FTP Script files that were just used. Good thing because there’s some sensitive security credentials in this file! With trace mode enable these script files remain in the FTP Working Directory for inspection.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. Email Recipients&lt;br /&gt;&lt;/strong&gt;While in development our email recipients were hard-coded to be our development team members. As we got close production deployment, we realized there were many more interested parties; therefore, this list was changed to a package variable whose value was a package configuration.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;a. EmailRecipients&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;Stores a semi-colon separated list of email recipients. This package variable is then passed to our stored procedure that sends out an SMTP Email notification.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4. Auditing Related Configurations&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The auditing subsystem uses package configurations extensively. Below one package configuration example:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:85%;"&gt;a. ParentPgkID&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;Each package is assigned a unique identifier by the auditing subsystem. This is a parent package configuration (a package configuration value obtains from the calling or parent package) that allows track parent and child package execution hierarchy from our auditing tables. This has proven very useful since it is very common to have a master package whose job it is to execute all extract and load packages in the correct order – thereby producing an entire batch extract and run.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-6782173006801096012?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/6782173006801096012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=6782173006801096012' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6782173006801096012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/6782173006801096012'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/05/non-standard-uses-for-ssis-package.html' title='Non-Standard uses for SSIS Package Configurations'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-185240311336314031</id><published>2009-04-15T13:44:00.006-04:00</published><updated>2009-04-15T15:15:08.878-04:00</updated><title type='text'>Sales for past six months using SQL Pivot Operator</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Problem Statement&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;A simple revenue report needed to be generated that displays the summarized revenue dollars for each customer from a SalesDetail table. The YYMM column that holds the year and month ('0904' = April, 2009 ...). This YYMM column show be transposed and displayed as a column header in the report rather than have it display in each row of data.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Background&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;Each month, we get revenue new data that is appended to the SalesDetails table. At first, we simply modified the SQL Code that is generated the report data to include the new month's data. Each month our report got a bit wider, but it was nice to see all of our past data and new total revenue. Our client decided that they would rather have a no-maintenance solution that simply reports on the most recent 6 months (They didn't need to go back any further). This way they didn't have to make any report changes from month-to-month.&lt;br /&gt;&lt;br /&gt;Using PIVOT Operator, we had the report working by hard-coding each YYMM value, but we are looking for a solution without any hard-coding. Here is the sample of SQL using hard-coded YYMM values&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;color:#3333ff;"&gt;SELECT&lt;br /&gt;             CustomerNumber,&lt;br /&gt;             CustomerName,&lt;br /&gt;             [0810] as 'Oct 2008 Revenue',&lt;br /&gt;            [0811] as 'Nov 2008 Revenue',&lt;br /&gt;            [0812] as 'Dec 2008 Revenue',&lt;br /&gt;            [0901] as 'Jan 2009 Revenue',&lt;br /&gt;            [0902] as 'Feb 2009 Revenue',&lt;br /&gt;             [0903] as 'Mar 2009 Revenue',&lt;br /&gt;            [0904] as 'Apr 2009 Revenue',&lt;br /&gt;            [0810] + [0811] + [0812] + [0901] + [0902] + [0903] + [0904] as 'Total Revenue'&lt;br /&gt;FROM&lt;br /&gt;           (SELECT&lt;br /&gt;                               CustomerNumber, CustomerName, Revenue, YYMM&lt;br /&gt;             FROM SalesDetails&lt;br /&gt;          ) SD&lt;br /&gt;        PIVOT&lt;br /&gt;        ( SUM(Revenue) FOR YYMM IN ([0810], [0811], [0812], [0901], [0902], [0903], [0904])) as pvt&lt;br /&gt;ORDER BY&lt;br /&gt;         CustomerNumber, CustomerName&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Solution&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;This problem can be solved using PIVOT operator and without Hard-coding the YYMM values, but getting the column names as mentioned in the sample SQL above could be difficult.&lt;br /&gt;&lt;br /&gt;PIVOT Operator works on fixed number of attribute values. Hence the number of values cannot be dynamic. Hence I tried work around this issue.&lt;br /&gt;&lt;br /&gt;Here is SQL to create the Table and load sample data&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="color:#3333ff;"&gt;CREATE TABLE dbo.SalesDetails&lt;br /&gt;(&lt;br /&gt;YYMM CHAR(4) NULL,&lt;br /&gt;CustomerName VARCHAR(64) NULL,&lt;br /&gt;CustomerNumber VARCHAR(32) NULL,&lt;br /&gt;Revenue MONEY NULL&lt;br /&gt;)&lt;br /&gt;GO&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;----- Sept 2008 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0809', 'Sears' ,'11111', $34.07)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0809', 'Sears' ,'11111', $24.07)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0809', 'Kmart' ,'22222', $41.11)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0809', 'Kmart' ,'22222', $1.78)&lt;br /&gt;--- Oct 2008 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0810', 'Sears' ,'11111', $34.99)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0810', 'Sears' ,'11111', $124.00)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0810', 'Sears' ,'11111', $11.11)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0810', 'Kmart' ,'22222', $61.78)&lt;br /&gt;--- Nov 2008 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0811', 'Sears' ,'11111', $84.39)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0811', 'Kmart' ,'22222', $124.00)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0811', 'Kmart' ,'22222', $11.11)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0811', 'Kmart' ,'22222', $61.78)&lt;br /&gt;--- Dec 2008 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0812', 'Sears' ,'11111', $2.99)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0812', 'Sears' ,'11111', $41.81)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0812', 'Kmart' ,'22222', $283.23)&lt;br /&gt;--- Jan 2009 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Sears' ,'11111', $2.99)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Sears' ,'11111', $41.81)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Kmart' ,'22222', $43.44)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Kmart' ,'22222', $10.34)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Kmart' ,'22222', $29.00)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0901', 'Kmart' ,'22222', $111.34)&lt;br /&gt;--- Feb 2009 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Sears' ,'11111', $2.99)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Sears' ,'11111', $41.81)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Kmart' ,'22222', $43.44)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Kmart' ,'22222', $10.34)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Kmart' ,'22222', $29.00)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0902', 'Kmart' ,'22222', $111.34)&lt;br /&gt;--- Mar 2009 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0903', 'Sears' ,'11111', $12.89)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0903', 'Sears' ,'11111', $21.81)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0903', 'Kmart' ,'22222', $33.40)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0903', 'Kmart' ,'22222', $110.94)&lt;br /&gt;--- Apr 2009 Sales&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0904', 'Sears' ,'11111', $14.89)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0904', 'Sears' ,'11111', $15.81)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0904', 'Kmart' ,'22222', $13.40)&lt;br /&gt;INSERT dbo.SalesDetails VALUES ('0904', 'Kmart' ,'22222', $156.94)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since PIVOT works on fixed set of Attributes, I used a CASE statement and passed parameters to segregate past 6 months data as [SIXTHMONTH], [FIFTHMONTH], [CURRENTMONTH] etc. I used this new fixed attributes in the PIVOT portion. Here is the solution&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;color:#3333ff;"&gt;DECLARE @SixthLastMonth char(4)&lt;br /&gt;DECLARE @FifthLastMonth char(4)&lt;br /&gt;DECLARE @FourthLastMonth char(4)&lt;br /&gt;DECLARE @ThirdLastMonth char(4)&lt;br /&gt;DECLARE @SecondLastMonth char(4)&lt;br /&gt;DECLARE @LastMonth char(4)&lt;br /&gt;DECLARE @CurrentMonth char(4)&lt;br /&gt;&lt;br /&gt;SELECT @SixthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -6, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @FifthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -5, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @FourthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -4, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @ThirdLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -3, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @SecondLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -2, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @LastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -1, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @CurrentMonth = SUBSTRING(CONVERT(VARCHAR, GETDATE(), 12), 1,4)&lt;br /&gt;&lt;br /&gt;SELECT&lt;br /&gt;CustomerNumber,&lt;br /&gt;CustomerName,&lt;br /&gt;ISNULL([SIXTHMONTH], 0.00) as 'Sixth Last Month Revenue',&lt;br /&gt;ISNULL([FIFTHMONTH], 0.00) as 'Fifth Last Month Revenue',&lt;br /&gt;ISNULL([FOURTHMONTH], 0.00) as 'Fourth Last Month Revenue',&lt;br /&gt;ISNULL([THIRDMONTH], 0.00) as 'Third Last Month Revenue',&lt;br /&gt;ISNULL([SECONDMONTH], 0.00) as 'Second Last Month Revenue',&lt;br /&gt;ISNULL([LASTMONTH], 0.00) as 'Last Last Month Revenue',&lt;br /&gt;ISNULL([CURRENTMONTH], 0.00) as 'Current Last Month Revenue',&lt;br /&gt;ISNULL([SIXTHMONTH], 0.00) + ISNULL([FIFTHMONTH], 0.00)&lt;br /&gt;+ ISNULL([FOURTHMONTH], 0.00) + ISNULL([THIRDMONTH], 0.00)&lt;br /&gt;+ ISNULL([SECONDMONTH], 0.00) + ISNULL([LASTMONTH], 0.00)&lt;br /&gt;+ ISNULL([CURRENTMONTH], 0.00) AS 'Total Revenue'&lt;br /&gt;FROM&lt;br /&gt;( SELECT&lt;br /&gt;CustomerNumber,&lt;br /&gt;CustomerName,&lt;br /&gt;Revenue,&lt;br /&gt;CASE YYMM&lt;br /&gt;WHEN @SixthLastMonth THEN 'SIXTHMONTH'&lt;br /&gt;WHEN @FifthLastMonth THEN 'FIFTHMONTH'&lt;br /&gt;WHEN @FourthLastMonth THEN 'FOURTHMONTH'&lt;br /&gt;WHEN @ThirdLastMonth THEN 'THIRDMONTH'&lt;br /&gt;WHEN @SecondLastMonth THEN 'SECONDMONTH'&lt;br /&gt;WHEN @LastMonth THEN 'LASTMONTH'&lt;br /&gt;WHEN @CurrentMonth THEN 'CURRENTMONTH'&lt;br /&gt;ELSE 'OTHER'&lt;br /&gt;END [YYMM]&lt;br /&gt;FROM SalesDetails&lt;br /&gt;) SD&lt;br /&gt;PIVOT&lt;br /&gt;( SUM(Revenue) FOR YYMM IN ( [SIXTHMONTH], [FIFTHMONTH], [FOURTHMONTH], [THIRDMONTH], [SECONDMONTH], [LASTMONTH], [CURRENTMONTH])&lt;br /&gt;) as pvt&lt;br /&gt;ORDER BY&lt;br /&gt;CustomerNumber, CustomerName&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This solves the issue of Hard-coding the YYMM values. But the column names will be like “Sixth Last Month Revenue” instead of “October 2008 Revenue”. Well this can be solved by tweaking the headings expression in the SSRS reports.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Alternate Solutions&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using SSRS reports&lt;/strong&gt;&lt;br /&gt;One can use PIVOT reports to solve this problem by filtering out sales which is older than six months. The column headings expression need to be tweaked to show the values like “October 2008 Revenues” etc. Here is the Sample Screen shot&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_NszYjBYumWY/SeYeoy-0o9I/AAAAAAAAAOg/1GU0QU_br-8/s1600-h/BI.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5324977295641060306" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 323px; CURSOR: hand; HEIGHT: 85px" alt="" src="http://4.bp.blogspot.com/_NszYjBYumWY/SeYeoy-0o9I/AAAAAAAAAOg/1GU0QU_br-8/s320/BI.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using Dynamic SQL&lt;br /&gt;&lt;/strong&gt;Dynamic SQL can be used to solve this issue too. Here is the code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;color:#3333ff;"&gt;declare @ColNameSixth char(40), @ColNameFifth char(40), @ColNameFourth char(40), @ColNameThird char(40), @ColNameSecond char(40), @ColNameLast char(40), @ColNameCurrent char(40)&lt;br /&gt;&lt;br /&gt;select @ColNameSixth = datename(mm, dateadd(mm, -6, getdate())) + ' ' + cast(YEAR(dateadd(mm, -6, getdate())) as varchar) + ' Revenues'&lt;br /&gt;select @ColNameFifth = datename(mm, dateadd(mm, -5, getdate())) + ' ' + cast(YEAR(dateadd(mm, -5, getdate())) as varchar) + ' Revenues'&lt;br /&gt;select @ColNameFourth = datename(mm, dateadd(mm, -4, getdate())) + ' ' + cast(YEAR(dateadd(mm, -4, getdate())) as varchar) + ' Revenues'&lt;br /&gt;select @ColNameThird = datename(mm, dateadd(mm, -3, getdate())) + ' ' + cast(YEAR(dateadd(mm, -3, getdate())) as varchar) + ' Revenues'&lt;br /&gt;select @ColNameSecond = datename(mm, dateadd(mm, -2, getdate())) + ' ' + cast(YEAR(dateadd(mm, -2, getdate())) as varchar) + ' Revenues'&lt;br /&gt;select @ColNameLast = datename(mm, dateadd(mm, -1, getdate())) + ' ' + cast(YEAR(dateadd(mm, -1, getdate())) as varchar) + ' Revenue'&lt;br /&gt;select @ColNameCurrent = 'Current Revenues'&lt;br /&gt;&lt;br /&gt;DECLARE @SixthLastMonth char(4), @FifthLastMonth char(4),@FourthLastMonth char(4),@ThirdLastMonth char(4),@SecondLastMonth char(4),@LastMonth char(4),@CurrentMonth char(4)&lt;br /&gt;&lt;br /&gt;SELECT @SixthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -6, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @FifthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -5, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @FourthLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -4, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @ThirdLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -3, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @SecondLastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -2, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @LastMonth = SUBSTRING(CONVERT(VARCHAR, DATEADD(mm, -1, GETDATE()), 12), 1,4)&lt;br /&gt;SELECT @CurrentMonth = SUBSTRING(CONVERT(VARCHAR, GETDATE(), 12), 1,4)&lt;br /&gt;&lt;br /&gt;DECLARE @SQL NVARCHAR(4000)&lt;br /&gt;&lt;br /&gt;SELECT @SQL = '&lt;br /&gt;SELECT&lt;br /&gt;CustomerNumber,&lt;br /&gt;CustomerName,&lt;br /&gt;ISNULL([' + @SixthLastMonth + '], 0.00) as ''' + @ColNameSixth + ''',&lt;br /&gt;ISNULL([' + @FifthLastMonth + '], 0.00) as ''' + @ColNameFifth + ''',&lt;br /&gt;ISNULL([' + @FourthLastMonth + '], 0.00) as ''' + @ColNameFourth + ''',&lt;br /&gt;ISNULL([' + @ThirdLastMonth + '], 0.00) as ''' + @ColNameThird + ''',&lt;br /&gt;ISNULL([' + @SecondLastMonth + '], 0.00) as ''' + @ColNameSecond + ''',&lt;br /&gt;ISNULL([' + @LastMonth + '], 0.00) as ''' + @ColNamelast + ''',&lt;br /&gt;ISNULL([' + @CurrentMonth + '], 0.00) as ''Current Last Month Revenue'',&lt;br /&gt;ISNULL([' + @SixthLastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @FifthLastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @FourthLastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @ThirdLastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @SecondLastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @LastMonth + '], 0.00)&lt;br /&gt;+ ISNULL([' + @CurrentMonth + '], 0.00) AS ''Total Revenue''&lt;br /&gt;FROM&lt;br /&gt;( SELECT CustomerNumber, CustomerName, Revenue, [YYMM]&lt;br /&gt;FROM SalesDetails&lt;br /&gt;) SD&lt;br /&gt;PIVOT&lt;br /&gt;( SUM(Revenue) FOR YYMM IN ( [' + @SixthLastMonth + '], [' + @FifthLastMonth + '], [' + @FourthLastMonth + '], [' + @ThirdLastMonth + '], [' + @SecondLastMonth + '], [' + @LastMonth + '], [' + @CurrentMonth + '])) as pvt&lt;br /&gt;ORDER BY&lt;br /&gt;CustomerNumber, CustomerName&lt;br /&gt;'&lt;br /&gt;&lt;br /&gt;EXEC(@SQL)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-185240311336314031?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/185240311336314031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=185240311336314031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/185240311336314031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/185240311336314031'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/04/sales-for-past-six-months-using-sql.html' title='Sales for past six months using SQL Pivot Operator'/><author><name>Sarma Musty</name><uri>http://www.blogger.com/profile/04450720434203290103</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10041158569501359167'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_NszYjBYumWY/SeYeoy-0o9I/AAAAAAAAAOg/1GU0QU_br-8/s72-c/BI.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-9200878311777067329</id><published>2009-04-13T15:54:00.004-04:00</published><updated>2009-04-13T16:01:59.720-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RSClientPrint.cab'/><category scheme='http://www.blogger.com/atom/ns#' term='RSClientPrint.dll'/><category scheme='http://www.blogger.com/atom/ns#' term='SSRS'/><category scheme='http://www.blogger.com/atom/ns#' term='Printing Reports'/><title type='text'>Reporting Services Print from SharePoint: "Unable to load client print control"</title><content type='html'>In an enterprise environment that doesn't allow users to download ActiveX controls, the printing of reports from within SharePoint may not work correctly as the IE Browser cannot load the client print control.&lt;br /&gt;&lt;br /&gt;We attempted to install the RSClientPrint.cab manually and register the DLLs but that didn't work. Even creating a new MSI file did not work. Finally, after going through various steps, we were able to allow the ActiveX controls to be silently installed within the locked-down environment. In order for the steps below to work, any group policy must "Allow download of signed ActiveX controls".  This was confirmed to be resolved using IE 6.0, 7.0, &amp;amp; 8.0.&lt;br /&gt;&lt;br /&gt;Here is the summary of our troubleshooting for issue “Unable to load client print control” :&lt;br /&gt;&lt;br /&gt;1.       When we tried to print any report from Sharepoint Integrated Reporting Services, we got an error “Unable to load client print control”.&lt;br /&gt;2.       We checked that Reporting Services is on 9.00.3042 (SP2) version.&lt;br /&gt;3.       Upgraded Report Server with Security Update for SQL Server 2005 Service Pack 2 (KB954606) : &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=4603C722-2468-4ADB-B945-2ED0458B8F47&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=4603C722-2468-4ADB-B945-2ED0458B8F47&amp;amp;displaylang=en&lt;/a&gt;&lt;br /&gt;4.       That went successful and Report Server version changed to 9.00.3073&lt;br /&gt;5.       Then we installed the updated version of the SharePointRS.msi on all Web Front Ends in the SharePoint farm. The new version of the add-in can be found here: &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1e53f882-0c16-4847-b331-132274ae8c84&amp;amp;DisplayLang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=1e53f882-0c16-4847-b331-132274ae8c84&amp;amp;DisplayLang=en&lt;/a&gt;&lt;br /&gt;6.       Verified that the Microsoft.ReportingServices.SharePoint.UI.WebParts.dll has been updated to the correct build of 9.00.3294 by looking at the version of this file in  the C:\windows\assembly folder.&lt;br /&gt;7.  Now users are able to print the report&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-9200878311777067329?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/9200878311777067329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=9200878311777067329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/9200878311777067329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/9200878311777067329'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/04/reporting-services-print-from.html' title='Reporting Services Print from SharePoint: &quot;Unable to load client print control&quot;'/><author><name>Steve Mann</name><uri>http://www.blogger.com/profile/07380496759963407882</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='10161810642279669000'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35862303.post-7848842005432030576</id><published>2009-02-27T08:57:00.005-05:00</published><updated>2009-02-27T09:35:28.465-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server BI scalability'/><title type='text'>BI 'Appliances', reference configurations, and very large-scale Data Warehouses</title><content type='html'>As a BI consultant, one thing I find interesting in the BI industry is talk of a Data Warehouse 'Appliance'. Sounds like something you plug in, turn on, and --bam-- instant data warehouse! Would be nice, but while that's not likely to happen, what is becoming available from the hardware vendors are preconfigured systems (aka, an appliance) that are designed for the demands of a data warehouse.&lt;br /&gt;&lt;br /&gt;Well, Microsoft has partnered with Dell and HP to pre-configure and pretest DW ‘reference’ configurations to compete with similar offerings from other big players. The thing I liked seeing was the ‘cost per terabyte’ - granted, these would be for very large implementations, but I thought this was an interesting reference to keep in the back of the mind for high-level scoping.&lt;br /&gt;&lt;br /&gt;According to a news article on TDWI.org ...&lt;br /&gt;“DW appliance pricing varies, but -- if Microsoft can come in at its $13,000-per-TB figure -- it can plausibly claim to field one of the cheaper DW appliance entries. On the other hand, "cheaper" in the DW appliance segment is something of a moving target. Prices have plummeted to such an extent that even DW powerhouse Teradata Corp. -- which appliance players Netezza Inc. and Dataupia Inc. like to position as a pricey proposition -- now markets a system (the Extreme Data 1550) that it says sells for about $16,500 per TB.” (Netezza sells a unit for $18,000 per TB)  (you can read more at &lt;a href="http://www.tdwi.org/News/display.aspx?ID=9325"&gt;http://www.tdwi.org/News/display.aspx?ID=9325&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;The other take away from this is that (for anyone still wondering) - yes - Microsoft SQL Server is truly an Enterprise-class BI platform or we wouldn't even be talking about them with the likes of Teradata and Netezza. Furthermore, the features that are planned for the next version of SQL Server as well as Project Madison mean that exciting things are still to come.&lt;br /&gt;&lt;br /&gt;For more info, check out -&lt;br /&gt;&lt;strong&gt;Project codename "Madison"&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/sqlserver/2008/en/us/madison.aspx"&gt;http://www.microsoft.com/sqlserver/2008/en/us/madison.aspx&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;and for a slide-show about Project Madison...&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://sharepoint.microsoft.com/sharepoint/worldwide/us/southeast/Connections%20BUSINESS%20INTELLIGENCE/Connection%20SE%20Jan%202009%20-%20Madison%20Final.pptx"&gt;http://sharepoint.microsoft.com/sharepoint/worldwide/us/southeast/Connections%20BUSINESS%20INTELLIGENCE/Connection%20SE%20Jan%202009%20-%20Madison%20Final.pptx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35862303-7848842005432030576?l=bisqlserver.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bisqlserver.blogspot.com/feeds/7848842005432030576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35862303&amp;postID=7848842005432030576' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/7848842005432030576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35862303/posts/default/7848842005432030576'/><link rel='alternate' type='text/html' href='http://bisqlserver.blogspot.com/2009/02/bi-appliances-reference-configurations.html' title='BI &apos;Appliances&apos;, reference configurations, and very large-scale Data Warehouses'/><author><name>Jim Pletscher</name><uri>http://www.blogger.com/profile/10792906609505822758</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13067548512495526067'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry></feed>