Tuesday, January 13, 2009

Finding the Last Occurrence of a Pattern in a String

When dealing with string data, one of the most useful Transact-SQL functions you can have in your toolbox is PATINDEX. Aside from it’s many creative uses (and there are quite a few), it allows you to search for an expression (including wildcard operators) within any valid SQL Server character type. It returns the position of the first occurrence of the pattern within the string, and returns zero (0) if the pattern is not found. As always, an example is worth 1000 bon mots:

SELECT PATINDEX('%c%''abcdefgabcdefga')

The above snippet returns 3, because the first instance of “c” within “abcdefgabcdefga” is at the third character.

On occasion, you may be required to find the last occurrence of the pattern rather than the first. This usually happens when you’re dealing with data from external systems, or when you’ve inherited custody of an inappropriately denormalized system (one where more than one “logical” data item has been stored in a single, concatenated field). I have the same requirement for my “mad science” series, so I developed a function to take care of it. Here it is:

CREATE FUNCTION dbo.REVERSEPATINDEX(@StringToFind    nvarchar(max),

@StringToSearch nvarchar(max))

RETURNS bigint

AS

BEGIN

--LastIndex will store the "previous" index of the pattern

--while we search for the "next" index inside our string.

DECLARE @LastIndex bigint, @NextIndex bigint


--We will chop off the "searched" portion of our string

--After each search iteration

DECLARE @CurrentStringToSearch nvarchar(max)


--Assign the value of the input parameter to @CurrentStringToSearch

SET @CurrentStringToSearch = @StringToSearch


--Grab the first occurrence, if it exists, using PATINDEX

SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)


--If we've found the pattern within the string, continue and find

--subsequent occurrences until there are no more to find.

WHILE @NextIndex > 0

BEGIN

--Add @NextIndex to @LastIndex, effectively storing within

--@LastIndex the index of the occurence that we have just found,

--based upon the original (non-truncated) string.

SET @LastIndex = COALESCE(@LastIndex,0) + @NextIndex


--Truncate @CurrentStringToSearch, removing the portion of the

--string that we have already searched.

SET @CurrentStringToSearch
= RIGHT(@CurrentStringToSearch, LEN(@CurrentStringToSearch) - @NextIndex)


--Find the NEXT occurence of the pattern in the remaining portion of

--the string to search.

SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)

END


--We will COALESCE @LastIndex and @NextIndex; @LastIndex will be NULL

--if the pattern does not exist in the string (as the loop above will

--never have been executed).

RETURN COALESCE(@LastIndex, @NextIndex)

END

GO

And to test:

SELECT dbo.REVERSEPATINDEX('%c%', 'abcdefgabcdefga')

Returns 10 – the correct answer, given that the last occurrence of “c” in “abcdefgabcdefga” is at the tenth character.

Monday, January 12, 2009

How do you find out all the IDENTITY columns of all the tables in a given database?

How do you find out all the IDENTITY columns of all the tables in a 
given database?

SELECT '[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']' AS [Table Name], COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMNPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), COLUMN_NAME, 'IsIdentity') = 1
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0


Differences Between SQL Server 2000 and 2005

Feature

SQL Server 2000

SQL Server 2005

Server Programming Extensions

Limited to extended stored procedures, which are difficult to write and can impact the server stability.

The incorporation of the CLR into the relational engine allows managed code written in .NET languages to run. Different levels of security can protect the server from poorly written code.

T-SQL Error Handling

Limited to checking @@error, no much flexibility.

Addition of TRY/CATCH allows more mature error handling. More error_xx functions can gather additional information about errors.

T-SQL Language

SQL Language enhanced from previous versions providing strong data manipulation capabilities.

All the power of SQL Server 2000 with the addition of CTEs for complex, recursive problems, enhanced TOP capabilities, PIVOT/APPLY/Ranking functions, and ROW_NUMBER

Auditing

Limited support using triggers to audit changes.

Robust event handling with EVENT NOTIFICATIONS, the OUTPUT clauses, and DDL triggers.

Large Data Types

Limited to 8k for normal data without moving to TEXT datatypes. TEXT is hard to work with in programming environments.

