Showing posts with label T-SQL. Show all posts
Showing posts with label T-SQL. Show all posts

Wednesday, 30 December 2015

Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

Solution:

Starting with SQL Server 2008 you must always put a semicolon before WITH statement in CTE

But it is not need on below SQL version of SQL 2008 like SQL 2005,SQL 2000


Code:
create table #t
(
  pName Varchar(20),
  DateBegin DateTime,
  DateEnd DateTime
)

Insert Into #t(pName, DateBegin, DateEnd)
Values('Player1', '01/04/2012', '01/05/2012')

Insert Into #t(pName, DateBegin, DateEnd)
Values('Player2', '02/01/2012', '02/05/2012')


With DateRange(dt) As
(
    Select Convert(Datetime, '01/01/2012')
    UNion All
    Select DateAdd(dd, 1, Dat.dt) From DateRange Dat Where Dat.dt < CONVERT(Datetime, '01/31/2012')
)

Select T.pName, Dt.dt from #t T
Inner Join DateRange Dt on Dt.dt BETWEEN T.DateBegin and T.DateEnd

Drop Table #t

Correct Code:

Code:
create table #t
(
  pName Varchar(20),
  DateBegin DateTime,
  DateEnd DateTime
)

Insert Into #t(pName, DateBegin, DateEnd)
Values('Player1', '01/04/2012', '01/05/2012')

Insert Into #t(pName, DateBegin, DateEnd)
Values('Player2', '02/01/2012', '02/05/2012')


;With DateRange(dt) As----------------------------------To fix error added semicolon on SQL 2008
(
    Select Convert(Datetime, '01/01/2012')
    UNion All
    Select DateAdd(dd, 1, Dat.dt) From DateRange Dat Where Dat.dt < CONVERT(Datetime, '01/31/2012')
)

Select T.pName, Dt.dt from #t T
Inner Join DateRange Dt on Dt.dt BETWEEN T.DateBegin and T.DateEnd

Drop Table #t


Wednesday, 23 December 2015

How To Configure E - Mail In SQL Server

Introduction
In this article I am going to explain how to Configure E - Mail. You can send E-Mail from SQL server. Before sending e mail we have to configure e mail in SQL server.  Here I am explaining how to configure it.
Steps to configure E - Mail in SQL server 

Step 1 : Start SQL server :
Clipboard03.jpg
Step 2 : Expend Management and select Database Mail => Then select Configure database mail :
Clipboard05.jpg
Step 3 :  Database configuration wizard appear, click on Next button :
Clipboard07.jpg
Step 4 : There are four option, select first option " Set up Database Mail by performing the fallowing task" and click on Next button :
Clipboard09.jpg
Step 5 : Now you have to put Profile name and Description and click on Add button to fill other detail :
Clipboard11.jpg
Step 6 : A new window appear click on New Account :
Clipboard13.jpg
Step 7 : Now You have to put other detail like account name, description, email address, server name, port number, user name and password  and click on "OK " :
Clipboard16.jpg
Step 8 : Now you will see that vipendra account is added and click on next :
Clipboard18.jpg
Step 9 : It show some information about your mail account and click on Next Button :
Clipboard20.jpg
Step 10 : This window show information about your account name, mail server and profile name. If every thing ok then click on finish button to complete process :
Clipboard22.jpg
Step 11 : It show a new window which display information that mail is successful configured :
Clipboard24.jpg

Locks and Duration of Transactions in MS SQL Server



It is a common argument which I hear among developers these days, regarding SQL locks. Some say that the ‘locks are held for the duration of the entire transaction’. But others debate that ‘locks will be only held for the duration of the statement execution’. But who is correct ?
Well both parties are correct up to a certain point. Actually lock durations are depend on the Isolation Levels.
As mentioned in the SQL-99 Standards, there are 4 Transaction Isolation Levels
  • Read Committed (Default)
  • Read Uncommitted
  • Repeatable Read
  • Serializable
SQL Server** provides following two additional isolation levels (** SQL Server 2005 & Upwards)
  • Snapshot
  • Read Committed Snapshot
