Professional Documents
Culture Documents
11.1 Files
Concept
Files are used for persistent data. A file is a collection of data stored in a disk with a
specific name and a directory path. There are various operations that can be carried on file,
namely, file creation, file write, file read, file save, file close, file open.
Explanation
Also, there are operations to get information about the file like name of the file, size of the
file, properties of file (read only etc), path file, its date and time creation etc.
When a file is opened for reading or writing, it becomes a stream. The stream is basically
a sequence of bytes passing through the communication path. There are two main streams, the
input stream and the output stream.
The input stream is used for reading data from a file (read operation) and the output stream
is used for writing into the file (write operation).
In C#, the System.IO namespace has various classes for performing operation on files,
14. MemoryStream Used for random access to streamed data stored in memory.
15. Path Performs operations on path information.
1. The FileStream class is used in reading from, writing to and closing files.
2. This class derives from the abstract class stream.
3. Using FileStream class -
1. Create a FileStream object (for creating a new file or open an existing file.)
2. Syntax
For example, create a FileStream object F for reading a file named Example.txt as :
Where,
1. FileMode
Mode Description
It opens an existing file and puts cursor at the end of file, or creates the file, if the file
Append
does not exist.
Create It creates a new file. If file is already exist then it will overrite that file.
It will also use to create a new file If the file is already exist then it will throw an
CreateNew
Exception.
Open It opens an existing file.
It specifies to the operating system that it should open a file if it exists, otherwise it
OpenOrCreate
should create a new file.
Truncate It opens an existing file and truncates its size to zero bytes.
2. FileAccess
The FileAccess enumerator has definition of the kind of task that can be performed on file.
AccessMode Description
Read Data can be read from file.
Write Data can be written to the file.
ReadWrite Data can be written to and read from the file.
3. FileShare
Example 1
1. The StreamReader and StreamWriter classes are used for reading from and writing data
to text files.
2. These both classes inherit from the abstract base class Stream that supports reading and
writing bytes into a file stream.
3. Using statements - StreamReader and StreamWriter are best placed in a using-
statement. This ensures that they are removed from memory when no longer needed.
4. The StreamReader Class
The StreamReader class also inherits from the abstract base class TextReader that
represents a reader for reading series of characters.
Commonly used methods of the StreamReader class
Method Name Description
public override void It closes the StreamReader object and the underlying stream and releases any
Close() system resources associated with the reader.
public override int Reads the next character from the input stream and advances the character
Read() position by one character.
The StreamWriter class inherits from the abstract class TextWriter that represents a writer
that can write a series of characters.
Commonly used methods of this class
Method Description
public override void Close() Closes the current StreamWriter object and the underlying stream.
Clears all buffers for the current writer and causes any buffered data
public override void Flush()
to be written to the underlying stream.
public virtual void Writes the text representation of a Boolean value to the text string or
Write(bool value) stream. (Inherited from TextWriter).
public virtual void Writes the text representation of a decimal value to the text string or
Write(decimal value) stream.
public virtual void Writes the text representation of an 8-byte floating-point value to
Write(double value) the text string or stream.
public virtual void Writes the text representation of a 4-byte signed integer to the text
Write(int value) string or stream.
public virtual void WriteLine() Writes a line terminator to the text string or stream.
Example 2
Output
Example 3
Output
Example 4
Output
Example 5
Output
1. The BinaryReader and BinaryWriter classes are used for reading from and writing to a
binary file.
2. The BinaryReader Class
The BinaryReader class is used to read binary data from a file.
A BinaryReader object is created by passing a FileStream object to its constructor.
public virtual int Reads the characters from the underlying stream and advances the current
Read() position of the stream.
public virtual bool Reads a Boolean value from the current stream and advances the current
ReadBoolean() position of the stream by one byte.
Reads the next character from the current stream and advances the current
public virtual char
position of the stream in accordance with the Encoding used and the
ReadChar()
specific character being read from the stream.
Reads the specified number of characters from the current stream, returns
public virtual char[] the data in a character array and advances the current position in accordance
ReadChars(int count) with the Encoding used and the specific character being read from the
stream.
public virtual string Reads a string from the current stream. The string is prefixed with the
ReadString() length, encoded as an integer seven bits at a time.
Writes a Unicode character to the current stream and advances the current
public virtual void
position of the stream in accordance with the Encoding used and the
Write( char ch )
specific characters being written to the stream.
Writes a character array to the current stream and advances the current
public virtual void
position of the stream in accordance with the Encoding used and the
Write( char[] chars )
specific characters being written to the stream.
Example 6
1. To allow to display things on the monitor's screen, the .NET Framework provides a class
named Console. The Console class is defined in the System namespace.
2. The System namespace is part of the mscorlib.dll library. When C# application is
created, the mscorlib.dll library is directly available; which means that it is not required
to import directly.
3. The Console class is static. This means that it can be used without declaring a variable
from it in order to use it.
4. The Console.Write() method is used to display something on the screen, the Console
class provides the Read() method to get a value from the user.
5. To use it, the name of a variable can be assigned to it. The syntax used is :
This simply means that, when the user types something and presses Enter, what the user
had typed would be given (the word is assigned) to the variable specified on the left side of
the assignment operator.
6. Read() doesn't always have to assign its value to a variable. That is, it can be used on its
own line, which simply means that the user is expected to type something but the value
typed by the user would not be necessarily used for any significant purpose.
7. Apart from Read(), the Console class also provides the ReadLine() method. Like the
WriteLine() member function, after performing its assignment, the ReadLine() method
sends the caret to the next line. Otherwise, it works as the Read() function.
Example 7
Example 8
Q.1 What are I/O classes in C# ? Define some of the most commonly used ones.
Ans. : The System.IO namespace in C# consists of several classes used for performing
various file operations, such as creation, deletion, closing, and opening. Some of the most
frequently used I/O classes in C# are :
File - Manipulates a file
Path - Performs operations related to some path information
StreamReader - Reads characters from a stream
StreamWriter - Writes characters to a stream
StringReader - Reads a string buffer
StringWriter - Writes a string buffer
Q.2 What is StreamReader/StreamWriter class ?
Ans. : StreamReader and StreamWriter are classes of namespace System.IO. They are used
when we want to read or write charact90, Reader-based data, respectively.
Some of the members of StreamReader are: Close(), Read(), Readline().
Members of StreamWriter are : Close(), Write(), Writeline().
Q.3 Which class provides the operation of reading from and writing to the console
in C#.NET ?
Ans. : The method for reading and writing to the console in C#.NET is provided by
System.Console class. This class gives us access to the standard input, output and standard
error streams.
Q.4 What is returned when an error condition is generated while read() reads from
the console ?
Ans. : Read() returns -1 on error. This method also throws an IOException on failure.
Q.5 What are advantage and disadvantage using file operation ?
Ans. : The main advantage of files are, they are persistent and they are readily available for
the use of application and the disadvantage is, If the number of users accessing the same
file it will degrades the performance of the application.
Q.6 What is stream in file operations ?
Ans. : Stream is a sequence of bytes traveling from a source to a destination over a
communication path.
Q.7 What is the difference between Dispose ( ) and Flush ( ) ?
Ans. : Dispose ( ) is used to release all resources used by the current instances where as
Flush ( ) is used to clear all buffer for the current stream.
Syllabus : Collections.
12.1 Collection
Concept
1. A collection, is a group, also called a list, is many items of the same kind grouped into
one entity.
Explanation
2. The collection can be based on ant data type items, simple numbers, basic symbols, dates,
strings, times etc.
3. The collection can be of objects that each is made of own internal values
4. The basic rule is that all items included in a collection must be described using the same
characteristics.
Class Description
ArrayList This represents ordered collection of an object that can be indexed individually.
It is alternative to an array. But, unlike array one can add and remove items from
a list at a specified position using an index and the array resizes itself
automatically. Additionally, allows dynamic memory allocation, adding,
searching and sorting items in the list.
Hashtable A hash table is used when one needs to access elements by using key, and
identify a useful key value. Each item in the hash table has a key/value pair. The
key is used to access the items in the collection.
SortedList A sorted list is a combination of an array and a hash table. It contains a list of
items that can be accessed using a key or an index. If it is accessed using an
index, it is an ArrayList, and if accessed using a key , it is a Hashtable. The
collection of items is always sorted by the key value.
BitArray It is used when one needs to store the bits but do not know the number of bits in
advance. BitArray collection item can be accessed by using an integer index,
which starts from zero.
1. Setting Up a Collection
For using the collection first the class is created for data to be stored which would support
various operation applicable to data in the collection say, add item etc.
Example
For an array-based list, one must specify the number of items that the list will contain,
therefore, an array is declared as a field.
Example
//here as the size field is declared private, a property must be provided to access the private //member
outside the class.
Output
Property Description
Capacity Gets or sets the number of elements that the ArrayList can contain.
IsFixedSize Gets a value indicating whether the ArrayList has a fixed size.
Example
Property Description
IsFixedSize Gets a value indicating whether the Hashtable has a fixed size.
Item Gets or sets the value associated with the specified key.
Sr.No. Method
Example
Output
Property Description
IsFixedSize Gets a value indicating whether the SortedList has a fixed size.
Item Gets and sets the value associated with a specific key in the SortedList.
Sr. Methods
No.
Example
Output
Property Description
Example
Output
Property Description
Example
Output
Property Description
Item Gets or sets the value of the bit at a specific position in the BitArray.
Example
Output
Q.1 What is the difference between Hash table and Array list ?
Ans. : Hash table stores data in the form of value pair and name while Array list stores only
values.
You need to pass name to access value from the Hash table while in Array, you need to
pass index number to access value.
In Array, you can store only similar type of data type while in Hash table you can store
different type of data types. ex. int, string etc.
Q.2 What is the meaning of Immutable ?
Ans. : Immutable means once you create a thing, you cannot modify it.
For example : If you want give new value to old value then it will discard the old value
and create new instance in memory to hold the new value.
Q.3 What is the difference between Array and Arraylist ?
Ans. : In an array, we can have items of the same type only. The size of the array is fixed
when compared. To an arraylist is similar to an array, but it doesn't have a fixed size.
Q.4 What's the difference between the System.Array.CopyTo() and
System.Array.Clone () ?
Ans. : Using Clone() method, we creates a new array object containing all the elements in
the original Array and using CopyTo() method. All the elements of existing array copies
into another existing array. Both methods perform a shallow copy.
Q.5 How can we sort the elements of the Array in descending order ?
Ans. : Using Sort() methods followed by Reverse() method.
Q.6 What are Queues and stack collection ?
Ans. : Queues are collection which helps us to add object and retrieve them in the manner
they were added. In other word queues helps us to achieve the first in first out collection
behavior.
In .NET framework memory is managed through the use of Managed Heaps. Generally,
in case of other languages, memory is managed through the Operating System directly.
The program is allocated with some specific amount of memory for its use from the raw
memory allocated by the Operating system and then used up by the program. In case of
.NET environment, the memory is managed through the CLR (Common Language
Runtime) directly and hence .NET memory management is also called as Managed
Memory Management.
Memory management comprises various tasks like allocation of memory, release of
unused memory, searching for unused allocated memory
13.1.1.1 Managed and Unmanaged Resources
Managed resources are created, managed and under scope of CLR, pure .NET code
managed by runtime. Anything that lies within .NET scope and under .NET framework
classes such as string, int, bool variables are referred to as managed code. Periodically
and automatically, managed resources are garbage collected by .NET garbage collection
routine.
UnManaged objects are created outside the control of .NET libraries and are not
managed by CLR, example of such unmanaged code is COM objects, file streams,
connection objects, Interop objects. (Basically, third party libraries that are referred in
.NET code.) Unmanaged resources are the ones that can be files or folders on the disk,
database connections, GUI elements or network resources. They can be some external
elements required to interact with in the applications through some protocol (database
queries or file system manipulation methods). They are called unmanaged not without
a reason - any unmanaged resources accessed from .NET code will not be
automatically cleaned by the garbage collector. That is how they are
not(un)managed.
13.1.1.2 Memory Allocation
1. Garbage Collector (GC) is the part of the .NET framework that allocates and
releases memory for the .NET applications. Finalize is a special method that is
automatically called by the garbage collector (GC) before the object is collected.
6. For each active root, GC builds a graph that contains all the objects that are
reachable from these roots. If an object is unreachable, GC considers it no longer in
use and removes the object from the heap (releases the memory occupied by the
object). After the object is removed, GC compacts reachable objects in memory.
7. Garbage collector generally doesn't take an object as Garbage if it implements
Finalize method. During the process of garbage collection, it first looks for the
object finalization from metadata. If the object has implemented Finalize(), garbage
collector doesn't make this object as unreachable, but it is assigned to as Reachable
and a reference of it is placed to the Finalization queue. Finalize is also handled by a
separate thread called Finalizer thread which traces through the finalizer queue and
calls the finalize of each of those objects and then marks for garbage collection.
8. Thus, if an object is holding an expensive resource, the finalize should be used. But
there is also a problem with this, if finalize method is used, the object may remain in
memory for long even when the object is unreachable. Also, Finalize method is
called through a separate thread, so there is no way to invoke it manually when the
object life cycle ends.
The framework also provides a GC.SuppressFinalize method which tells GC that the
object has been manually disposed and no more finalization is necessary. As soon as
it's called, the object reference is removed from finalization/fReachable queue. The
goal is to prevent finalizing the object twice.
9. .NET Framework provides a System.IDisposable interface which should be
implemented by a class which works with unmanaged resources. To overcome the
problem with Finalize method .NET provides a more sophisticated implementation
of memory management implementing IDisposable interface's Dispose method
which could be invoked manually during object destruction. The only thing that is
needed is to write the code to release memory in the Dispose and call it manually
and not in finalize as Finalize() delays the garbage collection process.
10. Because the Dispose method must be called explicitly, objects that implement
IDisposable must also implement a finalizer to handle freeing resources when
Dispose is not called. By default, the garbage collector will automatically call an
object's finalizer prior to reclaiming its memory. However, once the Dispose method
has been called, it is typically unnecessary for the garbage collector to call the
disposed object's finalizer. To prevent automatic finalization, Dispose
implementations can call the GC.SuppressFinalize method.
1. For better performance of memory release, the managed heap is divided into
segments called generations: 0, 1, and 2 as shown in below figure. When initialized,
the managed heap contains no objects.
2. When objects are just created, they are placed to the Generation 0 (Gen 0).
3. When Gen 0 is full (the size of the heap and generations is defined by GC), GC
performs a garbage collection. During the collection, GC removes all unreachable
objects from the heap. All reachable objects are promoted to the Generation 1
(Gen 1).
4. The Gen 0 collection is a rather quick operation.
5. When Gen 1 is full, the Gen 1 garbage collection is performed. All objects that
survive the collection are promoted to Gen 2. The Gen 0 collection also takes place
here.
6. When Gen 2 is full, GC performs full garbage collection. First, Gen 2 collection is
performed, after this, the Gen 1 and Gen 0 collections take place. If there is still not
enough memory for new allocations, GC raises the Out of Memory exception.
7. During full garbage collection, GC has to pass through all objects in the heap, so,
this process might have a great impact on system resources.
8. So the central idea of generations is, the newer an object is, the shorter its lifetime
will be. The older an object is, the longer its lifetime will be. Newer objects tend to
have strong relationships to each other and are frequently accessed around the same
time. Compacting a portion of the heap is faster than compacting the entire heap.
1. Due to performance reasons, large objects (>85 kB) are stored in a separate segment of
the managed heap called Large Object Heap (LOH).
2. Survived objects in LOH are not compacted. This means that LOH becomes fragmented
over time. Starting from .NET Framework 4.5.1, GC can be forced to compact LOH
during the full garbage collection.
13.1.1.6 Working with System.GC
The System.GC type allows application to have some direct control over the garbage
collector. Inforamation about the maximum generation supported by the managed heap can be
acquired by reading the GC.MaxGeneration property. Currently, the GC.MaxGeneration
property always returns 2.
It is also possible to force the garbage collector to perform a collection by calling one of
the two methods shown below,
The first method allows to specify which generation to collect. Any integer can be passed
to the method ranging from 0 to GC.MaxGeneration, inclusive. Passing 0 causes generation 0
to be collected; passing 1 causes generation 1 and 0 to be collected; and passing 2 causes
generation 2, 1, and 0 to be collected. The version of the Collect method that takes no
parameters forces a full collection of all generations and is equivalent to calling,
As far as possible calling any of the Collect methods should be avoided; it is best to just let
the garbage collector run on its own accord. But as the application knows more about its
behavior than the runtime does, some collections can be forced to be accessed. For example,
in the application full collection of all generations can be forced after the user saves his data
file or internet browsers can perform a full collection when pages are unloaded or application
can force after lengthy operations; this hides the fact that the collection is taking processing
time and prevents a collection from occurring when the user is interacting with the
application.
The GC type also offers a WaitForPendingFinalizers method. This method simply suspends
the calling thread until the thread processing the freachable C# queue has emptied the queue,
calling each object's Finalize method. In addition, the garbage collector offers two methods
that allows to determine which generation an object is currently in,
The first version of GetGeneration takes an object reference as a parameter, and the second
version takes a WeakReference reference as a parameter. The value returned will be
somewhere between 0 and GC.MaxGeneration, inclusive.
13.1.1.7 Cleaning Up Unmanaged Resources
When application has unmanaged objects, GC is unable to clear them and there is need to
release such objects explicitly when finished using them. Mostly unmanaged objects are
wrapped/hide around operating system resources like file streams, database connections,
network related instances, handles to different classes, registries, pointers etc. GC is
responsible to track the life time of all managed and unmanaged objects but still GC is not
aware of releasing unmanaged resources.
1. There are different ways to cleanup unmanaged resources,
2. Implement IDisposable interface and Dispose method
3. 'using' block is also used to clean unmanaged resources
C# supports pointers in a limited extent. Pointers are defined as a variable that contains the
memory address of another variable.
Pointers can be declared as,
Here * is called a de-reference operator and iptr is the variable that contains the address of
integer type variable.
In unsafe context a variable type can be of reference type, value type and pointer type but
pointers can only point to,
primitive value types
struct containing value types only
other pointer types
In C# pointers cannot point to reference types because reference types are managed by
CLR and can be garbage collected but on other hand pointers run under unmanaged
environment and cannot be tracked by GC (garbage collector). A reference can be garbage
collected any time when a pointer pointing to it is de-referenced. So in C# pointers cannot
point to,
reference types
struct containing reference types
13.1.2.4 Pinning an Object
The C# garbage collector can move the objects in memory as it wishes during the garbage
collection process. The C# provides a special keyword fixed to tell Garbage Collector not to
move an object. That means this fixes the in memory locations of the value types pointed to.
This is what is known as pinning in C#. The fixed statement is typically implemented by
generating tables that describe to the Garbage Collector, so as to indicate that which objects
are to remain fixed in which regions of executable code. Thus as long as a Garbage Collector
process doesn't actually occur during execution of fixed statements, there is very little cost
associated with this. However when a Garbage Collector process does occur, fixed objects
may cause fragmentation of the heap. Hence objects should be fixed only when absolutely
necessary and only for the shortest amount of time.
13.1.2.5 Working of Pointers in C#
Example
There are different ways to execute statements as unsafe like a Modifier, constructor, etc.
In the above example, a group of statements are marked as unsafe. In the above code, there are
two variables a and b with values 40 and 20 respectively and pointers contain their addresses.
Console.WriteLine() is used to display the values and addresses of the variables.
13.1.2.6 Pointers and Conversions
In C# pointer types do not inherit from object and no conversion exists between pointer
types and objects. That means boxing and un-boxing are not supported by pointers. But C#
supports conversions between the different pointer types and pointer types and integral types.
C# supports both implicit and explicit pointer conversions within un-safe context. The implicit
conversions are,
1. From any type pointer type to void * type.
2. From null type to any pointer type.
The cast operator (()) is necessary for any explicit type conversions. The explicit type
conversions are,
1. From any pointer type to any other pointer type.
2. From sbyte, byte, short, ushort, int, uint, long, ulong to any pointer type.
3. From any pointer type to sbyte, byte, short, ushort, int, uint, long, ulong types.
13.1.2.7 Pointer Arithmetic
In an un-safe context, the ++ and - operators can be applied to pointer variable of all
types except void * type. The pointer arithmetic works on the size of data type whose
address they are holding and actual address held. In pointer arithmetic it will be absurd
to work on values. Thus for every pointer type P* the following operators are implicitly
overloaded.
The ++ operator adds sizeof(P) to the address contained in the variable and - operator
subtracts sizeof(--) from the address contained in the variable for a pointer variable of
type P*.
In an un-safe context a constant can be added or subtracted from a pointer variable.
Similarly a pointer variable can be subtracted from another pointer variable. But it is
not allowed to add two pointer variables in C#.
In un-safe context relational operators like, = =, ! =, <, >, < =, > = can be applied to value
types of all pointer types. The multiplication and division of a pointer variable with a constant
or with another pointer variable is not possible in C#.
13.1.2.8 Stack Allocation
In an unsafe context, a local declaration may include a stack allocation initializer, which
allocates memory from the call stack. In C#, the operator stackalloc P[Exp,] requires P to be
an unmanaged type and Exp to be an expression of type int. The above construct allocates Exp
* sizeof(P) bytes from the call stack and produces a pointer of the type P* to the newly
allocated block. The Exp is negative, a System.OverFlowException is thrown. If there is not
enough memory to allocate, a System.StackOverflowException is thrown. The content of
newly allocated memory is undefined. There is no way to implicitly free memory allocated
using stackalloc. Instead all stack allocated memory block are automatically discarded once
the function returns.
The structures in C# are value types. The pointers can be used with structures if it contains
only value types as its members. This is illustrated in below program.
Computer programs have to deal with errors and so does the programmer. Errors are
unexpected conditions that are not part of the normal operation of a program say for
example running out of memory.
Explanation
Errors can be classified based on their time of occurrence or based on the damage they
could make to the running process or the way they should be tackled.
There are several kinds of errors.
1. Based on damage they cause - Fatal errors, non-fatal errors,
2. Based on where the damage is caused - system errors, application errors,
3. Based on what made them to occur - Arithmetic errors, IO errors, logical errors,
hardware errors,
Following Fig. 13.2.1 depicts the basic hierarchical classification of errors.
1. When programmer anticipates situations, but does not dealt with it ‘in normal ways’ then
it leads to an exception. The situation could be recoverable through exception handling
mechanism or else can be left unhandled leading to program crash. Exception handling
makes application robust that is tough against all types unexpected situation.
Explanation
2. The program code is put in the try block that may raise an exception followed by a
catch and/or finally block. A try-catch block is placed around the code that might
generate an exception. Code within a try-catch block is referred to as protected code,
3. Variable declarations are generally kept out of the try block so that they can be
accessed in the catch and finally blocks.
4. The try block must be followed by catch or finally or both blocks. The try block
without a catch or finally block will result in a compile time error.
5. A multiple catch block can also be specified with a different exception type is
called exception filters. A multiple catch block is useful when one want to handle
different exceptions in different ways.
6. ‘try’ is a block of code –
A try block identifies a block of code for which particular exceptions is activated or
where in the exception is anticipated. In the nomenclature of exception handling, an
exception is said to be ‘raised by’ the code. Try block is followed by one or more
catch blocks.
7. ‘catch’ is a block of code
The catch block contains the code for handling the exception. That is, it is a
exception handling routine which would be invoked only when the exception is
raised. In the nomenclature of exception handling, the catch block is said to be
‘catching the exception’ and then it runs the own code.
8. ‘Finally’ is a block of code
The finally block is used to execute a given set of statements, in either of the
circumstances, whether an exception is raised or not raised.
The finally block is generally used for cleaning-up code e.g. for disposing an
Output
Example
Output
Example
Example
Output
catch
Output
13. Raising the exception explicitly and throwing it - use of throw keyword
The way exceptions are raised by CLR automatically, similarly, exceptions can be
raised manually.
An exception can be raised manually by using the throw keyword.
Any type of exceptions which is derived from Exception class can be raised using the
throw keyword. The throw keyword cannot be used with any other type which does
not derive from the Exception class.
Example
Output
2. The class encapsulates relevant exception knowledge, like, Place of occurrence (class,
method, line number), Kind of exception, exception message formulation, call stack
information and provides transportation of the exception from the place of origin to the
place of handling.
3. The Exception classes in C#
The System.SystemException class is the base class for all predefined system
exception.
Though built-in various exceptions are provided by .Net environment there can situation
that developer wants to have own object specific exceptions.
Explanation
The user-defined exception classes are derived from the Exception class
Example
Output
In SQL Server, whenever an exception occurred, it displays the exception message and
then continues the program execution. That is it display the error part and continues
further which should not happen.
Exception handling in SQL Server
Handling exceptions in a programming language needs stopping the abnormal
termination and allowing the statements which are not related to the error to execute but
handling an error in SQL Server means stopping the execution of the statements which
are related to the error.
With the introduction of Try/Catch blocks in SQL Server 2005, the error handling in
the SQL server is now very much similar to programming languages like C#.
Example - a stored procedure and its output when the exception is raised
A SQL Server Stored Procedure for dividing two numbers that raises a exception.
When above stored procedure is executed with 100 and 0, following error occurs. This
is because the divisor value is 0 as we know a number cannot be divided by zero as per
the rule of mathematics.
Msg 8134, level 16, state 1, procedure spDivideTwoNumber, Line 21 divide by zero error
encountered.
RESULT IS :
So though the error occurred still the next code is executed. A good application should
not have such processing instead it should convey to the user that what has happened
and then safely either close the application or else wait for further user input. To achieve
this one has to write the exception handling code.
Exception Handling Using RAISERROR System Function
Error Message - The custom error message that is to be displayed whenever the
exception is raised.
Error Severity - In most of the cases, when one is returning custom errors in SQL
Server, there is need to set the ErrorSeverity level as 16, which indicates this is a
general error and the error can be corrected by the user. In above example, the error can
be corrected by passing a nonzero value for the second parameter.
Error State - The ErrorState is also an integer value between 1 and 255. The
RAISERROR() function can only generate custom errors if the Error State value is set
between 1 to 127.
In SQL Server 2000, in order to detect errors, the @@Error system function is used.
The @@Error system function returns a NON-ZERO value if there is an error,
otherwise, ZERO which indicates that the previous SQL statement executed without
any error.
Using @@Error System Function in SQL Server
Modified version of the above stored procedure to make use of @@ERROR system
function is as shown below,
When the above stored procedure is executed passing 100 and 0, it gives the below output.
Msg 8134, level 16, state 1, procedure spDivideTwoNumber, Line 21 divide by zero error
encountered.
RESULT IS :
Predefined Error Terms in Details
Whenever an error occurs under a program like dividing a number by zero, violation of
primary key, violation of Check constraint, etc. the system displays an error message
conveying the application the problem encountered in the code. Every error that occurs
in the program is associated with four attributes.
1. Error Number 2. Error Message 3. Severity Level 4. Error State
Example
Message 8134 (Error Number), Level 16(SEVERITY Level), State 1 (state), Divide by
Zero error encountered (Error Message)
Error Number : The Error number is a unique identifier given for each and every error
that occurs in SQL Server. This value will be below 50,000 for predefined errors and
must be above 50,000 for error defined by the user.
Error Message : It is a piece of brief information describing the error occurred which
should be maxing from 2047 characters.
Severity Level : This tells about the importance of the error which can be ranging
between 0 to 24. In which
1. 0 to 9 : are not serves which can be considered as information or status messages.
2. 11 to 16 : Indicates these errors can be created by the user.
3. 17 to 19 : Indicates these are software errors that cannot be corrected by the user
must be reported to the system administrator.
4. 20 to 24 : Indicates fatal errors and if these errors occur they can damage the system
or database. So here the connection immediately terminates with the database.
Error state : It is an arbitrary value that is not that important can be ranging between
0 to 127. This is used whenever the same error has to occur in multiple places.
In exception handling all T-SQL statements are put into a try block. If all statements
execute without any error then everything is OK else control will go to the catch block.
13.2.5.4 Types of SQL Server Exceptions
Output
Here 60000 denotes the error number and 5 denotes the state to associate with the message.
13.2.5.5 Error Information Using - System Functions
The error message that is system-generated message can be displayed after collecting
information about the error using a system function called the ERROR_MESSAGE().
Consider below error message in context with it all the parts of error message are
discussed below,
SQL Server has six predefined system functions used in the Catch block.
1) ERROR_MESSAGE() - This function will return a text message explaining the
error. One can embed or add own message along with the predefined message.
4) ERROR_STATE() : This function will return an Integer value that indicates the
exact location in the code where the error has occured. In a multi user environment,
the "state" of the error can help locate and diagnose errors with ease.
SELECT ERROR_STATE() AS ErrorState
5) ERROR_PROCEDURE() : Returns the name of the procedure that threw the error.
This can be done by adding the following line inside the catch block.
SELECT ERROR_PROCEDURE() AS Stored_Procedure
If it is not a procedure, but a query then it will return as NULL.
6) ERROR_LINE() : Returns the line number where the actual error has occurred.
This helps developers to pinpoint the place or error (code) and fix it.
13.2.5.6 Advanced SQL Error Handling
The exception handling can be done for transactions as well. This can be achieved by
running and analyzing the XACT_STATE function that reports transaction state.
This function returns one of the following three values,
1 - the transaction is committable
– 1 - the transaction is uncommittable and should be rolled back
0 - there are no pending transactions
The only crucial aspect here is to remember to actually do this inside the catch statement
because it would be required to better stop the transactions and rather than starting it and then
committing it or rolling it back.
1. Attributes are a mechanism for adding metadata, such as compiler instructions and other
data about data, methods, and classes, to the program itself. Attributes are inserted into the
metadata and are visible through ILDasm and other metadata-reading tools.
Explanation
2. An attribute is a declarative tag that is used to convey information to runtime about the
behaviors of various elements like classes, methods, structures, enumerators, assemblies
etc. in the program. One can add declarative information to a program by using an
attribute. A declarative tag is depicted by square ([ ]) brackets placed above the element it
is used for.
3. Attributes are used for adding metadata, such as compiler instruction and other
information such as comments, description, methods and classes to a program. The .Net
Framework provides two types of attributes: the pre-defined attributes and custom built
attributes.
4. Attribute get inherited in the derived classes.
13.3.1.1 Types of Attribute
Member
Usage
name
where, an attribute name and its value are specified within the square brackets ([ ]) before
the element to which the attribute is applied.
3. Attribute might require one or more parameters, positional or named.
Positional parameters are used to specify information about an attribute.
Named parameters are used to convey optional information about an attribute.
The difference between positional parameters and named parameters is that named
parameters are specified with the name of the parameter and are always optional.
The DllImportAttribute attribute is one attribute wherein both positional and named
parameters are seen.
13.3.1.3 Applying Custom Attribute in an application
4. The “Attribute” part of the attribute name is optional. So the following is equivalent to the
attribute above:
5. Whenever there is ambiguity in how an attribute is applied, one can add a target
specification to ensure the right language element is decorated properly.
6. An attribute that helps ensure assemblies adhere to the Common Language Specification
(CLS) is the CLSCompliantAttribute attribute.
7. The CLS is the set of standards that enable different .NET languages to communicate.
Attribute targets are specified by prefixing the attribute name with the target and
separating it with a colon (:).
Example
Output
1. The custom variables can be created through the .NET framework. The information is
stored and can be retrieved at runtime by the user.
2. A simple code can be created to read through the metadata to find the bug fixing notations
and help to update the database. Metadata is data about data. It is used for describing
about other data.
5. Now apply the “CheckAttribute” to some class, the “Customer” as shown in the code
below. Now developers who see this class , see the information right in the front of their
eyes.
Concept
1. Reflection is the process by which a program can read its own metadata . A program is
said to reflect on itself, extracting metadata from its assembly and using that metadata
either to inform the user or to modify its own behavior. Reflection feature in the C#
language to access attributes at runtime.
Explanation
2. In C#, reflection is used to reflect all the information about a program. The programs
make use of the reflection to get the class information at the runtime. They can also reflect
the information about a program.
3. Reflection is used in the process of obtaining type information at runtime. The classes that
provide the information of a running program are in the System.Reflection namespace.
The classes in the Reflection namespace, along with the System.Type and
System.TypedReference classes, provide support for examining and interacting with the
metadata. The abstract base class Type helps access metadata information. The types
include the constructors, methods, fields, properties, and events of a class and the module
and the assembly in which these are stored.
The System.Reflection namespace defines the following types :
Assembly Module
Enum MethodInfo
ConstructorInfo MemberInfo
ParameterInfo Type
FieldInfo EventInfo
PropertyInfo
5. Reflection is much the same as RTTI (RunTime Type Information) of native C++ but
with a major difference in that reflection in C# works with managed code and is much
more powerful.
6. Uses of Reflections
1) To View metadata : Allows the user to view the attribute information from the code
at runtime.
2) To Perform type discovery : It allows the user to examine the various types in an
assembly and instantiate them.
3) Apply late binding to the methods and properties : It allows the user to call
properties and methods on dynamically instantiated objects using the type discovery.
4) Reflection emit : It allows the user to create new types at runtime and use them to
perform the tasks.
13.3.2.2 To View Metadata
Where, the typeof operator on the Calculate type returns the object type of the Type class.
The Type class is the root of the reflection class.
13.3.2.3 Type Discovery
Concept
1. Reflection can be used to explore and examine the contents of an assembly. One can find
the types associated with a module; the methods, fields, properties, and events associated
with a type, as well as the signatures of each of the type's methods; the interfaces
supported by the type; and the type's base class.
Explanation
2. First, load an assembly dynamically with the Assembly.Load static method. The
Assembly class encapsulates the actual assembly itself, for purposes of reflection. The
signature for the Load method is:
public static Assembly.Load(AssemblyName)
3. Secondly, load the assembly, by passing in the Core Library to the Load method.
MsCorLib.dll has the core classes of the .NET Framework:
Assembly a = Assembly.Load("Mscorlib.dll");
4. Once the assembly is loaded, can be called to return an array of Type
objects. The object is the heart of reflection. Type represents type declarations:
classes, interfaces, arrays, values, and enumerations:
Type[] types = a.GetTypes( );
Output
Stack Heap
Ans. : Memory-mapped files are used to map the content of a file to the logical address of
an application. It makes you able to run multiple process on the same machine to share data
with each other. To obtain a memory mapped file object, you can use the method
MemoryMappedFile.CreateFromFiles( ). It represents a persistent memory-mapped file
from a file on disk.
Q.4 What is the difference between dispose() and finalize() ?
Ans. : Although Dispose and Finalize both methods are used by CLR to perform garbage
collection of runtime objects of .NET applications but there is a difference between them.
The Finalize method is called automatically by the runtime while the Dispose method is
called by the programmer.
Q.5 Can multiple catch blocks be executed ?
Ans. : No, Multiple catch blocks can't be executed. Once the proper catch code executed,
the control is transferred to the finally block, and then the code that follows the finally
block gets executed.
Q.6 Difference between throw exception and throw clause.
Ans. : Throw clause - In Throw, the original exception stack trace will be retained. To keep
the original stack trace information, the correct syntax is 'throw' without specifying an
exception.
Declaration of throw
Throw exception - In Throw exception, the original stack trace information will get
override and program will lose the original exception stack trace. That is ,'throw ex' resets the
stack trace.
So basically the Throw exception overwrites the stack trace and this makes it hard to
find the original code line number that has thrown the exception. In turn Throw retains the
stack information and adds to the stack information in the exception that it is thrown.
Ans. :
Q.9 Explain : Handling exceptions from SQL server. (Refer section 13.2.5)