Thursday, December 6, 2012

ER Studio connecton issue

 

Errors:

 

Connection failed:
SQL State: '01000'
SQL Server Error: 14
[Microsoft][ODBC SQL Server Driver][DBNETLIB]ConnectionOpen (Invalid
Instance())
Connection failed:
SQL State: '08001'
SQL Server Error: 14
[Microsoft][ODBC SQL Server Driver][DBNETLIB]Invalid Connection

 

Rosolution:

 

Use servername\instancename,portnumber

Portnumber is 1433

Thursday, November 29, 2012

When to use Cross Apply?

 

URL: http://explainextended.com/2009/07/16/inner-join-vs-cross-apply/

 

URL: http://stackoverflow.com/questions/1139160/when-should-i-use-cross-apply-over-inner-join

 

EXPLAIN EXTENDED

How to create fast database queries

My latest article on SQL in general: Happy New Year!. You're welcome to read and comment on it.

INNER JOIN vs. CROSS APPLY

Comments enabled. I *really* need your comment

From Stack Overflow:

Can anyone give me a good example of when CROSS APPLY makes a difference in those cases whereINNER JOIN will work as well?

This is of course SQL Server.

A quick reminder on the terms.

INNER JOIN is the most used construct in SQL: it joins two tables together, selecting only those row combinations for which a JOIN condition is true.

This query:

view sourceprint?

1.SELECT *

2.FROM table1

3.JOIN table2

4.ON table2.b = table1.a

reads:

For each row from table1, select all rows from table2 where the value of field b is equal to that of field a

Note that this condition can be rewritten as this:

view sourceprint?

1.SELECT *

2.FROM table1, table2

3.WHERE table2.b = table1.a

, in which case it reads as following:

Make a set of all possible combinations of rows from table1 and table2 and of this set select only those rows where the value of field b is equal to that of field a

These conditions are worded differently, but they yield the same result and database systems are aware of that. Usually both these queries are optimized to use the same execution plan.

The former syntax is called ANSI syntax, and it is generally considered more readable and is recommended to use.

However, it didn’t get into Oracle until recently, that’s why there are many hardcore Oracle developers that are just used to the latter syntax.

Actually, it’s a matter of taste.

To use JOINs (with whatever syntax), both sets you are joining must be self-sufficient, i. e. the sets should not depend on each other. You can query both sets without ever knowing the contents on another set.

But for some tasks the sets are not self-sufficient. For instance, let’s consider the following query:

We table table1 and table2. table1 has a column called rowcount.

For each row from table1 we need to select first rowcount rows from table2, ordered bytable2.id

We cannot formulate a join condition here. The join condition, should it exists, would involve the row number, which is not present in table2, and there is no way to calculate a row number only from the values of columns of any given row in table2.

That’s where the CROSS APPLY can be used.

CROSS APPLY is a Microsoft’s extension to SQL, which was originally intended to be used with table-valued functions (TVF‘s).

The query above would look like this:

view sourceprint?

01.SELECT *

02.FROM table1

03.CROSS APPLY

04.(

05.SELECT TOP (table1.rowcount) *

06.FROM table2

07.ORDER BY

08.id

09.) t2

For each from table1, select first table1.rowcount rows from table2 ordered by id

The sets here are not self-sufficient: the query uses values from table1 to define the second set, not to JOINwith it.

The exact contents of t2 are not known until the corresponding row from table1 is selected.

I previously said that there is no way to join these two sets, which is true as long as we consider the sets as is. However, we can change the second set a little so that we get an addicional calculated field we can later join on.

The first option to do that is just count all preceding rows in a subquery:

view sourceprint?

01.SELECT *

02.FROM table1 t1

03.JOIN (

04.SELECT t2o.*,

05.(

06.SELECT COUNT(*)

07.FROM table2 t2i

08.WHERE t2i.id <= t2o.id

09.) AS rn

10.FROM table2 t2o

11.) t2

12.ON t1.rowcount = t2.rn

The second option is to use a window function, also available in SQL Server since version 2005:

view sourceprint?

1.SELECT *

2.FROM table1 t1

3.JOIN (

4.SELECT t2o.*, ROW_NUMBER() OVER (ORDER BY id) AS rn

5.FROM table2 t2o

6.) t2

7.ON t1.rowcount = t2.rn