There are several concurrency issues which can occur in a DBMS when multiple users try to access the same data. Each isolation level protects against a specific concurrency problem.
  • Lost Update
  • Dirty Read
  • Non-Repeatable Read
  • Phantom Reads

Lost Update – This can take place in two ways. First scenario: it can take place when data that has been updated by one transaction (Transaction A), overwritten by another transaction (Transaction B), before the Transaction A commits or rolls back. (But this type of lost update can never occur in SQL Server** under any transaction isolation level)
img_screen_02
The second scenario is when one transaction (Transaction A) reads a record and retrieve the value into a local variable and that same record will be updated by another transaction (Transaction B). And later Transaction A will update the record using the value in the local variable. In this scenario the update done by Transaction B can be considered as a ‘Lost Update’.
img_screen_04

Dirty Read – This is when the data which is changed by one transaction (Uncommitted) is accessed by a different transaction. All isolation levels except for the ‘Read Uncommitted’ are protected against ‘Dirty Reads’.
img_screen_05

Non Repeatable Read – This is when a specific set of data which is accessed more than once in one transaction (Transaction A) and between these accesses, it’s being updated or deleted by another transaction (Transaction B). The repeatable read, serializable, and snapshot isolation levels protect a transaction from non-repeatable reads.
img_screen_03

Phantom Read – This is when two queries in the same transaction, against the same table, use the same ‘WHERE’ clause, and the query executed last returns more rows than the first one. Only the serializable and snapshot isolation levels protect a transaction from phantom reads.
img_screen_06

In order to solve the above mentioned concurrency issues, SQL Server uses the following type of locks.
  • Shared or S-locks - Shared locks are sometimes referred to as read locks. There can be several shared locks on any resource (such as a row or a page) at any one time. Shared locks are compatible with other shared locks.
  • Exclusive or X-locks - Exclusive locks are also referred to as write locks. Only one exclusive lock can exist on a resource at any time. Exclusive locks are not compatible with other locks, including shared locks.
  • Update or U-locks - Update locks can be viewed as a combination of shared and exclusive locks. An update lock is used to lock rows when they are selected for update, before they are actually updated. Update locks are compatible with shared locks, but not with other update locks.
Please refer to the following link to get more information regarding lock types. http://msdn.microsoft.com/en-us/library/ms175519.aspx
As I have mentioned earlier, the type of lock which the SQL server will be acquired depends on the active transactions isolation level. I will briefly describe each isolation level a bit further.
Read Committed Isolation Level – This is the default isolation level for new connections in SQL Server. This makes sure that dirty reads do not occur in your transactions. If the connection uses this isolation level, and if it encounters a dirty row while executing a DML statement, it’ll wait until the transaction which owns that row has been committed or rolled back, before continuing execution further ahead.
img_screen_07

Read Uncommitted Isolation level - Though this is not highly recommended by experts, it's better to consider about it too. It may result in a 'dirty read', but when correctly used it could provide great performance benefits.
You should consider using this isolation level only in routines where the issue of dirty reads is not a problem. Such routines usually return information that is not directly used as a basis for decisions. A typical example where dirty reads might be allowed is for queries that return data that are only used in lists in the application (such as a list of customers) or if the database is only used for read operations.
The read uncommitted isolation level is by far the best isolation level to use for performance, as it does not wait for other connections to complete their transactions when it wants to read data that these transactions have modified. In the read uncommitted isolation level, shared locks are not acquired for read operations; this is what makes dirty reads possible. This fact also reduces the work and memory required by the SQL Server lock manager. Because shared locks are not acquired, it is no problem to read resources locked by exclusive locks. However, while a query is executing in the read uncommitted isolation level, another type of lock called a ‘schema stability lock’ (Sch-S) is acquired to prevent Data Definition Language (DDL) statements from changing the table structure. Below is an example of the behavior of this isolation level.
img_screen_08

Repeatable Read Isolation Level - In this isolation level, it guarantees that dirty reads do not happen in your transaction. Also it makes sure that if you execute/issue two DML statements against the same table with the same where clause, both queries will return the same results. But this isolation level will protect against updates and deletes of earlier accessed rows, but not the inserts, which is known as ‘Phantom’ rows concurrency problem. Note that phantom rows might also occur if you use aggregate functions, although it is not as easy to detect.
img_screen_09

