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;
}

Tuesday, August 26, 2008

Dynamic Array for unknown number of data

In one situation, I want to display a drop down selection of different dealers for administrator to assign dealer to various products/users. I don't want to connect to database to retrieve dealers for 100 times so I used a in-memory array to hold the dealers and build drop down selection on the ASP page.

Here is the code for dynamic array and assigning values. With this array in memory. It will be fast and easy to create as many dropdown as you want with only one connect to database.


'create an array to save the retailers.
dim aryRetailers() ' dynamic array
ReDim aryRetailers(1,0)

aryRetailers(0,0) = "0"
aryRetailers(1,0) = "select a retailer"
dim cnt
cnt = 1
do while not rst.eof
ReDim Preserve aryRetailers(1, cnt)
aryRetailers(0,cnt) = rst("intRetailer")
aryRetailers(1,cnt) = rst("txtRetailer")
cnt = cnt + 1
rst.movenext
loop
set rst = nothing

' build the dealer drop down list
sub retailerdropdown
<select name=drpRetailer size=1>
for i = 0 to ubound(aryRetailers,2)
<option value=" & aryRetailers(0,i) & ">" & aryRetailers(1,i) & "</option>"
next
</select>
end sub

Parallel Computing in .NET

It was a little surprise but not shocked when I heard that INTEL are talking to Microsoft for parallel computing programming because in a couple of years, there will be CPUs with 16 cores to 256 cores.

As we have already seen many new PCs come with quad-core (four core processing units), it is not a surprise to hear 16 cores PC will come out soon. But for 256 cores? I am a little surprised. As in 1960's, those old slow computer on APOLLO could send human to Moon, now equipped with 256 cores computers, what will human beings do with the computing power? Yeh, of course, someone will use the computing power to play games!

The demonstration of parallel computing programming was run on a laptop with duo-core processor.

The first time, the program ran a million times of heavy math calculation. It took about 10 seconds to complete with one CPU running nearly 100% and another one idle.

The second demonstration was to separate the calculation into 10 blocks. This time, both CPU ran at high usage and the total time was 5.3 seconds.

By looking at the time, we noticed that the parallel computing is not exactly half of the one thread computing. This was because of the “context switch”, the extra work involved in parallel computing.

Since this is a duo-core laptop, there are only two working threads at a time. When one thread is processed, the CPU will have to clean up the context of the thread and load the context for a new thread. It is a like a hotel with two rooms. If a customer checked out, we need to clean up the room for new customer. This is the overhead of “context switch”.

This session was given by Keith Rome. He said the so-called “Hyper-threading” label on some PCs was not good. For a single core CPU, hyper-threading just added more context space in process memory. If you have only two threads running on PC, it can improve the speed by pre-load the next thread context. But if you truly believe the “hyper-threading” and began to “multi-tasking” on such old PC, there will be a lot of context switching and the actual speed will be very slow.

You may have already experienced it.

Warning: ONLY when CPU one runs at high and others idle, you may try multi-threading programming. Usually, the optimization in operating system is better than you can design in your code.

There is a situation when your computer runs slow but when you look at the performance, the CPU is running at low usage, 10 to 15% maybe.

This is not issue of threading or parallel computing. Most times, the bottleneck is at the I/O. Reading and writing to hard drive is slow but reading and writing to a network drive can be even slower. In this case, APM model is introduced. APM is Asynchronous Programming Model.

Asynchronous programming means you make an asynchronous I/O call, switch off the thread and let the CPU to notify you when the Asynchronous call returned a value. So the thread of CPU can be used for other computing tasks while your task is waiting on a reply from I/O.

The benefit is this can increase the scalability of a system, operating system threads are used more often, more efficient use of available resources.

The difficulties are that debugging will be harder, code can be more difficult to read, difficult to maintain.

In ASP.NET, to deal with I/O latency problem, one can consider using APM pattern to write asynchronous page, call asynchronous web services.

My question: what about the traditional ASP pages? Will multi-cores server handle the threading properly?

Monday, August 25, 2008

devLink 2008 in Murfreesboro is a great hit

The two-day confernce DevLink (devlink.net) is a very good experience for me. I had listened to speakers about .NET, Visual Studio, Parallel computing, ADO.NET connection and many other topics.

One most interesting thing was the new language in developing process: F# (f sharp).

To my understanding, it is going to be a very smart lauguage that you can write like vb script that you don't specify data type, and the compiler will decide the appropriate data type for you.

The conference have attendees coming down from Michigan, Ohio. Of course there are people from other southern states.

Can't describe everything in one post, so I am going to write a few paragraphs in the coming days.