This functions returns the ordinal number a row would have be the ORDER BY condition used in the function applied to the whole query.

This is essentially the same result as the subquery used in the previous query.

Now, let's create the sample tables and check all these solutions for efficiency:

view sourceprint?

01.SET NOCOUNT ON

02.GO

03.DROP TABLE [20090716_cross].table1

04.DROP TABLE [20090716_cross].table2

05.DROP SCHEMA [20090716_cross]

06.GO

07.CREATE SCHEMA [20090716_cross]

08.CREATE TABLE table1

09.(

10.id INT NOT NULL PRIMARY KEY,

11.row_count INT NOT NULL

12.)

13.CREATE TABLE table2

14.(

15.id INT NOT NULL PRIMARY KEY,

16.value VARCHAR(20) NOT NULL

17.)

18.GO

19.BEGIN TRANSACTION

20.DECLARE @cnt INT

21.SET @cnt = 1

22.WHILE @cnt <= 100000

23.BEGIN

24.INSERT

25.INTO [20090716_cross].table2 (id, value)

26.VALUES (@cnt, 'Value ' + CAST(@cnt AS VARCHAR))

27.SET @cnt = @cnt + 1

28.END

29.INSERT

30.INTO [20090716_cross].table1 (id, row_count)

31.SELECT TOP 5

32.id, id % 2 + 1

33.FROM [20090716_cross].table2

34.ORDER BY

35.id

36.COMMIT

37.GO

table2 contains 100,000 rows with sequential ids.

table1 contains the following:

id
row_count

1
2

2
1

3
2

4
1

5
2

Now let's run the first query (with COUNT):

view sourceprint?

01.SELECT *

02.FROM [20090716_cross].table1 t1

03.JOIN (

04.SELECT t2o.*,

05.(

06.SELECT COUNT(*)

07.FROM [20090716_cross].table2 t2i

08.WHERE t2i.id <= t2o.id

09.) AS rn

10.FROM [20090716_cross].table2 t2o

11.) t2

12.ON t2.rn <= t1.row_count

13.ORDER BY

14.t1.id, t2.id

id
row_count
id
value
rn

1
2
1
Value 1
1

1
2
2
Value 2
2

2
1
1
Value 1
1

3
2
1
Value 1
1

3
2
2
Value 2
2

4
1
1
Value 1
1

5
2
1
Value 1
1

5
2
2
Value 2
2

8 rows fetched in 0.0000s (498.4063s)

Table 'table1'. Scan count 2, logical reads 200002, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'Worktable'. Scan count 100000, logical reads 8389920, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'table2'. Scan count 4, logical reads 1077, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times:
   CPU time = 947655 ms,  elapsed time = 498385 ms. 

This query, as was expected, is very unoptimal. It runs for more than 500 seconds.

Here's the query plan:

SELECT
  Sort
    Compute Scalar
      Parallelism (Gather Streams)
        Inner Join (Nested Loops)
          Inner Join (Nested Loops)
            Clustered Index Scan ([20090716_cross].[table2])
            Compute Scalar
              Stream Aggregate
                Eager Spool
                  Clustered Index Scan ([20090716_cross].[table2])
          Clustered Index Scan ([20090716_cross].[table1])

For each row selected from table2, it counts all previous rows again an again, never recording the intermediate result. The complexity of such an algorithm is O(n^2), that's why it takes so long.

Let's run he second query, which uses ROW_NUMBER():

view sourceprint?

01.SELECT *

02.FROM [20090716_cross].table1 t1

03.JOIN (

04.SELECT t2o.*, ROW_NUMBER() OVER (ORDER BY id) AS rn

05.FROM [20090716_cross].table2 t2o

06.) t2

07.ON t2.rn <= t1.row_count

08.ORDER BY

09.t1.id, t2.id

id
row_count
id
value
rn

1
2
1
Value 1
1

1
2
2
Value 2
2

2
1
1
Value 1
1

3
2
1
Value 1
1

3
2
2
Value 2
2

4
1
1
Value 1
1

5
2
1
Value 1
1

5
2
2
Value 2
2

8 rows fetched in 0.0006s (0.5781s)

Table 'Worktable'. Scan count 1, logical reads 214093, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'table2'. Scan count 1, logical reads 522, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'table1'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times:
   CPU time = 578 ms,  elapsed time = 579 ms. 