Serializable Isolation Level – This guarantees that none of the aforesaid concurrency issues can occur. It is very much similar to the ‘repeatable read isolation level’ except that this prevents the ‘phantom read’ also. But use of this isolation level increases the risk of having more blocked transactions and deadlocks compared to ‘Repeat Read’. However it will guarantee that if you issue two DML statements against the same table with the same WHERE clause, both of them will return exactly the same results, including same number of row count. To protect the transaction from inserts, SQL Server will need to lock a range of an index over a column that is included in the WHERE clause with shared locks. If such an index does not exist, SQL Server will need to lock the entire table.

Snapshot Isolation Level – In addition to the SQL’s standard isolation levels, SQL 2005 introduced ‘Snapshot Isolation Level’. This will protect against all the above mentioned concurrency issues, like the ‘Serializable Isolation Level’. But the main difference of this is, that it does not achieve this by preventing access to rows by other transaction. Only by storing versions of rows while the transaction is active as well as tracking when a specific row was inserted.
To illustrate this I will be using a test database. It’s name is ‘SampleDB’. First you have to enable the ‘Snapshot Isolation Level’ prior using it
alter database SampleDB set allow_snapshot_isolation on;
alter database SampleDB set read_committed_snapshot off;

Now we’ll create a sample table and insert few records.

create table SampleIsolaion(
    id int,
    name varchar(20),
    remarks varchar(20) default ''
)

insert into SampleIsolaion (id,name,remarks)
select 1, 'Value A', 'Def' union
select 2, 'Value B', 'Def'



img_screen_10





Read Committed Snapshot Isolation Level – This can be considered as a new implementation of the ‘Read Committed’ isolation level. When this option is set, this provides statement level read consistency and we will see this using some examples in the post. Using this option, the reads do not take any page or row locks (only SCH-s: Schema Stability locks) and read the version of the data using row versioning by reading the data from tempdb. This option is set at the database level using the ALTER DATABASE command

I will illustrate the use of this isolation level with a sample. First enable the required isolation level.

alter database SampleDB set read_committed_snapshot on;
alter database SampleDB set allow_snapshot_isolation on;


Now lets create a table and populate it with few sample data.

create table sample_table(
    id int,
    descr varchar(20),
    remarks varchar(20)
)

insert into sample_table
select 1,'Val A','Def' union
select 2,'Val B','Def' 

Now open two query windows in SQL Server Management Studio.

--Window 1
begin tran
    update sample_table set descr = 'Val P', remarks = 'Window 1' where id = 1



Without committing execute the following in the second window


--Window 2
begin tran
    set transaction isolation level read committed    
    select * from sample_table
    

And you can see, even without committing, it’ll read from the older values, from the row versions which were created in the tempdb. If it was only the ‘Read Commited’ isolation level without the ‘Read Committed Snapshot’ option turned on, this select statement would have been locked.

Elevate permission on a SQL login having read only access to Execute Stored Procedures and to View Database Schemas

Due to an unavoidable situation, it was decided that all the write access to a particular server (SQL Server) was required to be removed immediately. And only few people should be able to access the server with full privileges. How ever this wasn’t sound very friendly to the developers, since they were using this server for various kinds of activities during their development and testing. Once the write access was removed we ran into various kinds of trouble since majority couldn’t view the contents of the database objects such as Stored Procedures, Views etc.
So a requirement came to allow them to access the schemas so that they can view the contents, also to execute the procedures (required when debugging a flow using Profiler) without allowing anyone to change or add any new database objects nor any data updates to existing tables directly.
The easiest workaround was to create a SQL user login with read permission and grant execution access to that login.
1.  Create a SQL Login.
image

2. Only keep the ‘public’ server role selected for this SQL Login.
image

2. Select ‘db_datareader’ role membership.
image

Afterwards if you connect to the SQL Server using the above created login, you can see that only read only operations are allowed. You will be able to see the tables, views (cannot see the underlying SQL Code). Stored procedures will be hidden

image

