Friday, October 31, 2008

Why IE only prints the first page?

A few days ago, an issue was escalated to me that one of the web report can only print one (first) page in IE, even the report has three pages. It appeared in Print Preview that there is only one page. But if you look it in Firefox 3.0, you can see three pages in preview and can print all three pages.

The problem is with the css file (Cascade style sheet) with "absolute" keyword.

In the CSS file referred in the webpage, there is a section like this:
div.outbox
{
position: absolute;
left: 65px;
top: 30px;
}

When the page has a DIV tag called the class as <DIV class="outbox" >, or you have a tag like <div style="position:absolute; left:65px; top:30px;" >, IE will mis-interpret the keyword and stop at first page.

In the next example, I changed the keyword "absolute" to "relative":
.outbox2
{
position: relative;
left: 65px;
top: 30px;
}

This solved the "IE only prints first page" issue.

If you encountered similar error and solved with different methods or a different tag/keyword caused the error, please kindly post a comment here to share with other viewers. Thanks.

Wednesday, October 15, 2008

Smalldatetime error

If you see this error:
The conversion of char data type to smalldatetime data type resulted in an out-of-range smalldatetime value

it means you have bad date to convert from string to smalldatetime data type in database. It usually occurs when you have a web form that submitted some data to save into database and one of the data is a date string.

For some reason, people will type the date wrong such as 1/1/2008 becomes 1/1/2998. But the smalldatetime data type can only hold a date smaller than June 6 2079.

For ASP.NET, you can add this to your customized validation:

Private Sub ValidateStartDate(ByVal sender As Object, ByVal args As ServerValidateEventArgs)
Dim IsValid As Boolean = False
Dim strSalesDate As String
strSalesDate = Clean(Me.txtAdStart.Text)
If IsDate(strSalesDate) Then
IsValid = True
Dim intYear As Integer
intYear = Year(CDate(strSalesDate))
If intYear > 2075 Then
IsValid = False
End If
End If
args.IsValid = IsValid
End Sub

Monday, September 8, 2008

Can't edit DTS package email notifications

After installed SQL Server 2005 Management Studio, my SQL2000 Enterprise Manager encountered an error while modifying the email notification component in DTS packages.

The error message is like this:
Error Source: Microsoft Data Transformation Services (DTS) Package
Error Description: Cannot load MAPI interface layer for DTS. Please make sure that semmap90.dll is installed.

Execution cannot continue as the language dependent resources file ...\1033\semmap90.dll could not be loaded.


The error came up because after you installed SQL2005 management studio, the windows registry has updated to newer versions.

The fix is quite simple. If you installed the SQL2000 Desktop Engine in default location then it can be done in this folder:
c:\Program Files\Microsoft SQL Server\80\Tools\BINN\Resources\1033\