Includes the new varchar(max) types that can store up to 2GB of data in a single column/row.

XML

Limited to transforming relational data into XML with SELECT statements, and some simple query work with transformed documents.

Native XML datatype, support for schemas and full XPATH/XQUERY querying of data.

ADO.NET

v1.1 of ADO.NET included enhancements for client development.

v2 has more features, including automatic failover for database mirroring, support for multiple active result sets (MARS), tracing of calls, statistics, new isolation levels and more.

Messaging

No messaging built into SQL Server.

Includes Service Broker, a full-featured asynchronous messaging system that has evolved from Microsoft Message Queue (MSMQ), which is integrated into Windows.

Reporting Services

An extremely powerful reporting environment, but a 1.0 product.

Numerous enhancements, run-time sorting, direct printing, viewer controls and an enhanced developer experience.

ETL

DTS is a very easy to use and intuitive tool. Limited capabilities for sources and transformations. Some constructs, such as loops, were very difficult to implement.

Integration Services is a true programming environment allowing almost any source of data to be used and many more types of transformations to occur. Very complex environment that is difficult for non-DBAs to use. Requires programming skills.

Full-Text Search

Workable solution, but limited in its capabilities. Cumbersome to work with in many situations.

More open architecture, allowing integration and plug-ins of third party extensions. Much more flexible in search capabilities.

Sql Split function

CREATE FUNCTION Split

(

     @StringToSplit varchar(2048),

     @Separator varchar(128)

)

RETURNS TABLE AS RETURN

WITH CTE AS

(

     SELECT 0 StartIndex, 1 EndIndex

     UNION ALL

     SELECT EndIndex, CHARINDEX(@Separator, @StringToSplit, EndIndex) + LEN(@Separator)

     FROM CTE

     WHERE EndIndex > StartIndex

)

SELECT

     SUBSTRING(@StringToSplit

                        , StartIndex

                        , CASE WHEN EndIndex > LEN(@Separator)

                                  THEN EndIndex-StartIndex-LEN(@Separator)

                                  ELSE LEN(@StringToSplit) - StartIndex + 1

                         END) String

     ,StartIndex StartIndex     

FROM CTE

WHERE StartIndex > 0

How to export GridView to PDF (ASP.NET)

How to export GridView to PDF (ASP.NET)

Recently I have been trying to generate some reports to PDF file format from ASP. NET2.0 application. There are a lot of open source PDF libraries out there that you can use to export to PDF such as iTextSharp, Gios PDF .NET Library and PDFSharp. You can go to this link to find out more open source PDF libraries in C#.

Later I will show you a working solution on how to export GridView to PDF by using one of the free libraries – iTextSharp.

ITextSharp is a port of the iText open source java library written entirely in C# for the .NET platform. It is a library that allows developers to extend the capabilities of their web server applications with dynamic PDF document generation and generate PDF file on the fly.

Before that, you need to download the iTextSharp library. Here is the download link.

Add in the iTextSharp.dll as a reference into your web application.

Here is my sample of code:


using iTextSharp.text;
using iTextSharp.text.pdf;

protected void Page_Load(object sender, EventArgs e)
{
  ExportToPDF();
}