image
I have created the following stored procedure in my sample database (AdventureWorks) for testing purpose.
CREATE PROCEDURE ReadOnlyUserProc
AS 
BEGIN
    SELECT GETDATE() AS CurrentDate
END


And when the aforementioned procedure is executed as the ‘readonlyuser’ we will get the following error:


EXEC ReadOnlyUserProc

image

Now lets just provide the necessary access to this login so that it can be use to execute the procedures and to see the schemas of database objects. Use the following code to grant the execution access to the previously created user.


USE AdventureWorks
GO
 
GRANT EXECUTE TO readonlyuser
GO



And now when we execute the stored procedure we will get the desired result.


EXEC ReadOnlyUserProc

image

However still we are unable to see the schema of the SQL Objects, which is a part of what we want in this exercise.

image

If you try to generate the script by right clicking the object you will get an error message:

image

We will try to fix that issue as well. Please follow these steps:

1. Right click the login and go to the properties window.

2. Go to the ‘Securables’ tab and check/tick the ‘Grant’ check box for ‘View any definition’.

3. Click ‘OK’

image

Now you can see the definitions of the database objects.

image

image

image
Hope this might be useful to you as well.

Monday, 14 September 2015

SQL Function to Remove Special Characters and Convert to Multiple Columns by using ParseName Function

In some cases, we may need to remove special characters from a input string such as title or description fields. Sql server does not have build-in function to do that. We have to create our own user-defined function. This function removes any special character from the given string.


CREATE FUNCTION [dbo].[ufn_RemoveSpecialChars]
(
    @Input VARCHAR(MAX)
)
RETURNS VARCHAR(MAX
BEGIN
    
   DECLARE @Output VARCHAR(MAX  )
    
   IF (ISNULL(@Input,'')='')
      SET @Output = @Input
   ELSE
   BEGIN
    
    DECLARE @Len INT
    DECLARE @Counter INT
    DECLARE @CharCode INT
         
    SET @Output = ''
    SET @Len = LEN(@Input)
    
   SET @Counter = 1
    
       WHILE @Counter <= @Len
       BEGIN
           
          SET @CharCode = ASCII(SUBSTRING(@Input, @Counter, 1))
          IF @CharCode=32 OR @CharCode BETWEEN 48 and 57 OR @CharCode BETWEEN 65 AND 90 OR @CharCode BETWEEN 97 AND 122 
             SET @Output = @Output + CHAR(@CharCode)
              
          SET @Counter = @Counter + 1
           
       END
          
   END
       
   RETURN @Output
    
END




Sample Usage

SELECT dbo.[ufn_RemoveSpecialChars]('This^ is $- sample ~text.#&*')
--Output : This is  sample text



Note

If this doesn't meet your requirement, just alter a little bit. Find the ascii code of character what you want to remove. You can check the char code with the code like follow.
?
1
2
3
4
SELECT ASCII('%')
-- Output : 37
SELECT ASCII('~')
-- Output : 126

--Final Query 
--Used function to remove special characters.
--Used ParseName builtin function to split the FullName depending upon ''( space).
--Wrote Case Statement to adjust middle name to last name where there is no last name.

;WITH CTE
     AS (SELECT Reverse(Parsename(Replace(
Reverse(dbo.[Ufn_removespecialchars](FullName)), ' ', '.'), 1)) AS [FirstName],
                Reverse(Parsename(Replace(Reverse(dbo.[Ufn_removespecialchars](FullName)), ' ', '.'), 2)) AS [MiddleName],
                Reverse(Parsename(Replace(Reverse(dbo.[Ufn_removespecialchars](FullName)), ' ', '.'), 3)) AS [LastName]
         FROM   dbo.ColSplit)
SELECT FirstName,
       CASE
         WHEN LastName IS NULL THEN NULL
         ELSE MiddleName
       END AS MiddleName,
       CASE
         WHEN LastName IS NULL
              AND MiddleName IS NOT NULL THEN MiddleName
         ELSE LastName
       END AS LastName
FROM   CTE

The above query can be changed according to the requirement. We can also write a user function to split string string into multiple columns. Here we were required to split FirstName,MiddleName and LastName and that can be handled with built in function.