(You can copy and paste this link into your PC's Start->Run box and hit "Enter".)

In this folder, copy the semmap.rll and paste in the same folder, then rename it to semmap90.rll. That's all you need to do.

Note: this is RLL file, not DLL.

Step by Step Installing Visual Studio 2008

Having heard so many good words about Visual Studio 2008 (VS2008), I decided to give it a try on my develop machine. Overall, it is a pleasant experience and everything worked just fine and smooth.

In the morning, the first thing after checking emails, I backed up my PC. It took about 25 minutes to create a backup of my current documents and etc.

Next, I put the VS2008 (standard version) install DVD into the DVD-rom. It was a colorful DVD with laser marks “genuine” and “made in Puerto Rico”. Well, “Genuine” matters but “Made in Puerto Rico” doesn’t matter.

First, the process began to copy files to local hard drive. You shall be patient not to interrupt it. After a screen to enter the product key, five sets of five character keys, the installation wizard showed a screen of components to install. By default, everything on the list was selected. But I un-checked the SQL2005 express, which is an optional item, because I have this component already.

Then the installation wizard began to copy files from DVD to my PC. It was a long list of components, from Microsoft .NET Framework 3.5, Microsoft Document Explorer 2008, Microsoft Visual Studio Web Authoring Component, Microsoft Visual Studio 2008, Microsoft SQL server Compact 3.5 (and design tools), several SDKs for Visual Studio 2008 and a Microsoft SQL Publishing Wizard.

After it installed the third component “Microsoft Visual Studio 2008”, a window popped up saying you can install MSDN documentation separately and etc. Then you have to reboot your PC.

This is the end. The total installation process took about 25 minutes on my Dual-Core P4 3.5GHz PC.

After the PC rebooted, you can open Visual Studio 2008 from Programs menu. For the first time, it will ask you what your primary development is; you can choose VB, C# or Web. I chose web because my work mostly involves ASP.NET SQL server and other web pages.

On the start page, it didn’t show any links (RSS feeds) about ASP.NET and wanted me to check the “Tools->Options->Environment” settings. Ok, I didn’t see the environment at first. The trick is you have to check the “Show all settings” checkbox at the bottom of left column. Then all settings appeared.

Now, it’s time to sail in VS2008.

Friday, August 29, 2008

T-SQL: Use “Having” or “Where”

When writing T-SQL query in SQL Server, one has two options to limit the returned data. You can either use “HAVING” or “WHERE”. The question is when and how to use them?

For example:
Query1

Select tblEmployees.EmployeeID, SUM( tblEmployees.intHourThisWeek) as TotalHoursWorked
FROM tblEmployees
WHERE tblEmployees.Active=True
AND tblEmployees.DateofWork < '1/1/2008'
AND tblEmployees.DateofWork >= '1/1/2007'
GROUP BY tblEmployees.EmployeeID

and query2

Select tblEmployees.EmployeeID, SUM( tblEmployees.intHourThisWeek) as TotalHoursWorked
FROM tblEmployees
WHERE Active=True
GROUP BY tblEmployees.EmployeeID
HAVING tblEmployees.DateofWork < '1/1/2008'
AND tblEmployees.DateofWork >= '1/1/2007'

will return the same result. It summarize the total hours of each employee worked in year 2007.

But the difference is that the “WHERE” search condition is applied before the grouping operation occurs and the “HAVING” search condition is applied after the grouping operation occurs.

So if the search condition is limiting the search result into a small subset of the original table(s), it is better to apply the search condition before the grouping operation because this let the database engine to calculate the result set on a smaller subset of data.

Applying this principle to some of the queries while I am fine-tuning the database performance, it is easy to see a 60% to 75% CPU time improvement.

But you can't always move HAVING clause into WHERE clause. Because only HAVING can contain aggregate functions. HAVING clauses can reference any of the items that appear in the select list.

For example:
One company has a promotion that any salesperson who sold more than five refrigerators of one new model in the promotion date period, will qualify for a special bonus.

SELECT intSalespersonID, sum(intUnits) as totalSold
FROM tblSales
WHERE txtProduct = 'Refrigerator ABC'
--AND dateSold between @Date1 and @Date2
GROUP BY txtProduct, intSalespersonID
HAVING sum(intUnits) > 5

If you tried to move the HAVING clause to WHERE clause, you will see this error:
“An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.”

Thursday, August 28, 2008

"semmap90.dll is installed" for SQL2000 DTS Mail Object

The environment at my work has both SQL server 2000 and 2005.

After I upgraded the Enterprise Manager of SQL2000 to Management Studio from SQL2005, I can no longer view or modify the MailObjects in SQL2000 DTS packages.
(DTS stands for Data transformation system)

The error is "Please make sure the semmap90.dll is installed."

I installed Enterprise Manager again and tried to open the DTS package MailObject, it gave me the same error message.

Based on a document from microsoft Technet, the solutiion is:
On the computer where you installed the desktop engine to run management studio, go to

..\Microsoft SQL Server\80\Tools\binn\

Then rename semmap.dll to semmap90.dll

Or you can make a copy of the dll and renamed the new one as semmap90.dll. In this case, you have two dlls so both Enterprise Manager and Management Studio can work.

No need to reboot or restart Management Studio, it immediately fixed the error.

Wednesday, August 27, 2008

Validation for Form Submission with Javascript: Textbox

There are a few common form fields that we need to validate before submit the web form.

Here is a collection of javascript code to access form field value and run some common validations.

For exmaple, you have a form named "myForm1" and you have a function to validate the form submission:

function validateSubmission()
{
// code added inside function
}

1. Text field.

This is the easiest one. Usually this section of code will be enough:
// this block of code checks if user has put in the first name.
// It will check the field value and send a warning to user when the field is empty.
// Also, it will move the cursor onto the field. So the user can type in something immediately.

var fldname="txtfirstname";
if (document.myForm1[fldname].value == ""){
alert("Please put in the first name.");
document.myForm1[fldname].focus();
return false;
}
Besides just checking if the field is empty or not, you can check if the input is correctly formatted.
Here is the sample for email validation:

function checkemail(fldname)
{
var passfail=true;
var myval=document.myForm1[fldname].value;
var mylen=myval.length;
if(mylen>0)
{
if(myval.indexOf("@")<0)
{
alert("Email must be in the format:\r\nuser@domain.com");
document.myForm1[fldname].focus();
return false;
}

if(myval.indexOf(".")<0)
{
alert("Email must be in the format:\r\nuser@domain.com");
document.myForm1[fldname].focus();
return false;
}
}
return true;
}