This is much faster, only 0.5 ms.

Let's look into the query plan:

SELECT
  Inner Join (Nested Loops)
    Clustered Index Scan ([20090716_cross].[table1])
  Lazy Spool
    Sequence Project (Compute Scalar)
      Compute Scalar
        Segment
          Clustered Index Scan ([20090716_cross].[table2])

This is much better, since this query plan keeps the intermediate results while calculating the ROW_NUMBER.

However, it still calculates ROW_NUMBERs for all 100,000 of rows in table2, then puts them into a temporary index over rn created by Lazy Spool, and uses this index in a nested loop to range the rns for each row fromtable1.

Calculating and indexing all ROW_NUMBERs is quite expensive, that's why we see 214,093 logical reads in the query statistics.

Finally, let's try a CROSS APPLY:

view sourceprint?

01.SELECT *

02.FROM [20090716_cross].table1 t1

03.CROSS APPLY

04.(

05.SELECT TOP (t1.row_count) *

06.FROM [20090716_cross].table2

07.ORDER BY

08.id

09.) t2

10.ORDER BY

11.t1.id, t2.id

id
row_count
id
value

1
2
1
Value 1

1
2
2
Value 2

2
1
1
Value 1

3
2
1
Value 1

3
2
2
Value 2

4
1
1
Value 1

5
2
1
Value 1

5
2
2
Value 2

8 rows fetched in 0.0004s (0.0008s)

Table 'table2'. Scan count 5, logical reads 10, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'table1'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 1 ms. 

This query is instant, as it should be.

The plan is quite simple:

SELECT
  Inner Join (Nested Loops)
    Clustered Index Scan ([20090716_cross].[table1])
    Top
      Clustered Index Scan ([20090716_cross].[table2])

For each row from table1, it just takes first row_count rows from table2. So simple and so fast.

Summary:

While most queries which employ CROSS APPLY can be rewritten using an INNER JOIN, CROSS APPLY can yield better execution plan and better performance, since it can limit the set being joined yet before the join occurs.

Wednesday, November 28, 2012

Using hashbyte()

 

Reference

URL: http://www.bidn.com/blogs/TomLannen/bidn-blog/2265/using-hashbytes-to-compare-columns

Using HASHBYTES() to compare columns

change text size: A A A

posted 10/17/2011  by TomLannen -  Views: [11671]

Recently, while at a client engagement, I was building some SSIS packages an issue came up where they didn?t want to use the CHECKSUM() function in TSQL to do column comparisons because the results can be inaccurate on some rare occasions.  I personally have never come across this but others here at Pragmatic Works have.  So we have two options freely available to work around this issue.  The first is the third party component plugin that you can get free at codeplex called Multiple Hash.  The client wasn?t comfortable with having to install this component on multiple servers throughout the environment so that option wasn?t available to me.  Instead I had to use the HASHBYTES() function in TSQL.

HASHBYTES() is much more reliable than checksum when it comes to producing accurate results, but it comes at a slight cost.

The first thing to note is how to construct the HASHBYTES() function.  In the first part you tell the function which algorithm you are going to use.  I?m using SHA1, but be aware that they single tics ? ? are required followed by a comma.  Then you must concatenate the columns you wish to use together as seen below.

image

There you can see its already a bit more arduous than using CHECKSUM(), but not that big of a deal to concatenate a bunch of columns.  Lets look at the results.

image

Uh-Oh here is our first problem.  HASHBYTES() doesn?t work with NULL values inside any columns.  So we?ve got to handle the Nulls in our query using the ISNULL() function.

image

Now the results look like this:

image

Then next thing that you have to look at is how HASHBYTES() handles(or more accurately doesn?t handle) Data types.  Here the ID column is an INT data type, but the same holds true for any non-string data type.

image

We get an error saying that the data type is wrong for the HASHBYTES() function

image

So now we have to CAST every column that is a non-string data type.

image

Now after this fix our results look better.

image

So as you can see already there will be a good deal more T-SQL coding involved with using HASHBYTES then with CHECKSUM(). But this isn?t all.  The last little gotcha isn?t quite as obvious as the first two.  Lets go back to our Null handling query.

image

I?ve gone and edited the data some for this example. Please also note that HASHBYTES() is case sensitive meaning that if you have the same spelling but different casing at an individual character level the hash value returned will be different.

