Sunday, November 30, 2008

Cách định dạng mã nguồn được đăng trên BLOGGER

Cách sử dụng trong bài viết này là sử dụng SyntaxHighlighter , nó là một thư viện nguồn mở viết bằng JavaScript .

Nó thực hiện đặt màu và phông chữ phù hợp với đoạn mã nguồn mà bạn trích dẫn bằng các câu lệnh JavaScript.

Tiếp theo là các bước để cài đặt:

1. Download các file thư viện cho SyntaxHighlighter và đưa lên vào host lưu trữ các file trong thư viện này, bạn có thể upload lên Google Code Page.

2. Đăng nhập vào BLOGGER, vào mục Layout –> Edit HTML. Tiếp theo copy đoạn code sau vào template:

</div></div> <!-- end outer-wrapper -->
<link href='http://[YOUR HOST]/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script src='http://[YOUR HOST]/shCore.js' type='text/javascript'/>

<script src='http://[YOUR HOST]/shBrushCpp.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushCss.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushJava.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushJScript.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushSql.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushXml.js' type='text/javascript'/>

<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag)
{
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++)
{
if (elements[i].getAttribute("name") == name)
{
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, "code", "pre");
FindTagsByName(elements, "code", "textarea");

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == "TEXTAREA") {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);

}
else if(elements[i].nodeName.toUpperCase() == "PRE") {
brs = elements[i].getElementsByTagName("br");
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
//clipboard does not work well, no line breaks
// dp.SyntaxHighlighter.ClipboardSwf =
//"http://[YOUR HOST]/clipboard.swf";
dp.SyntaxHighlighter.HighlightAll("code");
//]]>
</script>

</body>
</html>

3. Bây giờ bạn có thể trích dẫn các đoạn code bằng cách thêm thẻ “pre” hoặc “textarea”. Cách sử dụng cụ thể như sau:

... some code here ...

4. Các ngôn ngữ hổ trợ bao gồm:

C++: cpp, c, c++

C#: c#, c-sharp, csharp

CSS: css

Delphi: delphi, pascal

Java: java

Java Script: js, jscript, javascript

PHP: php

Python: pt, python

Ruby: rb, ruby, rails, ror

SQL: sql

VB: vb, vb.net

XML, HTML: xml, html, xhtml, xslt

Friday, November 28, 2008

How to create a partition for an existing table and index?

Take the following steps to create a partition for an existing table and index:

1. Create File Group:

To create a filegroup named 2003Q3 for the AdventureWorks database, use ALTER DATABASE:

ALTER DATABASE AdventureWorks ADD FILEGROUP [2003Q3]

Once a filegroup exists then you use ALTER DATABASE to add files to the filegroup.

ALTER DATABASE AdventureWorks
ADD FILE
	(NAME = N'2003Q3',
	FILENAME = N'C:\AdventureWorks\2003Q3.ndf',
	SIZE = 5MB,
	MAXSIZE = 100MB,
	FILEGROWTH = 5MB)
	TO FILEGROUP [2003Q3]

2. Create a partition function:

A partition function can be created by using the CREATE PARTITION FUNCTION STATEMENT. An example is given below:

CREATE PARTITION FUNCTION OrderDateRangePFN(datetime)
AS
RANGE LEFT FOR VALUES (
	'20000930 23:59:59.997',
	'20001231 23:59:59.997',
	'20010331 23:59:59.997',
	'20010630 23:59:59.997')

For RANGE LEFT

1st partition is all data <= '20000930 23:59:59.997’

2nd partition is all data >  '20000930 23:59:59.997’ and <= '20001231 23:59:59.997'

3rd partition is all data > '20001231 23:59:59.997' and <= '20010331 23:59:59.997'

4th partition is all data > '20010331 23:59:59.997' and <= '20010630 23:59:59.997'

5th partition is all data > '20010630 23:59:59.997'

For RANGGE RIGHT

1st partition is all data < '20000930 23:59:59.997’

2nd partition is all data >=  '20000930 23:59:59.997’ and < '20001231 23:59:59.997'

3rd partition is all data >= '20001231 23:59:59.997' and < '20010331 23:59:59.997'

4th partition is all data >= '20010331 23:59:59.997' and < '20010630 23:59:59.997'

5th partition is all data >= '20010630 23:59:59.997'

3. Create a partition scheme:

A partition scheme can be created by using the CREATE PARTITION SCHEME statement. An example is given below:

CREATE PARTITION SCHEME OrderDateRangePS
AS PARTITION OrderDateRangePFN
TO ([2000Q3], [2000Q4], [2001Q1], [2001Q2], [PRIMARY])

4. Drop the existing clustered index:

If in your table has clustered index (default for primary keys), you must drop it and recreate nonclustered index with primary keys of table. The clustered index can be dropped by using the DROP INDEX statement. The statement is as follows:

ALTER TABLE [dbo].[Orders] DROP CONSTRAINT [PK_Orders]

ALTER TABLE [dbo].[Orders] ADD CONSTRAINT [PK_Orders] PRIMARY KEY NONCLUSTERED 
(
	[OrderID] ASC
)

5. Create the clustered index on the partition scheme:

The index can be created on a partitioned scheme as follows:

CREATE CLUSTERED INDEX [PartitionIndex_on_OrderDateRangePS] ON [dbo].[Orders] 
(
	[OrderDate]
)
	WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) 
	ON [OrderDateRangePS]([OrderDate])
