All posts by Basavaraj Biradar

CREATE OR ALTER DDL Statement in Sql Server 2016 SP1

CREATE OR ALTER is one of the new Transact-Sql DDL statement supported in Sql Server 2016 SP1. This statement can be used while creating or altering the Stored Procedures, Functions, Triggers and Views. Basically, if we are using this statement with a module like Stored Procedure, then if the Stored Procedure doesn’t exists it will create it and if it already exists then it will alter the the Stored Procedure. The good thing with this statement is, if the module already existing it alters the module definition but preserves the existing permissions on it.

Let us understand this feature with an example. Execute the following script to create a stored procedure WelcomeMessage and then verify the SP content by executing the SP_HELPTEXT statement.

CREATE OR ALTER PROCEDURE WelcomeMessage
AS
    SELECT 'Welcome to Sqlhints'
GO
SP_HELPTEXT WelcomeMessage

RESULT:
Sql Server 2016 SP 1CREATE OR ALTER Statement Example 1

From the above result we can see that the stored procedure WelcomeMessage is created.

Now execute the below statement, which is same as the previous statement and only difference is the change in the WelcomeMessage Stored Procedure definition:

CREATE OR ALTER PROCEDURE WelcomeMessage
AS
    SELECT 'Welcome to WWW.Sqlhints.COM'
GO
SP_HELPTEXT WelcomeMessage

RESULT:
Sql Server 2016 SP 1CREATE OR ALTER Statement Example 2

From the result we can see that this time as the WelcomeMessage stored procedure already exists. The CREATE OR ALTER statement modified the stored procedure definition. So CREATE OR ALTER statement creates the module if it doesn’t exists already, if the module already exists it will alter the module.

In the prior versions of Sql Server to achieve this we would have checked the existence of the module first, if it exists we drop the module and then create the module as shown in the below script. The problem with this approach is the re-creation of the Stored procedure requires us to re-grant the permission as the previous permissions assigned to the object are lost when object is dropped. Where as in case of CREATE OR ALTER statement, for an existing object it uses the ALTER statement, in that way the previous permissions granted to the object remains intact and no need to re-grant.

IF EXISTS(SELECT 1 FROM sys.procedures 
          WHERE Name = 'WelcomeMessage')
BEGIN
    DROP PROCEDURE dbo.WelcomeMessage
END
GO
CREATE PROCEDURE WelcomeMessage
AS
    SELECT 'Welcome to WWW.Sqlhints.COM'
GO

OUTER APPLY in Sql Server

OUTER APPLY operator in Sql Server returns all rows from the LEFT table expression of the OUTER APPLY operator irrespective of whether it produces the corresponding result in the RIGHT table expression or not. The RIGHT table expression columns value will be NULL in the final result for those rows in the LEFT table expression that don’t produce the result from the RIGHT table expression. So from the result perspective we can say that the OUTER APPLY is similar to the classic LEFT OUTER JOIN

To understand OUTER APPLY in Sql Server with extensive list of examples, let us create the demo tables with sample data as shown in the following image by executing the following script:

apply-operator-demonstration-tables

CREATE DATABASE SqlHintsOUTERAPPLYDemo
GO
USE SqlHintsOUTERAPPLYDemo
GO
--Create Customers Table and Insert records
CREATE TABLE Customers 
( CustomerId INT, Name VARCHAR(50) )
GO
INSERT INTO Customers(CustomerId, Name) 
VALUES(1,'Shree'), (2,'Kalpana'), (3,'Basavaraj')
GO
--Create Orders Table and Insert records into it
CREATE TABLE Orders
(OrderId INT, CustomerId INT,Amount MONEY, OrderDate DATETIME)
GO
INSERT INTO Orders(OrderId, CustomerId,Amount,OrderDate) 
VALUES(100,1,100.0,Getdate()-30), (101,1,200.0,Getdate()-20),
      (103,1,300.0,Getdate()-10), (104,2,150.0,Getdate())	
GO

Create a Table Valued Function

Now execute the following script to create an inline Table valued function fnGetLastTwoCustomerOrders, which returns order details of the last 2 orders corresponding to the input customer id.

CREATE FUNCTION dbo.fnGetLastTwoCustomerOrders
( @CustomerId AS INT )  
RETURNS TABLE 
AS 
RETURN ( 
		SELECT TOP 2 * 
		FROM Orders O 
		WHERE O.CustomerId = @CustomerId 
		ORDER BY OrderDate DESC
	)