image

The rows are different from one another but when concatenated together for the HASBYTES() function they produce the same exact value. So to handle this we have to update our code again.  We are going to add a rarely used character to the concatenation so ensure that they results will return correctly.

image

Here I chose to use a pipe to basically delimit the columns thereby making them different from each other. The result is much better.

image

If we take a quick look at results of the two concatenations we can see why we get the different results

image

The delimited column is obviously different from one row to the next, and the Non-Delimited column is exactly the same for each row.

While HASHBYTES() is definitely more accurate and reliable than using CHECKSUM(), there are some hoops to jump through to insure you get the results you need.  I hope this helps you guys out.

Friday, November 9, 2012

Stupid mistake when running report project solution with more than one reports

 

I’ve created a report project solution and imported a few report rdl files. First, BIDS 2008 asked me to identify the StartItem.

Then When I try to run a report, I just click the green triangle to debugging but did not realize bids was trying to run that default report I've

picked as the StartItem. This error bothered me for a few hours until I finally figured it out .

I have to right click the report I want to run under designer and run it . Keep that in mind!!!

Thursday, October 18, 2012

How to find out missing data in columns

Sometimes, I need to compare two columns to find out missing value

such as column a contains list of orderid from one script while column b contains list of orders from another script

Since two scripts are running on different env, the only way to compare is to copy and paste to excel.

Now if list contains thousands of orders, it is inhumane to go through each row

Here is the solution:  http://en.kioskea.net/forum/affich-456715-find-missing-data-in-2-columns-excel

use COUNTIF function in excel

Suppose A column contains less orders than E

You want to find out how many are missing in column

=IF(COUNTIF(A$2:A$3730,E2521)=0,E2521,"")

Remember to use $

What it does it to take each value in E column and go through the whole A column, if there is no match, display that value from Column E

 

Neat !

Tuesday, October 16, 2012

How to create a temp table using dynamic sql

When using dynamic sql to create a temp table, you need to create the temp table first, then alter columns in the dynamic sql

see this blog below:

 

Temporary Tables and Dynamic SQL

When programming in SQL on occasion there is a need to generate temporaty tables inside a sproc without knowing the colums or type when the sproc is written. One such situation would be when you want to pivot a table. You can create a cursor over a column result set and create a new column for each value.
When you try to create temporary tables with dynamic SQL you will run into a scoping problem.
for example:
DECLARE @SQL nvarchar(4000)
SELECT @SQL = 'CREATE TABLE #Temp (col1 int)'
EXEC (@SQL)
SELECT * FROM #Temp

This will cause an error:

Msg 208, Level 16, State 0, Line 4
Invalid object name '#Temp'.

The problem here is the scope of the session. When we execute dynamic sql via EXEC or sp_executesql a new scope is created for a child session. Any objects created in that session are dropped as soon as the session is closed.

One solution I have found for this problem is creating the table in the "parent" scope and then just using dynamic sql to modify the table. For this to work a table is created with a minimum set of colums. And then we use the ALTER TABLE statement with dynamic SQL. The Child session has access to the objects created in the parent session so the table can be modified with dynamic sql:

DECLARE @SQL NVARCHAR(4000)
CREATE TABLE #Temp ( id int null)
SELECT @SQL = 'ALTER #Temp ADD Col1 int null'
EXEC (@SQL)
SELECT * FROM #Temp
DROP TABLE #Temp

This table is visible and both columns will show up.

Tuesday, October 9, 2012

How to open Sql files in TFS using SSMS instead of default vs2010 window

 

to be filled…

How to execute SSRS report from Sql Server job agent

 

Sometimes, there are needs to execute SSRS directly from a sql server job or inside a SSIS package.

If it is from a SSIS package, you need to use script component and use the web service exposed by SSRS

If you need to execute it through a Sql server job agent, below is the step

 

1.  Create a one time subscription for that report.

2. Find out the Subscription ID for that report

SELECT s.SubscriptionID

FROM dbo.Catalog AS c

INNER JOIN dbo.ReportSchedule AS s

             ON   c.ItemID = s.ReportID

WHERE

      c.Name = ‘your report name’

3. Execute dbo.AddEvent proc on ReportServer

 