private void ExportToPDF()
{
  Document document = new Document(PageSize.A4, 0, 0, 50, 50);
  System.IO.MemoryStream msReport = newSystem.IO.MemoryStream();

  try {
    // creation of the different writers
    PdfWriter writer = PdfWriter.GetInstance(document, msReport);

    // we add some meta information to the document
    document.AddAuthor("eJuly");
    document.AddSubject("Export to PDF");

    document.Open();

    iTextSharp.text.Table datatable = new iTextSharp.text.Table(7);

    datatable.Padding = 2;
    datatable.Spacing = 0;

    float[] headerwidths = { 6, 20, 32, 18, 8, 8, 8 };
    datatable.Widths = headerwidths;

    // the first cell spans 7 columns
    Cell cell = new Cell(new Phrase("System Users Report",FontFactory.GetFont(FontFactory.HELVETICA, 16,Font.BOLD)));
    cell.HorizontalAlignment = Element.ALIGN_CENTER;
    cell.Leading = 30;
    cell.Colspan = 7;
    cell.Border = Rectangle.NO_BORDER;
    cell.BackgroundColor = newiTextSharp.text.Color(System.Drawing.Color.Gray);
    datatable.AddCell(cell);

    // These cells span 2 rows
    datatable.DefaultCellBorderWidth = 1;
    datatable.DefaultHorizontalAlignment = 1;
    datatable.DefaultRowspan = 2;
    datatable.AddCell("No.");
    datatable.AddCell(new Phrase("Full Name",FontFactory.GetFont(FontFactory.HELVETICA, 14,Font.NORMAL)));
    datatable.AddCell("Address");
    datatable.AddCell("Telephone No.");

    // This cell spans the remaining 3 columns in 1 row
    datatable.DefaultRowspan = 1;
    datatable.DefaultColspan = 3;
    datatable.AddCell("Just Put Anything");

    // These cells span 1 row and 1 column
    datatable.DefaultColspan = 1;
    datatable.AddCell("Col 1");
    datatable.AddCell("Col 2");
    datatable.AddCell("Col 3");

    datatable.DefaultCellBorderWidth = 1;
    datatable.DefaultRowspan = 1;

    for (int i = 1; i < 20; i++) {
      datatable.DefaultHorizontalAlignment =Element.ALIGN_LEFT; 
      datatable.AddCell(i.ToString()); 
      datatable.AddCell("This is my name."); 
      datatable.AddCell("I have a very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very long long address."); 
      datatable.AddCell("0123456789"); 

      datatable.DefaultHorizontalAlignment =Element.ALIGN_CENTER;
      datatable.AddCell("No"); 
      datatable.AddCell("Yes"); 
      datatable.AddCell("No"); 
    } 

    document.Add(datatable); 
  } 
  catch (Exception e) { 
    Console.Error.WriteLine(e.Message); 
  } 

  // we close the document 
  document.Close(); 

  Response.Clear(); 
  Response.AddHeader("content-disposition", "attachment;filename=Export.pdf"); 
  Response.ContentType = "application/pdf"
  Response.BinaryWrite(msReport.ToArray()); 
  Response.End(); 
}


Hope these codes can help those people who are new to asp.net developing and save some time on their searching solutions. You can also find the tutorial of iTextSharp at here.

Import Data from Excel File to sql datatable

Import Data from Excel File to sql datatableTo Export Data Form an Excel file, there is one drawback lying behind them. The Sheet1 from the query actually is the name of the spreadsheet in your excel file. What if there is no Sheet1 inside the excel file? What if you don’t even know the sheet name? 


Yes. I found this error when I tried to upload an excel file with different sheet name. And here is the solution for that.

To get the sheet name in your excel file, firstly, 
Microsoft DAO 3.5 Library is needed. Go to Project -> Reference -> Add Reference, select Microsoft DOA 3.5 Library from the list and add to your project. Here is the example code of how to get the first sheet in the excel file.

Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strSheet As String

dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\test.xls", False, True, "Excel 8.0;")
strSheet = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
"Data Source=C:\test.xls;Extended Properties=""Excel 8.0;"""

da = New OleDbDataAdapter("SELECT * FROM [" & _
strSheet & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)

Import Data from Excel File to sql datatable

Import Data from Excel File to sql datatable

As I has stated in my previous post regarding to Export Data Form an Excel file, there is one drawback lying behind them. The Sheet1 from the query actually is the name of the spreadsheet in your excel file. What if there is no Sheet1 inside the excel file? What if you don’t even know the sheet name? 

Yes. I found this error when I tried to upload an excel file with different sheet name. And here is the solution for that.

To get the sheet name in your excel file, firstly, Microsoft DAO 3.5 Library is needed. Go to Project -> Reference -> Add Reference, select Microsoft DOA 3.5 Library from the list and add to your project. Here is the example code of how to get the first sheet in the excel file.

Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strSheet As String

dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\test.xls", False, True, "Excel 8.0;")
strSheet = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
"Data Source=C:\test.xls;Extended Properties=""Excel 8.0;"""

da = New OleDbDataAdapter("SELECT * FROM [" & _
strSheet & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)