Let us verify this functions result for the customer id = 1

--Return last two order details for the customer id = 1
SELECT * FROM dbo.fnGetLastTwoCustomerOrders(1) O
GO

RESULT:
apply-operator-table-valued-function-result

OUTER APPLY Examples

Example 1: Demonstrates how we can re-write a very basic LEFT OUTER JOIN query by OUTER APPLY operator

OUTER APPLY is not an alternative for LEFT OUTER JOIN, instead each of them have their own pros and cons. The general rule of thumb is you may like to use the OUTER JOIN if you want to evaluate/execute the RIGHT side table expression or Table Valued function for each row in the LEFT side table expression. Just to demonstrates how we can use OUTER APPLY operator with a very basic example, here in this example will re-write a very basic LEFT OUTER JOIN query by OUTER APPLY.

We can write a query like below by using LEFT OUTER JOIN to get all Customers table rows irrespective of whether a corresponding record exists in the Orders table or not. For the records in the Customers table which don’t have matching records in the Orders table, the Orders table columns in the result will have NULL values

SELECT *
FROM Customers C
        LEFT OUTER JOIN Orders O
	   ON C.CustomerId = O.CustomerId

RESULT
left-outer-join-query

We can re-write the above LEFT OUTER JOIN query using OUTER APPLY as shown below and still get the same result

SELECT *
FROM Customers C
  OUTER APPLY (SELECT * 
               FROM Orders O
     	       WHERE O.CustomerId = C.CustomerId) ORD

RESULT
outer-apply-left-outer-join-equivalent

From the above results we can see that the re-written OUTER APPLY query is returning the same result as that of the LEFT OUTER JOIN query.

[ALSO READ] CROSS APPLY in Sql Server

Example 2: OUTER APPLY operator between a Table and user defined Table Valued Function

We can write a query like below using OUTER APPLY operator to get details of all the customers with their last two order details if it is present. This query basically evaluates the function fnGetLastTwoCustomerOrders for each row in the Customer table by taking CustomerId as the input.

SELECT *
FROM dbo.Customers C
      OUTER APPLY 
        dbo.fnGetLastTwoCustomerOrders(C.CustomerId) O

RESULT:
sql-server-outer-apply-example-1

From the result we can see that for the customer with customer id =1, we have two orders in the result even though this customer has three orders because the function fnGetLastTwoCustomerOrders returns at max the last two orders for any given CustomerId. And for CustomerId =2, we see only one order detail in the result as this customer has placed only one order till now and for the Customer with CustomerId = 3 in the result we can see only the Customer details and all the Order details columns value for this customer is NULL because this customer is yet to place any order.

[ALSO]

[ALSO READ] Sql Server APPLY operator

Example 3: OUTER APPLY operator between a Table and Table Expression

In the example 2 the RIGHT side of the OUTER APPLY operator was User Defined Function, this example demonstrates how we can have a Table Expression on the right side of this operator.

The below script can also achieve the same result as the example 2, but here we have not used the Table Valued Function fnGetLastTwoCustomerOrders instead we have used the derived table.

SELECT *
FROM dbo.Customers C
	OUTER APPLY (SELECT TOP 2 * 
	  	     FROM Orders O 
		     WHERE O.CustomerId = C.CustomerId 
		     ORDER BY OrderDate DESC) ORD

RESULT:
sql-server-outer-apply-example-2

CROSS APPLY in Sql Server

CROSS APPLY operator invokes/executes a Table Valued User Defined Function for each row returned by the LEFT side table expression of the CROSS APPLY operator. It returns only those rows from the LEFT side table expression of the CROSS APPLY operator which produces the result from the RIGHT side Table Valued User Defined function/Table expression. So from the result perspective we can say that the CROSS APPLY is similar to that of the classic INNER JOIN.

To understand CROSS APPLY in Sql Server with extensive list of examples, let us create the demo tables with sample data as shown in the following image by executing the following script:

apply-operator-demonstration-tables

