Pages

Showing posts with label Database. Show all posts
Showing posts with label Database. Show all posts

Saturday, June 19, 2010

Creating SQL Server Limited User Account

Sometimes you need to create a limited user account in SQL Server 2005. This is a trivial task but I find many new DB developers struggling to do so. However, if you understand the underlying concept, it indeed is trivial.

This is how I find new DB developers creating a limited user account:

1. Open up SQL Server Management Studio
2. Expand the desired DB > Security
3. Right click on Users and select New User…
4. In the Database User – New dialog, enter in a User name following by a Login name. Usually both are the same
5. Bang. This is where you get the error “Error 15007 when trying to add a new user

So what went wrong in the above steps? The answer is that you cannot create a User Role without first creating a Login. A Login connects to an SQL Server instance while a User Role defines the database access level. In other words:

Login – SQL Server Level
User – Database Level

Now to create a limited user account, you following steps have to be followed:

1. Open up SQL Server Management Studio
2. Expand Security. You will see a Logins node. Right click on Logins and click on New Login…
3. In the Login – New dialog, enter in a Login name
4. Next click on SQL Server Authentication radio button. Enter and confirm Password.
5. From Default database, select the desired database. Now you are done creating a Login. The next step is to create his specific role
6. Under the SQL Server instance node, Expand Databases > [Database] > Security. You will see a Users node.
7. Right click on Users and select New User…
8. In the Database User – New dialog, under General page, enter in User name
9. In front of Login name, click on the browse (…) button. You will see a Select Login dialog
10. Click on Browse button and check the Login you created above and click OK. Close the Select Login dialog by click on OK
11. Next under Database User – New dialog, click on Securables page. Click on Add button. This will open up Add Objects dialog.
12. Select Specific objects and click OK. This will open up Select Objects dialog.
13. Click on Object Types button. This will open up Select Object Types dialog.
14. Check the desired object type (Tables, Views, Stored Procedures etc) which Login will have access to. Click OK
15. Under Select Objects dialog, click on Browse button. This will open up Browse for Objects dialog. Select the desired objects which Login will have access to. Click OK.
16. Click on OK to close Select Objects dialog.
17. Under Database User - New, you can select each object in Securables list and specify permission level on each object in the Explicit permissions for list
18. Click on OK to close the Database User - New dialog. You have now set permissions on the specific user.

I hope you have found this post to be useful. Please do provide your feedback and stay tuned for more…

Friday, March 19, 2010

Avoiding Cursors in SQL Server 2005



In this post, I will show you a technique which replicates a cursor in SQL Server. The idea is to avoid the overhead of using cursors in SQL Server.

Problem with using Cursors

Some time ago, I used cursors in one of my stored procedure. This procedure returned data which was consumed by a reporting screen. I was working with a limited amount of data for testing purpose so the screen worked great (at least for a while). But when the same stored procedure ran on the production machine with tables having hundreds of thousands of rows, the screen just went slow like anything. The stored procedure returned the data in almost 10 minutes (only). This was acceptable to me :) but not to my management LOL.

I started to debug the stored procedure and it finally dawned on me that the cursors in the stored procedure were causing the application to choke. After doing some googling binging, it was clear to me that that cursors have a performance overhead.

Cursors in SQL Server are great when we need to process data on a row by row basis. Usually a query returns a static dataset, However; at times, we need to process the data for each row before it is returned. This is where cursors come in handy. However cursors can have a performance issue if not used properly. I will not go into details of describing problems associated with cursors. You can find many useful articles online on this subject.

So the hundred thousand million dollar question is that how we can we avoid cursors but still get the same functionality. The point is to be able to process each row before we can return the data. Well there are many techniques to replicate a cursor. In the following section, I will show you the use of Temporary Table to implement cursor functionality.


Using Temporary Table to avoid Cursors

A Temporary Table is used to store data temporarily. When using a temporary table, the table and its data is stored on the disk in the tempdb database. A temporary table can be local or global. A local temporary table is only visible to user who created it and only within the connection which created it. Local variables get dropped when the connection is closed. The basic syntax of creating a Temporary Table is as follows:

CREATE TABLE #MyTable
(
ID int,
Address varchar (50)
)


On the other hand, a global temporary table is visible to anyone connected to the SQL Server instance. These tables are dropped when the last connection to the table is closed. The syntax for creating temporary table is as follows:

CREATE TABLE ##MyTable
(
ID int,
Address varchar (50)
)


To replicate cursors, I will use temporary table in the following code.

Code Listing

USE Northwind

-- Ref 1 - Create temporary table
CREATE TABLE #EmployeeData
(
employeeID INT UNIQUE CLUSTERED,
lastName VARCHAR (20),
firstName VARCHAR (20),
isProcessed BIT
)

-- Ref 2 - Insert Data in temporary table
INSERT INTO
#EmployeeData
SELECT
EmployeeID, LastName, FirstName, 0
FROM
Employees


DECLARE @employeeID INT
DECLARE @fName VARCHAR (20)
DECLARE @lName VARCHAR (20)

-- Ref 3 - Loop through data in the temporary table
WHILE EXISTS (SELECT employeeID FROM #EmployeeData WHERE isProcessed = 0)
BEGIN


-- Ref 4 - Get top employeeID with flag not set
SELECT TOP (1)
@employeeID = employeeID,
@lName = lastName,
@fName = firstName
FROM
#EmployeeData
WHERE
isProcessed = 0

-- Now you can process the data. For bravity, I will only print the full-name
PRINT @fName + ' ' + @lName

-- Ref 4 - Set flag for the currently selected employeeID
UPDATE #EmployeeData SET isProcessed = 1 WHERE employeeID = @employeeID
END

DROP TABLE #EmployeeData


Let me explain the above reference points one by one:

Ref 1: Create a temporary table. The fourth column will be used as a flag to traverse each row replicating a cursor
Ref 2: Insert table from Employee table into temporary table. Set the flag column equal to 0
Ref 3: Traverse each row in temporary table using the fourth column. Loop through each row until flag is equal to 0
Ref 4: Update the flag to 1 of the currently selected row. This way the control will move to the next row with flag equal to 0

I hope the above code is easy to understand now. One question remains that what if we want to traverse the temporary table again. The answer is that all you have to do is update the table by setting the flag equal to 0 using the following regular Update statement:


Update 
#EmployeeData
Set
isProcessed = 0


Now you are ready to process each row again using the above code.

I hope that this post has been useful. Please feel free to share your thoughts. And yes, stay tuned for more :)…

Sunday, January 31, 2010

Connecting to Remote SQL Server Instance


From time to time, we need to connect to remote SQL Server 2005 instances. Connecting to a local SQL Server instance is simple but if you have made a fresh SQL Server installation and you try to connect it remotely, chances are that your attempt may fail.

You might think that this can be a simple task. All you have to do is simply check the "Allow Remote Connection" under the properties of the particular SQL Server instance. However, this will still not work.

The solution is to use SQL Server Configuration Manager. You can do so by clicking on Start -> Programs -> Microsoft SQL Server -> Configuration Tools -> SQL Server Configuration Manager. When the manager opens up, in the right pane, click on SQL Native Client Configuration -> Client Protocols. In the right pane, right click Named Pipes and select 'Enable'.

Thats all you need. Now when you connect to the remote instance, you will do so without any difficulty.

Hope this helps. Stay tunned for more...