The table is automatically partitioned according to the partition scheme of the clustered index.
 

Thursday, November 27, 2008

Những bài học từ một dự án phần mềm

Đây là một câu chuyện có thật về một dự án phần mềm trải qua 4 năm và tiêu tốn 35 triệu USD mà không đem lại kết quả nào, và có kế hoạch kéo dài thêm ít nhất là 4 năm nữa.

Dự án này diễn ra tại một công ty sản xuất dụng cụ thể thao vào hàng đầu trên thế giới, doanh thu khoảng hơn chục tỷ USD một năm, có trụ sở tại Tây Bắc Mỹ, tạm gọi là công ty N.

Trên phương diện là một study case, đây là một dự án khá độc đáo, và có thể dùng làm bài học điển hình về nhiều khía cạnh khác nhau của một dự án phần mềm, nhất là dành cho các doanh nghiệp sản xuất, dịch vụ đang có ý định ứng dụng công nghệ thông tin vào quy trình sản xuất và hoạt động của mình. Bài viết này hướng tới các đối tượng là Giám đốc Công nghệ Thông tin của doanh nghiệp (CIO – Chief Information Technology Officer), Quản trị Dự án (Project Manager) và Kiến trúc sư phần mềm (Software Architect), và sẽ phân tích qua các khía cạnh sau đây của dự án: Quy trình Quản lý (Management Process), Quy trình phát triển phần mềm (Software Development Process)  và Kiến trúc phần mềm (Software Architecture).

Chi tiết...

(Trích từ hanoian.com)

Generics in .NET

There are language features that are nothing more than syntactical sugar. For example, C#'s coalesce operator (??) is a short-handed and specialized if-else. Object initializes make it easier to set properties on a newly created objects. Some features though go beyond mere convenience and add real value. I know it seems like we constantly have to learn new things, while at the same time actually produce code to pay our bills. It can be hard to pick and choose what to learn and what can wait. Let me be straight up though: if you haven't mastered generics yet, you're starting to fall dangerously behind.

Read more...

Wednesday, November 26, 2008

Cách phân trang dữ liệu trong SQL Server 2005

Khi tìm kiếm và hiển thị dữ liệu, việc phân trang dữ liệu kết quả tìm kiếm rất quan trọng, nhất là với lượng dữ liệu lớn. Trong SQL Server 2005 có hàm ROW_NUMBER cho phép bạn thực hiện phân trang các bản ghi nhận được.

Ví dụ sau sẽ minh họa cách thực hiện phân trang dữ liệu:

CREATE PROCEDURE dbo.spGetManyProducts 
	@ProducNo VARCHAR(13) = NULL,
	@PageIndex INT, 
	@PageSize INT 
AS 
BEGIN 

	WITH ProductRecords AS ( 
		SELECT ROW_NUMBER() OVER (ORDER BY ProductName) AS RowIndex, 
			ProductNo, ProductName, Description 
		FROM TbProducts
		WHERE (@ProductNo IS NULL OR ProductNo LIKE @ProductNo)
	) , GetTotalRowCount AS ( 
		SELECT MAX(RowIndex) AS TotalRowCount 
		FROM ProductRecords 
	) 
	SELECT ProductNo, ProductName, Description, TotalRowCount 
	FROM ProductRecords, GetTotalRowCount 
	WHERE (RowIndex BETWEEN (@PageIndex - 1) * @PageSize + 1 AND @PageIndex*@PageSize) 
END

Trong đoạn code TSQL ở trên còn cho phép bạn lấy về tổng số dòng dữ liệu có thể nhận được với mỗi kết quả tìm kiếm.

Đây là cách chỉ được sử dụng trên SQL Server 2005 hoặc mới hơn. Còn với SQL Server 2000, bạn có thể sử dụng bảng tạm để lấy toàn bộ kết quả tìm kiếm, sau đó lấy ra các dòng cần thiết với câu lệnh phù hợp. Tôi có 1 cách khác để phân trang trên SQL Server 2000 sẽ đưa ra trong một dịp khác.