SQL Programming

This section covers advanced SQL programming concepts, including stored procedures, user-defined functions, triggers, cursors, and transaction management. Mastering these elements allows for more complex, efficient, and robust database interactions.

Stored Procedures

Stored procedures are precompiled SQL statements or a set of SQL statements that are stored in the database. They offer benefits such as improved performance, enhanced security, and code reusability.

Creating a Stored Procedure

The basic syntax for creating a stored procedure involves the CREATE PROCEDURE statement.


CREATE PROCEDURE GetCustomerOrders (@CustomerID INT)
AS
BEGIN
    -- Select all orders for the given CustomerID
    SELECT OrderID, OrderDate, TotalAmount
    FROM Orders
    WHERE CustomerID = @CustomerID;
END;
            

Executing a Stored Procedure

You can execute a stored procedure using the EXEC or EXECUTE command.


EXEC GetCustomerOrders 101;
            
Note: Stored procedures can accept input parameters, return output parameters, and execute complex logic including control flow statements like IF-THEN-ELSE and loops.

User-Defined Functions (UDFs)

UDFs are routines that accept parameters, perform actions (like computations or data manipulations), and return a value. They can be scalar (returning a single value) or table-valued (returning a table).

Scalar UDF Example


CREATE FUNCTION CalculateTotalOrderValue (@OrderID INT)
RETURNS DECIMAL(10,2)
AS
BEGIN
    DECLARE @Total DECIMAL(10,2);
    SELECT @Total = SUM(Quantity * Price)
    FROM OrderDetails
    WHERE OrderID = @OrderID;
    RETURN @Total;
END;
            

Using a Scalar UDF


SELECT OrderID, dbo.CalculateTotalOrderValue(OrderID) AS OrderTotal
FROM Orders;
            
Tip: Table-valued functions can be used in the FROM clause of a query, similar to a view, and can improve query readability and modularity.

Triggers

Triggers are a special type of stored procedure that automatically executes or fires in response to certain events on a particular table or view in a database. Common events include INSERT, UPDATE, and DELETE operations.

Creating a Trigger


CREATE TRIGGER UpdateProductInventory
ON OrderDetails
AFTER INSERT
AS
BEGIN
    -- Update the product's stock count after an order item is inserted
    UPDATE Products
    SET StockQuantity = Products.StockQuantity - i.Quantity
    FROM Products
    INNER JOIN inserted i ON Products.ProductID = i.ProductID;
END;
            
Important: Triggers can be complex and may lead to performance issues or unexpected behavior if not carefully designed and tested. Use them judiciously.

Cursors

Cursors allow you to process rows in a result set one by one. While powerful for row-by-row operations, they are generally less performant than set-based operations and should be used only when necessary.

Cursor Example


DECLARE @ProductName VARCHAR(50);
DECLARE product_cursor CURSOR FOR
SELECT ProductName FROM Products;

OPEN product_cursor;
FETCH NEXT FROM product_cursor INTO @ProductName;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- Process @ProductName (e.g., print it)
    PRINT @ProductName;

    FETCH NEXT FROM product_cursor INTO @ProductName;
END;

CLOSE product_cursor;
DEALLOCATE product_cursor;
            

Transactions

Transactions are a sequence of operations performed as a single logical unit of work. They ensure data integrity by adhering to ACID properties (Atomicity, Consistency, Isolation, Durability).

Transaction Control Statements

Transaction Example


BEGIN TRANSACTION;

TRY
BEGIN
    UPDATE Accounts SET Balance = Balance - 100 WHERE AccountID = 1;
    UPDATE Accounts SET Balance = Balance + 100 WHERE AccountID = 2;

    -- Simulate a potential error
    IF 1 = 2 BEGIN
        RAISERROR('Simulated error occurred.', 16, 1);
    END

    -- If all operations are successful, commit the transaction
    COMMIT TRANSACTION;
    PRINT 'Transaction committed successfully.';
END
END

CATCH
BEGIN
    -- If an error occurred, rollback the transaction
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
    PRINT 'Transaction rolled back.';
    -- Handle the error further if needed
    THROW;
END
END