CREATE DATABASE SqlHintsCROSSAPPLYDemo
GO
USE SqlHintsCROSSAPPLYDemo
GO
--Create Customers Table and Insert records
CREATE TABLE Customers 
( CustomerId INT, Name VARCHAR(50) )
GO
INSERT INTO Customers(CustomerId, Name) 
VALUES(1,'Shree'), (2,'Kalpana'), (3,'Basavaraj')
GO
--Create Orders Table and Insert records into it
CREATE TABLE Orders
(OrderId INT, CustomerId INT,Amount MONEY, OrderDate DATETIME)
GO
INSERT INTO Orders(OrderId, CustomerId,Amount,OrderDate) 
VALUES(100,1,100.0,Getdate()-30), (101,1,200.0,Getdate()-20),
      (103,1,300.0,Getdate()-10), (104,2,150.0,Getdate())	
GO

Create a Table Valued Function

Now execute the following script to create an inline Table valued function fnGetLastTwoCustomerOrders, which returns order details of the last 2 orders corresponding to the input customer id.

CREATE FUNCTION dbo.fnGetLastTwoCustomerOrders
( @CustomerId AS INT )  
RETURNS TABLE 
AS 
RETURN ( 
		SELECT TOP 2 * 
		FROM Orders O 
		WHERE O.CustomerId = @CustomerId 
		ORDER BY OrderDate DESC
	)

Let us verify this functions result for the customer id = 1

--Return last two order details for the customer id = 1
SELECT * FROM dbo.fnGetLastTwoCustomerOrders(1) O
GO

RESULT:
apply-operator-table-valued-function-result

CROSS APPLY Examples

Example 1: Demonstrates how we can re-write a very basic INNER JOIN query by CROSS APPLY operator

CROSS APPLY is not an alternative for INNER JOIN, instead each of them have their own pros and cons. The general rule of thumb is you may like to use the CROSS JOIN if you want to evaluate/execute the RIGHT side table expression or Table Valued function for each row in the LEFT side table expression. Just to demonstrates how we can use CROSS APPLY operator with a very basic example, here in this example will re-write a very basic INNER JOIN query by CROSS APPLY.

We can write a query like below by using INNER JOIN to get the details of the Customers who have orders in the Orders table.

SELECT *
FROM Customers C
        INNER JOIN Orders O
	   ON C.CustomerId = O.CustomerId

RESULT
inner-join-query-result

We can re-write the above INNER JOIN query using CROSS APPLY as shown below and still get the same result

SELECT *
FROM Customers C
  CROSS APPLY (SELECT * 
               FROM Orders O
     	       WHERE O.CustomerId = C.CustomerId) ORD

RESULT
cross-apply-inner-join-equivalent

From the above results we can see that the re-written CROSS APPLY query is returning the same result as that of the INNER JOIN query.

[ALSO READ] OUTER APPLY in Sql Server

Example 2: CROSS APPLY operator between a Table and user defined Table Valued Function

We can write a query like below using CROSS APPLY operator to get details of all the customers with their last two order details. This query basically evaluates the function fnGetLastTwoCustomerOrders for each row in the Customer table by taking CustomerId as the input.

SELECT *
FROM dbo.Customers C
      CROSS APPLY 
        dbo.fnGetLastTwoCustomerOrders(C.CustomerId) O

RESULT:
sql-server-cross-apply-example-1

From the result we can see that for the customer with customer id =1, we have two orders in the result even though this customer has three orders because the function fnGetLastTwoCustomerOrders returns at max the last two orders for any given CustomerId. And for CustomerId =2, we see only one order detail in the result as this customer has placed only one order till now and the details of the Customer with CustomerId = 3 is not available in the result because the function fnGetLastTwoCustomerOrders doesn’t return any record as this this customer is yet to place any order.

[ALSO READ] Sql Server APPLY operator

Example 3: CROSS APPLY operator between a Table and Table Expression

In the example 2 the RIGHT side of the CROSS APPLY operator was User Defined Function, this example demonstrates how we can have a Table Expression on the right side of this operator.

The below script can also achieve the same result as that of example 2, but here we have not used the Table Valued Function fnGetLastTwoCustomerOrders instead we have used the derived table.

SELECT *
FROM dbo.Customers C
	CROSS APPLY (SELECT TOP 2 * 
	  	     FROM Orders O 
		     WHERE O.CustomerId = C.CustomerId 
		     ORDER BY OrderDate DESC) ORD

RESULT:
sql-server-cross-apply-example-2