Dynamic Language Runtime

The DLR (Dynamic Language Runtime) is a runtime environment that adds a set of services for dynamic languages to the common language runtime (CLR). The DLR makes it easier to develop dynamic languages to run on the .NET Framework and to add dynamic features to statically typed languages (such as C# and Visual Basic).
The CLR always had dynamic capabilities. You could always use reflection, but its main goal was never to be a dynamic programming environment and there were some features missing. The DLR is built on top of the CLR and adds those missing features to the .NET platform.

Advantages of DLR:

  • Simplifies Porting Dynamic Languages to the .NET Framework
  • Enables Dynamic Features in Statically Typed Languages - Existing .NET Framework languages such as C# and Visual Basic can create dynamic objects and use them together with statically typed objects.
  • Provides Future Benefits of the DLR and .NET Framework
  • Enables Sharing of Libraries and Objects
  • Provides Fast Dynamic Dispatch and Invocation
Examples of dynamic languages are Lisp, Smalltalk, JavaScript, PHP, Ruby, Python, ColdFusion, Lua, Cobra, and Groovy.

Common Language Runtime

The CLR (Common Language Runtime) or the .NET runtime is the runtime execution environment of .NET Framework. Code running under the control of the CLR is often termed managed code and benefits from features such as cross-language integration, cross-language exception handling, enhanced security, versioning and deployment support, a simplified model for component interaction, and debugging and profiling services. The runtime provides the following benefits:

·          Performance improvements.
·          The ability to easily use components developed in other languages.
·          Extensible types provided by a class library.
·          Language features such as inheritance, interfaces, and overloading for object-oriented programming.
·          Support for explicit free threading that allows creation of multithreaded, scalable applications.
·          Support for structured exception handling.
·          Support for custom attributes.
·          Garbage collection.
·          Use of delegates instead of function pointers for increased type safety and security.

Runtime can be understood as a collection of external services that are required to execute a given compiled unit of code.

CLR (Common Language Runtime)



CLR Features in .Net 4.0

What is .NET Framework?

The .NET Framework is a revolutionary platform created by Microsoft for developing applications. The .NET Framework allows the creation of Windows applications, Web applications, Web Services, and pretty much anything else you can think of.

The .NET Framework is composed mainly of three parts:

  • An extensible set of development languages including C# and VB.NET, which must respect a specification named CLS (Common Language Specification). The base types used by these languages must also respect a specification names CTS (Common Type System). 
  • BCL (Base Class Library) - A set of base classes usable from programs developed in these languages.
  • A software layer respecting a specification named CLI (Common Language Infrastructure), which is responsible for the execution of .NET applications and knows only one language named IL (Intermediate Language). The CLI is responsible for the compilation of IL code into machine code during execution of an application. Consequently, the languages supported by .NET must have a compiler which will produce IL code. Microsoft’s implementation of the CLI is named CLR (Common Language Runtime).

What is .NET?



Overview of the .NET Framework - I



Overview of the .NET Framework - II



Overview of the .NET Framework - III


Why use DateTime.TryParse() instead of Convert.DateTime()

Convert.ToDateTime() uses DateTime.Parse() internally, with the current culture - unless you pass it null, in which case it returns DateTime.MinValue.

In short, Convert.ToDateTime() eliminates the code necessary to set the CultureInfo, which you'd have to do to use DateTime.Parse().

Note: If you're not sure string is a valid DateTime, use neither and instead, use DateTime.TryParse().

If you're sure the string is a valid DateTime, and you know the format, you could also consider the DateTime.ParseExact() or DateTime.TryParseExact() methods.

Please note that there may be certain cases when the DateTime.Parse() method fails (since Convert.ToDateTime() uses DateTime.Parse() internally, Convert.ToDateTime() will also fail).

Consider the scenario given below:

If user passes an invalid date format then the method DateTime.Parse() will throw a FormatException.

// throws FormatException, not a valid format
var dt1 = DateTime.Parse("");

// throws FormatException, February doesn’t have a 30th day, not a valid date
var dt2 = DateTime.Parse("02/30/2010 12:35");

Note: It is recommended to use DateTime.TryParse() method to avoid unexpected exceptions especially when accepting inputs from users.

It should be noted that DateTime.Parse() actually calls DateTime.TryParse() and just throws the exception in the event TryParse() returns false. That is, Parse() is roughly equivalent to:

// rough psuedo-code of Parse()
public DateTime Parse(string inputString)
{
     DateTime result;
     if (!DateTime.TryParse(inputString, out result))
     {
         throw new FormatException(...);
     }
     return result;
 }

So calling DateTime.TryParse() directly is more efficient because it avoids the wrapper call, and it doesn’t allocate and throw an unneeded exception in the case of an error.

Triggers in Detail

Basically, triggers are classified into two main types:

  • AFTER Triggers
  • INSTEAD OF Triggers

AFTER Triggers

These triggers are fired only when all operations specified in the triggering SQL statement (INSERT, UPDATE or DELETE), including any referential cascade actions and constraint check, have executed successfully. AFTER is the default if FOR is the only keyword specified. AFTER triggers cannot be defined on views.

AFTER TRIGGERS can be classified into three types:

  • AFTER INSERT Trigger
  • AFTER UPDATE Trigger
  • AFTER DELETE Trigger
Example:

CREATE TABLE Developer
(
in_developer_id INT IDENTITY,
vc_developer_name VARCHAR (100),
dc_developer_salary DECIMAL (10, 2)
)

INSERT INTO Developer VALUES ('Anil', 1000);
INSERT INTO Developer VALUES ('Ricky', 1200);
INSERT INTO Developer VALUES ('Johnnie', 1100);
INSERT INTO Developer VALUES ('Sebastian', 1300);
INSERT INTO Developer VALUES ('Maria', 1400);

Creation of AFTER INSERT TRIGGER to insert the rows inserted into the table into another log table.

CREATE TABLE DeveloperLog
(
in_developer_id INT,
vc_developer_name VARCHAR(100),
dc_developer_salary DECIMAL(10, 2),
vc_log_action VARCHAR(100),
dt_log_timestamp DATETIME
)


AFTER INSERT Trigger This trigger is fired after an INSERT on the Developer table.

CREATE TRIGGER trgAfterInsert ON [dbo].[ Developer]
FOR INSERT
AS
      DECLARE @in_developer_id INT;
      DECLARE @vc_developer_name VARCHAR (100);
      DECLARE @dc_developer_salary DECIMAL (10, 2);
      DECLARE @vc_log_action VARCHAR (100);

      SELECT @in_developer_id = i.in_developer_id FROM inserted i;     
      SELECT @vc_developer_name = i.vc_developer_name FROM inserted i; 
      SELECT @dc_ developer_salary = i.dc_ developer_salary FROM inserted i; 
      SET @vc_log_action = 'Inserted Record -- After Insert Trigger';

      INSERT INTO DeveloperLog (in_developer_id, vc_developer_name, dc_developer_salary, vc_log_action, dt_log_timestamp)
      VALUES (@in_developer_id, @vc_developer_name, @dc_developer_salary, @vc_log_action, GETDATE());
GO

The CREATE TRIGGER statement is used to create the trigger.
THE ON clause specifies the table name on which the trigger is to be attached.
The FOR INSERT specifies that this is an AFTER INSERT trigger. In place of FOR INSERT, AFTER INSERT can be used. Both of them mean the same.

To test the Trigger we insert a row into the Developer table as: 

INSERT INTO Developer VALUES ('Christy', 1500);

Now, a record has been inserted into the Developer table. The AFTER INSERT trigger attached to this table inserts the record into the DeveloperLog as:

6   Christy  1500.00   Inserted Record -- After Insert Trigger       2013-01-21 08:05:55.700


AFTER UPDATE Trigger – This trigger is fired after an update on the table.

CREATE TRIGGER trgAfterUpdate ON [dbo].[Developer]
FOR UPDATE
AS
      DECLARE @in_developer_id INT;
      DECLARE @vc_developer_name VARCHAR (100);
      DECLARE @dc_developer_salary DECIMAL (10, 2);
      DECLARE @vc_log_action VARCHAR (100);

      SELECT @in_developer_id = i.in_developer_id FROM inserted i;     
      SELECT @vc_developer_name = i.vc_developer_name FROM inserted i; 
      SELECT @dc_developer_salary = i.dc_developer_salary FROM inserted i;   
     
      IF UPDATE (vc_developer_name)
            SET @vc_log_action = 'Updated Record -- After Update Trigger';
      IF UPDATE (dc_developer_salary)
            SET @vc_log_action = 'Updated Record -- After Update Trigger';

      INSERT INTO DeveloperLog (in_developer_id, vc_developer_name, dc_developer_salary, vc_log_action, dt_log_timestamp)
      VALUES (@in_developer_id, @vc_developer_name, @dc_developer_salary, @vc_log_action, GETDATE());
GO

The AFTER UPDATE Trigger is created in which the updated record is inserted into the DeveloperLog table. There is no logical table updated like the logical table inserted. We can obtain the updated value of a field from the UPDATE (column_name) function.
We can use, IF UPDATE (vc_developer_name) to check if the column vc_developer_name has been updated.

To test the Trigger we update a record in the Developer table as:

UPDATE Developer SET dc_developer_salary = 2550 WHERE in_developer_id = 6

This inserts the row into the DeveloperLog table as:

6  Chris  2550.00  Updated Record -- After Update Trigger           2013-01-21 08:06:55.700


AFTER DELETE Trigger – This trigger is fired after a delete on the table.

CREATE TRIGGER trgAfterDelete ON [dbo].[Developer]
AFTER DELETE
AS
      DECLARE @in_developer_id INT;
      DECLARE @vc_developer_name VARCHAR (100);
      DECLARE @dc_developer_salary DECIMAL (10, 2);
      DECLARE @vc_log_action VARCHAR (100);

      SELECT @in_developer_id = d.in_developer_id FROM deleted d;
      SELECT @vc_developer_name = d.vc_developer_name FROM deleted d;  
      SELECT @dc_developer_salary = d.dc_developer_salary FROM deleted d;    
      SET @vc_log_action = 'Deleted -- After Delete Trigger';

      INSERT INTO DeveloperLog (in_developer_id, vc_developer_name, dc_developer_salary, vc_log_action, dt_log_timestamp)
      VALUES (@in_developer_id, @ vc_developer_name, @dc_developer_salary, @vc_log_action, GETDATE());
GO

In this trigger, the deleted record’s data is picked from the logical deleted table and inserted into the DeveloperLog table. Delete the record from the Developer table.

A record has been inserted into the DeveloperLog table as:

6  Christy          2550.00  Deleted -- After Delete Trigger.  2008-04-26 12:52:13.867

All the triggers can be enabled / disabled on the table using the statement:

ALTER TABLE Developer {ENABLE|DISBALE} TRIGGER ALL

Specific Triggers can be enabled or disabled as:

ALTER TABLE Developer DISABLE TRIGGER trgAfterDelete

This disables the After Delete Trigger named trgAfterDelete on the specified table.


Instead Of Triggers – This trigger is executed in place of the triggering SQL statement (it acts as an interceptor). The logic in the trigger can override the actions of the triggering statements.
If you define an Instead Of trigger on a table for the Delete operation, then try to delete rows, but the rows will not actually get deleted (unless you issue another delete instruction from within the trigger).

INSTEAD OF TRIGGERS can be classified into three types:

  • INSTEAD OF INSERT Trigger
  • INSTEAD OF UPDATE Trigger
  • INSTEAD OF DELETE Trigger
Example: Create an Instead Of Delete Trigger:

CREATE TRIGGER trgInsteadOfDelete ON [dbo].[Developer]
INSTEAD OF DELETE
AS
      DECLARE @in_developer_id INT;
      DECLARE @vc_developer_name VARCHAR (100);
      DECLARE @dc_developer_salary DECIMAL (10, 2);
     
      SELECT @in_developer_id = d.in_developer_id FROM deleted d;
      SELECT @vc_developer_name = d.vc_developer_name FROM deleted d;
      SELECT @dc_developer_salary = d.dc_developer_salary FROM deleted d;

      BEGIN
            IF (@dc_developer_salary > 1200)
            BEGIN
                  RAISERROR ('Cannot delete where salary > 1200', 16, 1);
                  ROLLBACK;
            END
            ELSE
            BEGIN
                  DELETE FROM Developer WHERE in_developer_id = @in_developer_id;
                  COMMIT;
                  INSERT INTO DeveloperLog (in_developer_id, vc_developer_name, dc_developer_salary, vc_log_action, dt_log_timestamp)
                  VALUES (@in_student_id,@vc_developer_name, @dc_developer_salary, 'Deleted -- Instead Of Delete Trigger', GETDATE());
            END
      END
GO

This trigger will prevent the deletion of records from the table where dc_developer_salary > 1200. If such a record is deleted, the Instead Of Trigger will rollback the transaction, otherwise the transaction will be committed. 

Let’s try to delete a record with the dc_developer_salary >1200:

DELETE FROM Developer WHERE in_developer_id = 4

This will print an error message as defined in the RAISERROR statement:

Server: Msg 50000, Level 16, State 1, Procedure trgInsteadOfDelete, Line 15
Cannot delete where salary > 1200

Related Post: Triggers in SQL

Triggers in SQL

A trigger is a special type of stored procedure that is automatically invoked when the data in a specified table or view is modified. The INSERT, UPDATE and DELETE statements can invoke a trigger. A trigger has the capability to query other tables and includes complex SQL statements.

A trigger can be used to reference or update data in another database or even on another server. When a trigger is fired, it becomes a part of the transaction from which the original data was modified. If a server error occurs, the entire transaction is rolled back automatically.

Differentiate between DML and DDL triggers

  • DDL trigger is a new feature added to SQL Server 2005, whereas DML triggers were user even with SQL Server 7.0 and 2000.
  • DML triggers execute many SQL statements or procedure on execution of a DML statement, like INSERT, UPDATE or DELETE.
  • SQL Server 2005 permits a user to create a trigger that can perform an action in case a DDL statement is executed. These triggers are used when the user wants to performs an action when a schema change occurs.
  • A DDL trigger is a type of stored procedure that is executed automatically when an event occurs in the database server.
  • DDL triggers are executed in response to the various data definition language (DDL) events, such as CREATE, ALTER, and DROP statements.

Limitations of Triggers

  • The CREATE TRIGGER statement can apply to only one table. Moreover, it must be the first statement in the batch.
  • Permission to create triggers on a table or view defaults to the owner of the table or view.
  • Triggers can only be created in the current database, although they can reference objects outside the current database.
  • Triggers cannot be created on a temporary table or system table. Temporary tables can be created and referenced by a trigger. Instead of referencing system tables, you should reference the Information Schema Views.
  • If a table contains a foreign key with an UPDATE or DELETE cascading action defined, then INSTEAD OF UPDATE or INSTEAD OF DELETE triggers should not be defined on the table.
  • The TRUNCATE TABLE statement will not fire a DELETE trigger because this action is not logged.
  • The WRITETEXT statement, whether logged or unlogged, will not activate a trigger.

Q. What are the two main methods for enforcing business rules and data integrity at the server?
A. The two main methods for enforcing business rules and data integrity at the server are constraints and triggers. The main benefit of triggers over constraints is the capability to perform complex processing logic using SQL.

Related Post: Triggers in Detail