EXEC ReportServer.dbo.AddEvent @EventType = 'TimedSubscription', @EventData = @SubscriptionID

 

This SSRS rpt will be executed  by this job.

Tuesday, July 17, 2012

Hw to add a logo to the Report Manager

If you want to customize your Report Manager a bit , check the following link

http://weblogs.asp.net/jgalloway/archive/2006/12/12/reporting-services-add-a-logo-to-the-report-manager.aspx


Reporting Services - Add a logo to the Report Manager

The SQL Server Reporting Services Report Manager is functional, but it's not very customizable. The ASPX pages just reference compiled assemblies, so the only real way to modify them is via CSS.
What makes that more difficult is that the SSRS HTML is poorly constructed so that the tags you'd most want to customize don't have Id's or Classes assigned. For instance, the most obvious customization anyone would want to make is to add a corporate logo, and there's no hook for that at all. The folder image is a simple tag, nestled between two other spacer tags, packed inside an unidentified , and all those elements are written out in code1. The problem there is that there's no way, even with some descendant selector trickery, to target that folder image.

That's not entirely true, part 1:

IE7 adds support for some combinators (e.g. child, adjacent, first:sibling) which allow you to directly target elements without classes or id's. Why I'm not using that approach here:
  • IE6 doesn't support it.
  • IE7's support is kind of quirky - it sees HTML comments as page elements, for instance. That means it's difficult to write cross browser combinator based CSS rules.
  • Targeting deeply nested elements with combinators is pretty difficult.
  • Combinator based rules are inherently unstable, since any changes to the page's structure (including HTML comments, as mentioned above) can really mess up your page. Structure changes can cause your rule to be ignored or - much worse - point it at another page element.

That's not totally true, part 2:

You could replace the image files (C:\Program Files\Microsoft SQL Server\MSSQL.X\Reporting Services\ReportManager\images\48folderopen.jpg
as well as all the other files in that directory named 48*.jpg)2 with your corporate logo. Problems with that approach:
  • You're constrained to a 48x48 px jpg
  • Subsequent upgrades could overwrite it
  • Those images do serve some use - they change depending on the current function you're performing in the site.

Who needs an Upper Title, anyway?

I went for the next best target - the rather useless "upper title" - since it's a div which actually has a class (div.msrs-uppertitle)assigned. First, let's look at the style changes, then we'll talk about the different ways to add them.
.msrs-uppertitle
{
    BACKGROUND: url(http://www.sitename.com/images/logo.gif) no-repeat; 
    HEIGHT: 35px;
    WIDTH: 120px; 
    TEXT-INDENT: -5000px; 
}
Some things to notice:
  1. We set a background image by URL. That will keep the reports up to date with our company logo as it may change in the future. Make sure to pick an image that's an appropriate size for that space.
  2. We set the background to no-repeat so it just displays once rather than tiling. That's handy even if the logo image has a border, since we don't have to be so precise on your height and width settings.
  3. We set a height and width which are large enough to display the logo. These should be just larger than your image size; you can just see via trial and error what looks best. This is one of those times where on the fly CSS editing tools like the IE DevToolbar or the Firefox Web Developer extension come in really handy.
  4. Now we need to get rid of the site title. I didn't want to mess with trying to blank it out in the SSRS Site Settings since it might be useful elsewhere, or someone might fill it in without knowing that it would conflict with the logo. The easiest solution is to use the Phark Image Replacement technique and hide the text by setting the indent to -5000px.
Done and done.
Oh, wait. I said I'd be talking about where to add this style, didn't I? A few options:
  1. Edit ReportingServices.css (in the C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportManager\Styles folder).
  2. Use another stylesheet - method 1: change the HTMLViewerStyleSheet parameter in RSReportServer.config
  3. Use another stylesheet - method 2: specify a stylesheet in rc:StyleSheet parameter of the report url:
    http://localhost/reportserver?/AdventureWorksSampleReports/Product+Line+Sales&rs:Command=Render&rc:Stylesheet=MyStyleSheet
I went with a variation of option 1 - I edited ReportingServices.css, but just to add an import statement that points to another CSS file where I'll put all my Reporting Services CSS customizations:
  1. Add the following to the top of ReportingServices.css:
    @import url(customizations.css);
  2. Save the block of CSS (the bit that starts with ".msrs-uppertitle") to a file called customizations.css to the same folder as ReportingServices.css. You might want to add other customizations to it while you're at it, like this CSS fix for Firefox.
That's it! We're done!

Great, but the logo should link to the home page of our intranet!

What!? Feature creep! Version 2!
Oh, okay. It's not easy, though...
Changing style isn't a piece of cake, but at least there's a supported hook for it. You can't add a link via CSS, though. CSS2 allows for some limited content generation, but it doesn't support adding links; even if it did we'd be out of luck because IE7 doesn't support it.
Bill Vaughn and Peter Blackburn proposed a solution using DHTML Behaviors. That's a pretty slick workaround - behaviors allow you to tie Javascript functionality to DOM elements in CSS. Unfortunately, only IE supports behaviors. Plus, if you're going to hack Javascript, why not edit the ReportingServices.js file...3
C:\Program Files\Microsoft SQL Server\MSSQL.n\Reporting Services\ReportManager\js\ReportingServices.js
There it is... the fabled treasure... a way to modify the content of the Reporting Services Manager...
I added the following code to the top of the JS file (after backing it up, of course):
addLoadEvent(SetLogoUrl);

function addLoadEvent(fn)
{
    if (window.addEventListener)
        window.addEventListener('load', fn, false)
    else if (window.attachEvent)
        window.attachEvent('onload', fn);
}

function SetLogoUrl()
{
    var header = document.getElementById('ui_sharedArea');
    if (!header) return;
    var headerDivs = header.getElementsByTagName('div');
    for (var i=0;i<headerDivs.length;i++)
    {
        if(headerDivs[i].className == 'msrs-uppertitle')
        {
            headerDivs[i].onclick = new Function('top.location="/"');
            headerDivs[i].style.cursor = 'pointer';
            //headerDivs[i].style.backgroundImage = 'url(http://images.slashdot.org/topics/topiccommunications.gif)';
            //headerDivs[i].style.backgroundRepeat = 'no-repeat';
            //headerDivs[i].style.width = '96px';
            //headerDivs[i].style.height = '62px';
        }
    }
}

Let's talk about it:
  1. That addLoadEvent business is there because we can't modify the page until it has finished loading, but this script is included at the top of the page. A less sophisticated solution is to set a timeout to call SetLogoUrl, but addLoadEvent leverages the built in event model to call the function after the page has finished loading. IE uses attachEvent, while everyone else uses addEventListener, so we'll include some logic to make sure the right one gets called.
  2. SetLogoUrl's job is to modify the Upper Title DIV. This would be easier if that DIV had an ID assigned, since Javascript doesn't have built in support for retrieving an element by class name. Most sample code which returns an element by class just iterates all elements in the DOM looking for a class name match, but since we know a bit about the page structure we can be a little more efficient. We narrow the search by grabbing the nearest parent element with an ID assigned and only searching through its children.
  3. Once we've got our DIV, we can just set the onclick behavior to navigate to the correct URL. We'll need to change the cursor to indicate that it's a link, too.
Hey, since we're messing with that DIV, why not just change the image in Javascript and simplify things? Well, I've left some commented code there to get you started if that's what you want to do, but I think it's better to keep the image modification in CSS.
Why? Well, there are a few good reasons. The biggest reason is that the Javascript doesn't execute until the page has finished loading, so the original DIV text is displayed, then changes to the logo. Ugh. Plus, from a maintenance and architectural perspective, it's a much better practice to keep your presentation information in CSS and your behaviors in Javascript.
And that's it.

SSRS R2 log in after fresh installation

today, I just installed a fresh copy of SSRS R2 and found a serious problem when I tried to login to Report Manager, it kept telling me

User does not have required permissions. Verify that sufficient permissions have been granted and Windows User Account Control (UAC) restrictions have been addressed



After a few googling, I've found a few useful tricks

1. official comments from MSDN, seems I am not the sole victim

http://connect.microsoft.com/SQLServer/feedback/details/622737/user-does-not-have-required-permissions-verify-that-sufficient-permissions-have-been-granted-and-windows-user-account-control-uac-restrictions-have-been-addressed



2. http://www.soheib.com/technical-knowledge/sql-server-2012-reporting-services-uac-user-access-control/

3. (optional)  http://www.soheib.com/?p=381


Basically, you have to Run your browser as Administrator and the URL has to be Localhost (Can not
be the real server name, don't know)
After get in, in the Site Settings -> security, create another role and assign yourself to sys admin.
Then back to the home page , under folder setting -> security, create a new user and assign content manger to this user.

 All done.

The only problem is you have to use browser under Admin , otherwise, it can not be resolved.









Monday, January 9, 2012

How to find out running process on a specified schema

SELECT p.SPID, Blocked_By = p.Blocked, p.Status, p.LogiName, p.HostName, Program = coalesce('Job: ' + j.name, p.program_name), DBName = db_name(p.dbid), Command = p.cmd, CPUTime = p.cpu, DiskIO = p.physical_io, LastBatch = p.Last_Batch, -- LastQuery = coalesce( (select [text] from sys.dm_exec_sql_text(p.sql_handle)), '' ), -- SQL Server 2005+ -- LastQuery = coalesce( (select * from ::fn_get_sql(p.sql_handle)), '' ), -- SQL Server 2000 ? FAILS p.WaitTime, p.LastWaitType, LoginTime = p.Login_Time, RunDate = GetDate(), [Server] = serverproperty('machinename'), [Duration(s)] = datediff(second, p.last_batch, getdate()) FROM master.dbo.sysprocesses p left outer join msdb.dbo.sysjobs j on substring(p.program_name,32,32) = substring(master.dbo.fn_varbintohexstr(j.job_id),3,100) where p.spid > 50 and p.status <> 'sleeping' and p.spid <> @@spid -- and ltrim(rtrim(p.loginame)) = 'NT AUTHORITY\SYSTEM' order by p.spid

Friday, January 6, 2012

List of table size before and after compression via sql code

One nice feature on SQL2008 Enterprise/Developer edition is the compression feature. However, it requires manual click on the SSMS and it will quickly turn to a very tedious thing if there are hundred of jobs needs to be compressed. Below is the code to help calculate the table size before and after the compression operation. Link ( http://sqlserver-online.blogspot.com/2011/02/calculating-sql-server-data-compression.html ) -- Determine the estimated impact of compression -- NOTE: This script is only for SQL Server Enterprise and Developer edition. set nocount on -- We create a temp table for the result if (object_id('tempdb..#comp', 'U') is not null) drop table #comp go create table #comp ( object_name sysname ,schema_name sysname ,index_id int ,partition_number int ,[size_with_current_compression_setting (KB)] bigint ,[size_with_requested_compression_setting (KB)] bigint ,[sample_size_with_current_compression_setting (KB)] bigint ,[sample_size_with_requested_compression_setting (KB)] bigint ) go -- Calculate estimated impact of page level compression for all -- user-tables and indexes in all schemas. -- NOTE: -- 1) To get the estimated impact of row level compression change the last parameter -- of sp_estimate_data_compression_savings to 'row' instead. -- 2) We don't care about partitioning here. If this is important for you, -- you have to modify forth parameter of sp_estimate_data_compression_savings. -- Please refer to BOL. declare @cmd nvarchar(max) set @cmd = '' select @cmd = @cmd +';insert #comp exec sp_estimate_data_compression_savings ''' + schema_name(schema_id)+''',''' + name + ''',null, null, ''page''' from sys.tables where objectproperty(object_id, 'IsUserTable') = 1 exec (@cmd) ; -- Do some further calculations for a more meaningful result with compressionSavings as ( select quotename(schema_name) + '.' + quotename(object_name) as table_name ,index_id ,[size_with_current_compression_setting (KB)] ,[size_with_requested_compression_setting (KB)] ,cast(case when [size_with_current_compression_setting (KB)] = 0 then 0 else 100.0*(1.0-1.0 *[size_with_requested_compression_setting (KB)] /[size_with_current_compression_setting (KB)]) end as decimal(6,2)) as [Estimated Savings (%)] from #comp ) select cs.table_name ,isnull(i.name, i.type_desc) as index_name ,cs.[size_with_current_compression_setting (KB)] ,cs.[size_with_requested_compression_setting (KB)] ,cs.[Estimated Savings (%)] from compressionSavings as cs left outer join sys.indexes as i on i.index_id = cs.index_id and i.object_id = object_id(cs.table_name, 'U') order by cs.[Estimated Savings (%)] desc -- Get rid of the temp table drop table #comp go