Wednesday, June 30, 2010

Transfer logins in SQL Server 2005 and SQL Server 2008

/*------------------------------------------------------------------------------------------------------------

Transfer logins in SQL Server 2005 and SQL Server 2008


In this script we cover sp_help_revlogin stored procedure which can help you copy sql server logins from one server to another server running SQL Server 2008.

This can be useful when you are trying to copy a database from one server (maybe production) to another (development or stage). Remember when you copy a database it does not move the SQL Server Logins which are present at the server level. You have to manually transfer the login accounts from the source ms sql server to target ms sql server.

Using the information here you can easily do this task.

------------------------------------------------------------------------------------------------------------*/

/*

Transfer logins SQL Server 2005 - Step 1


 Create sp_help_revlogin procedure

Sources:

http://support.microsoft.com/kb/246133/

http://blog.netnerds.net/2009/01/migratetransfer-sql-server-2008200520007-logins-to-sql-server-2008/

This needs to be run on the source sql server, the one you are copying the logins from


*/

----- Begin Script, Create sp_help_revlogin procedure -----



USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
  DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(256),
    @hexvalue varchar (514) OUTPUT
AS
DECLARE @charvalue varchar (514)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = '0x'
SELECT @i = 1
SELECT @length = DATALENGTH (@binvalue)
SELECT @hexstring = '0123456789ABCDEF'
WHILE (@i <= @length)
BEGIN
  DECLARE @tempint int
  DECLARE @firstint int
  DECLARE @secondint int
  SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
  SELECT @firstint = FLOOR(@tempint/16)
  SELECT @secondint = @tempint - (@firstint*16)
  SELECT @charvalue = @charvalue +
    SUBSTRING(@hexstring, @firstint+1, 1) +
    SUBSTRING(@hexstring, @secondint+1, 1)
  SELECT @i = @i + 1
END

SELECT @hexvalue = @charvalue
GO

IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
  DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
DECLARE @name sysname
DECLARE @type varchar (1)
DECLARE @hasaccess int
DECLARE @denylogin int
DECLARE @is_disabled int
DECLARE @PWD_varbinary  varbinary (256)
DECLARE @PWD_string  varchar (514)
DECLARE @SID_varbinary varbinary (85)
DECLARE @SID_string varchar (514)
DECLARE @tmpstr  varchar (1024)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)

DECLARE @defaultdb sysname

IF (@login_name IS NULL)
  DECLARE login_curs CURSOR FOR

      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSE
DECLARE login_curs CURSOR FOR

      SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
      ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
OPEN login_curs

FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGIN
  PRINT 'No login(s) found.'
  CLOSE login_curs
  DEALLOCATE login_curs
  RETURN -1
END
SET @tmpstr = '/* sp_help_revlogin script '
PRINT @tmpstr
SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'
PRINT @tmpstr
PRINT ''
WHILE (@@fetch_status <> -1)
BEGIN
  IF (@@fetch_status <> -2)
  BEGIN
    PRINT ''
    SET @tmpstr = '-- Login: ' + @name
    PRINT @tmpstr
    IF (@type IN ( 'G', 'U'))
    BEGIN -- NT authenticated account/group

      SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
    END
    ELSE BEGIN -- SQL Server authentication
        -- obtain password and sid
            SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )
        EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
        EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT

        -- obtain password policy state
        SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
        SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
         SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'

        IF ( @is_policy_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked
        END
        IF ( @is_expiration_checked IS NOT NULL )
        BEGIN
          SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked
        END
    END
    IF (@denylogin = 1)
    BEGIN -- login is denied access
      SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )
    END
    ELSE IF (@hasaccess = 0)
    BEGIN -- login exists but does not have access
      SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )
    END
    IF (@is_disabled = 1)
    BEGIN -- login is disabled
      SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'
    END
    PRINT @tmpstr
  END

  FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
   END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
GO


 ----- End Script, Create sp_help_revlogin procedure -----


/*

Transfer logins in SQL Server 2005 - Step 2


Run the following script on the source SQL Server. After you execute the SQL, this stored procedure will go ahead and generate the SQL code for your Logins.  You can then copy this SQL code and execute it on the target server.

*/


--USE [Enter your database]

EXEC master..sp_help_revlogin



For our case I am using Northwind sample database. I have included a screen shot of what this looks like on my machine.





Transfer logins SQL Server 2005 - Step 3


--Execute the sql code generated by the previous step on your target (destination) SQL Server, This will copy all the login information to the destination server.


Here is part of the SQL script.


/* sp_help_revlogin script
** Generated Jun 30 2010  4:08PM on KASHMONEY-PC */


-- Login: ##MS_PolicyEventProcessingLogin##
CREATE LOGIN [##MS_PolicyEventProcessingLogin##] WITH PASSWORD = 0x01003869D680ADF63DB291C6737F1EFB8E4A481B02284215913F HASHED, SID = 0x0A6983CDF023464B9E86E4EEAB92C5DA, DEFAULT_DATABASE = [master], CHECK_POLICY = ON, CHECK_EXPIRATION = OFF; ALTER LOGIN [##MS_PolicyEventProcessingLogin##] DISABLE

-- Login: ##MS_PolicyTsqlExecutionLogin##
CREATE LOGIN [##MS_PolicyTsqlExecutionLogin##] WITH PASSWORD = 0x01008D22A249DF5EF3B79ED321563A1DCCDC9CFC5FF954DD2D0F HASHED, SID = 0x8F651FE8547A4644A0C06CA83723A876, DEFAULT_DATABASE = [master], CHECK_POLICY = ON, CHECK_EXPIRATION = OFF; ALTER LOGIN [##MS_PolicyTsqlExecutionLogin##] DISABLE

-- Login: NT AUTHORITY\SYSTEM
CREATE LOGIN [NT AUTHORITY\SYSTEM] FROM WINDOWS WITH DEFAULT_DATABASE = [master]

-- Login: NT SERVICE\MSSQLSERVER
CREATE LOGIN [NT SERVICE\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE = [master]


Also we have included a screen shot right below of what it looks like:



TAGS: SQL Server 2005, Copy SQL Logins, sp_help_revlogin, SQL Server 2005

Thursday, June 17, 2010

Why Table Variables are better than Temporary Tables

Why Table Variables are better than Temporary Tables

If you are working with SQL Server tables that have millions of rows, one common technique to speed up your SQL queries and stored procedures is to either use temporary tables or table variables. There is quite a bit of debate on which is the better option, Table Variables or Temporary Tables. We will take a closer look at the two objects with SQL Profiler to decide the winner.

Temporary tables


Temporary tables are similar to static tables, however they are not permanent database objects. Temporary tables are extremely useful as work tables for storing intermediate results and complex queries.  In addition, SQL server creates and maintains them in Tempdb database and drops them when they are no longer needed. You can virtually do everything with a temporary table that you can do with a standard SQL Server table.  You can create indexes, create defaults, modify the table and basically use the temporary table anywhere you need to use a regular persistent database table.  Temporary tables can also be used in stored procedures to improve performance tuning and query optimization.  There are two types of temporary tables:

Local Temporary table:

This is by far the most common type of a temporary table.  When using this one, the scope of the temporary table is limited to the database connection that creates the temp table. The name of the local temporary table must start with a # (Hash symbol) e.g. #local_temp_table. The local temporary table can either be dropped explicitly (best practice), or when the database connection closes.  If you are using a store procedure, the local temporary table will be dropped when the stored procedure ends execution.

Global Temporary table:

Temporary tables can also be shared across many connections in SQL Server. This is possible by using a global temporary table which is visible to any and all connection in SQL server. This table is only deleted when the last connection explicit drops the temporary tables. Global temporary table must begin with 2 ## signs, e.g.##global_temp_table.
Let us take a look at some of these examples next, we are going to be using Northwind database which is a sample database for SQL server. If you would like to download this database, please visit the Northwind download page.

--Create Table #CUSTOMER_DATA 

CREATE TABLE #CUSTOMER_DATA
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL,
)



We will compare the performance of temporary table with a table variable using SQL Server 2008 at the end of this article


Advantages of using temporary tables

Here are some of the advantages of using temporary tables:

-It is possible to create an index on a temporary table
-You can create constraints on a temporary table including Primary Key, unique, NULL and check constraints
-The scope of a temporary table is not only limited to the current session, instead you can extend it to all connections using global temporary table
-Using Statistics is possible on a temporary table
-Temporary table are best suited for big datasets which involves large amount of processing


Disadvantages of using temporary tables

Some of the disadvantages of using temporary tables are:

-For smaller data sets, temporary table are outperformed by table variables
-Generally there is more overhead with temporary table as you have to create the object, populate temporary table  and also log read/write operations
-When using temporary table in a stored procedure, there may be incidence of recompilation


Performance Testing between Temporary Tables and Table Variables

Using Northwind sample database, we are going to create a test table called CUSTOMER_DATA_BAK which contains repeated data from CUSTOMER_DATA table. This test table has 2 million rows so we can compare temporary table with table variable for a large data set. When we run these sql queries we will run a trace in SQL Profiler to capture different parameters and statistics.  We will repeat the test for these scenarios:

1. Temporary table without an index
2. Temporary table with an index
3. Table Variable


Here we have included a transact sql script for testing the first case. It does the following things:

-Clear the data and procedure cache to get a clean baseline
-Create the temporary table
-Populate the temporary table
-Run a select query from the temporary table with formatted customer mailing list


USE Northwind

--TEMP TABLE WITH NO INDEX
--The first command empties the data cache and the second one empties the procedure cache


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

--This displays disk activity and time of TSQL execution


SET STATISTICS IO ON
SET STATISTICS TIME ON

--Create Table #CUSTOMER_DATA


CREATE TABLE #CUSTOMER_DATA
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL,
)

--Populate Temp Table #CUSTOMER_DATA


INSERT INTO #CUSTOMER_DATA
SELECT
CONTACTNAME, ADDRESS, CITY, COUNTRY
FROM DBO.CUSTOMER_DATA_BAK
WHERE CITY IN ('SAN FRANCISCO', 'SEATLLE', 'ELGIN', 'LONDON')

--Select formatted data from Temp Table #CUSTOMER_DATA


SELECT
CONTACTNAME + CHAR(13) + CHAR(10) +
ADDRESS + CHAR(13) + CHAR(10) +
CITY + ' ' + COUNTRY + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)AS PRINT_ADDRESS
FROM #CUSTOMER_DATA
WHERE CITY ='LONDON'

--Explicitly drop the Temp Table #CUSTOMER_DATA


DROP TABLE #CUSTOMER_DATA
 
/* SQL PROFILER RESULTS

CPU= 3274
READS= 72194
WRITES= 2297
DURATION= 162519

*/



You can download this sql script on temp table from this location:
When we look at the trace output from the SQL Profiler on temp table, the numbers are as follows:

CPU=3274
READS=72194
WRITES=2297
DURATION=162519

Here is a screen shot from SQL server Profiler trace



http://www.sqlserver2008tutorial.com/blog/temporary-tables/temp-table-profiler.jpg


Performance Testing on Temp Table with an Index


Next we are going to test the same process, however this time we are going to create an index on the temporary table in addition to the existing code. You can download this sql script on temp table with index from this location:

We have included a partial screen shot of this transact sql code when we tested this in Management Studion in SQL Server 2008:


http://www.sqlserver2008tutorial.com/blog/temporary-tables/create-temp-table-index.jpg

When we look at the trace on temp table with an index from the SQL Profiler, here are the numbers:

CPU=6114
READS=757553
WRITES=3035
DURATION=66602

Here is a screen shot from SQL server Profiler trace



http://www.sqlserver2008tutorial.com/blog/temporary-tables/temp-table-index-profiler.jpg

Table variables:

Table variable is simply a data variable of type table. As such Table variables is created using a declare statement.  It offers an alternative approach to using temporary table and is typically faster and efficient for smaller record sets.  A table variable can store results for later processing similar in concept to using a temporary table. Table variable act like a local variables and their scope ends with the batch that is currently using them.

Here is an example of sql code for a Table variable

--Declare Table Variable @CUSTOMER_DATA
DECLARE @CUSTOMER_DATA TABLE

( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL
)



Advantages of a Table variable


Here are some of the advantages of using table variables:

-In general for smaller record set, table variables outperform the temporary tables
-When using a function with temporary storage, you have to use the table variable as temporary tables will not work
-Table variables do not cause recompilation issues like temporary tables do
-Table variables require fewer system resources causing than them to be less of a performance hit compare to temp tables

Disadvantages of a table variable



Here are some of disadvantages of using table variables:

-The table definition cannot be changed once table variable has been declared
-You cannot use Select Into statements with table variables
-The only way you can create an index in a table variable is to use a Primary Key constraint at the time of table variable declaration
-New Indexes cannot be created after declaration of the table variable
-Performance is slow with table variables when working with large data sets
-Rollback Tran and Truncate table are not allowed with table variables

Performance Testing on Table Variable

Next we are going to repeat the process this time with a table variable.  Here is the script than we are going to use:

USE Northwind

--SQL TABLE VARIABLE
--The first command empties the data cache and the second one empties the procedure cache

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

--This displays disk activity and time of TSQL execution

SET STATISTICS IO ON
SET STATISTICS TIME ON

--Declare Table Variable @CUSTOMER_DATA

DECLARE @CUSTOMER_DATA TABLE
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL
)

--Insert data into Table Variable @CUSTOMER_DATA

INSERT INTO @CUSTOMER_DATA
SELECT
CONTACTNAME, ADDRESS, CITY, COUNTRY
FROM DBO.CUSTOMER_DATA_BAK
WHERE CITY IN ('SAN FRANCISCO', 'SEATLLE', 'ELGIN', 'LONDON')

--Select data from Table Variable @CUSTOMER_DATA

SELECT
CONTACTNAME + CHAR(13) + CHAR(10) +
ADDRESS + CHAR(13) + CHAR(10) +
CITY + ' ' + COUNTRY + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)AS PRINT_ADDRESS
FROM @CUSTOMER_DATA
WHERE CITY ='LONDON'

/* SQL PROFILER RESULTS

CPU= 2730
READS= 71000
WRITES= 2289
DURATION= 46184

*/

Next we are going to repeat the process this time with a table variable.  Here is the script than we are going to

You can also download the temp variable sql script from our site
We have included a screen shot of the SQL profiler results on table variables





http://www.sqlserver2008tutorial.com/blog/temporary-tables/table-variable-profiler.jpg

When we look at the trace on temp table from the SQL Profiler output, here are the numbers:

CPU=2730
READS=71000
WRITES=2289
DURATION=46184

Performance Testing Results between Temp Table and Table Variable





Parameter

Temp Table (No    Index)

Temp Table (With Index)

Table Variable
CPU 3274 6114 2730
DURATION 162519 66602 46184


As you can see using Table Variable is a much better option as it used less CPU and took only 1/3 of time to process the same data!!

For futher query optimization tricks and tips, please visit our site on SQL Server Tutorials

Related Links on the Topic

-Temporary Tables vs. Table Variables
-Should I use a #temp table or a @table variable?





TAGS: Table Variables, Temporary Tables

Friday, May 28, 2010

Change Recovery Model of all your SQL Server databases in one shot

Change Recovery Model of all your SQL Server databases in one shot


/*--------------------------------------------------------------------------------

Sometimes it is necessary to change properties of all your databases in one shot

In this script, we use a system table to get all the database names on our server.

Next we use a cursor to loop through all the records and then change the recovery model using Alter Database command

--------------------------------------------------------------------------------*/

--Declaration of variables

declare
@dbnm sysname,
@sql varchar(100)


-- Declare begin cursor to get the database names and get info from sys.databases catalog

declare cursor_db cursor
for select name from sys.databases where name != 'tempdb'

-- Using a cursor to loop through database names and change recovery model

open cursor_db
fetch next from cursor_db into @dbnm

--While Loop with Alter database command

while @@fetch_status = 0

begin

--print 'database is ' + @dbnm

set @sql='alter database ' + @dbnm + ' set recovery simple'
print 'sql is ' + @sql
exec (@sql)


fetch next from cursor_db into @dbnm
end

--clean up objects

close cursor_db
deallocate cursor_db



Tags: SQL Server 2008, Recovery Model, While loop, Cursor


Source:

http://sqlserver2008tutorial.com/member.htm

Saturday, May 1, 2010

SQL Joins Explained – Inner Joins and Outer Joins using SQL Server 2008



SQL Joins Explained – Inner Joins and Outer Joins using SQL Server 2008


Why do I need SQL Joins again?


Relational databases like SQL Server focus on the concept of “Normalization” which reduces data redundancy.  What this really means is that each subject or group of data in a sql database should really be stored in only one table.  In other words if you have customer data, you need to keep that data in CUSTOMERS table whereas if you have order detail information, this needs to be stored in an ORDERS table. Following this routine eliminates data redundancy in sql tables and makes relational databases like SQL Server efficient in processing data. At the same time it creates a challenge in pulling data together from different tables into a unified sql view. This is where SQL Joins come into play. The Joins facilitate in bringing data from various SQL tables by using T-SQL (Transact SQL) queries. In our case of CUSTOMERS and ORDERS example, a Join in SQL2008 could combine information together from both these tables in our database. We will show you how to do just that here shortly using SQL Server 2008.

SQL Joins are able to pull information by using Primary Key (PK) and Foreign Key (FK) relationships.  Primary Key is a column in a SQL table that uniquely identifies all the rows. In order to understand these concepts, we are going to use Northwind sample database from Microsoft SQL Server. We will be using a few tables from this database to walk you through the Joins in SQL.  More information on this database can be found online at this location, Northwind database

Coming back to SQL joins, in order to understand Primary and Foreign keys, let us take a look at this figure:



In CUSTOMERS, the Primary (aka Parent) table, a column CustomerID with unique values can be used to find a specific customer. This column or field serves as the Primary Key for CUSTOMERS SQL table and is highlighted in blue. Similarly in the Secondary table, ORDERS, we also have a Primary Key column OrderID which is highlighted in blue. This column is the unique identifier for records in the ORDERS table. We have the data and inner join from CUSTOMERS SQL table and ORDERS SQL table in this Excel Spreadsheet


One customer in this SQL Server database can have many orders, as such the database relationship between CUSTOMERS and ORDERS table is one to many. In order to relate CUSTOMERS table to the ORDERS table using Joins in SQL 2008 Server, you would need to add another column CustomerID in the ORDERS table. This column then becomes the Foreign Key for ORDERS table and is highlighted in red. If a customer has placed any orders, this CustomerID column in ORDERS table will contain the same value as CustomerID from CUSTOMERS table. This mechanism is exactly how SQL joins help in bringing related information together from many SQL tables in a unified view.

Types of SQL Joins:


There are two types of SQL Joins, SQL INNER Join and SQL OUTER Join.  A SQL OUTER Join can be subdivided into a Left OUTER Join, Right OUTER Join and a Full OUTER join.

SQL INNER Join:


An SQL INNER join is used to pull matching data from two tables. This is the type of join that is commonly used in databases like SQL Server. In order to understand inner joins in SQL, we are going to use Venn Diagrams which are helpful in understanding the concept.  Take a look at the following figure:




Here we are representing a table by a circle. On the left side we have the CUSTOMERS circle and on the right side we have the ORDERS circle.  The portion where the two circles intersect is common to both and represents Customers that have placed an Order.  As such this common region represents an INNER join in SQL.

We are going to show you the syntax for an INNER join query next:

SELECT columns
FROM table_1 JOIN table_2
ON table_1. primarykey = table_2.foreignkey

Notice the words in bold are SQL keywords and we use the ON clause to match rows from primary and secondary tables. In our database the query for inner join will look like this:   
  
SELECT
CUSTOMERS.CUSTOMERID,
CUSTOMERS.CompanyName,
Orders.CustomerID,
Orders.OrderDate
FROM CUSTOMERS
INNER JOIN ORDERS
ON CUSTOMERS.CUSTOMERID=ORDERS.CUSTOMERID
ORDER BY CUSTOMERS.CUSTOMERID


We have included an output of this data in the following screen capture.





Notice that the two matching columns are highlighted in blue. We have the complete data from Customers SQL table, Orders SQL table and Inner Join in this Excel Spreadsheet

SQL OUTER Join:


A SQL OUTER join is used to bring matching and non matching data from two tables.  There are two types of outer joins in SQL, Left Outer Join and Right Outer Join. 

Left OUTER Join:   


In order to understand Left Outer Joins, let us study this possible scenario:

-What if we wanted to find out CUSTOMERS in our database that has not placed any ORDERS so far?  In other words who is not buying our great products yet?

We could use a Left OUTER join to get this information.  In a Left OUTER join all the data from the main table, CUSTOMERS in our case and any matching data from the ORDERS is returned.  We can further explain a Left OUTER join with the following Venn diagram.



As you can see from the blue line with arrows, a Left OUTER join will not only include the intersection of the two circles (matching data) but that also the portion from Customers circle that is not matching with any Orders.

Here’s the join query for Left Outer Join in SQL Server database.

SELECT
CUSTOMERS.CUSTOMERID,
CUSTOMERS.CompanyName,
Orders.CustomerID,
Orders.OrderDate
FROM CUSTOMERS
LEFT OUTER JOIN ORDERS
ON CUSTOMERS.CUSTOMERID=ORDERS.CUSTOMERID
WHERE Orders.CustomerID IS NULL

The above sql query will return 3 customers that do not have any orders yet. The screen shot from SQL Server Management is shown below




 
One thing we wanted to point out is the last optional line (using IS NULL). This condition forces SQL Server to return Customer rows with no Orders. We have the complete data from Customers SQL table, Orders SQL table and Left Outer Join in this Excel Spreadsheet

Right OUTER Join:

Next we are going to look at Right Outer Join which is the logical opposite of a Left Outer Join. Here’s the scenario:

-What if we were trying to figure out which CATEGORIES in our SQL database have been added recently that do not have any corresponding PRODUCTS yet. How can we solve this problem using a Right Outer Join?

Let’s look at the Venn diagram shown below:



Here you will see that the Right Outer Join is highlighted in dark orange pointed by the blue line. This area includes all the records from CATEGORIES table and matching rows from PRODUCTS table.  If we were to write the transact SQL for this Right Outer Join, it would be as follows:

SELECT 
PRODUCTS.PRODUCTID,
PRODUCTS.PRODUCTNAME,
CATEGORIES.CATEGORYID,
CATEGORIES.CATEGORYNAME
FROM PRODUCTS
RIGHT OUTER JOIN
CATEGORIES
ON PRODUCTS.CATEGORYID = CATEGORIES.CATEGORYID
WHERE PRODUCTS.CATEGORYID IS NULL

The above sql query will return 2 categories that do not have any products yet. Once again the optional IS NULL condition on the last line limits only Categories without any products. If you omit the WHERE clause, you will get a true right join in line with the Venn diagram. A screen capture of this result is as follows.


sql right outer join


We have the complete data from CATEGORIES SQL table, PRODUCTS SQL table, Left Outer Join and Right Outer Join in this Excel Spreadsheet.


Related Links on Inner and Outer Joins


-SQL JOIN

-Examples of Inner and Outer Joins
-Free SQL Server Tutorials

-Inner joins in Oracle



TAGS: SQL, SQL JOIN, INNER JOIN, OUTER JOIN, SQL Server, Primary Key, Foreign Key




Kash


Learning SQL server 2008.com

Wednesday, April 28, 2010

How to check SQL Server Error logs


How to check SQL Server Error logs


When you are trying to troubleshoot problems in SQL Server, one of the best places to check is SQL Server Error logs.  These will have basic information on the issue, what was the source of the problem, what time did it occur so on and so forth.  In order to get to the SQL Server Error log, you would need to do connect to the instance and the following:

Server - Management - SQL Server Logs - Current

I have included a screen shot of this right below:






When you go ahead and double click on one of the SQL Server Error logs, it will open up a new Log File Viewer. This will not only contain information on SQL Server Logs, but also SQL Server Agent Logs, Database Mail and Windows Logs like Application, Security and System Logs.  Here’s a screen capture of what I’m talking about:



You will notice that on the left pane, you can choose which particular log you want to work with.  Within this log, you will see a Current Log and a set of Archive Logs.  Every time SQL Server or the SQL Server Agent is restarted, SQL Server goes ahead and recycles the log and creates a new one.  In this manner you can go back in time to see what issues happened with SQL Server.

On the right side you will have the details pane with information on particular SQL Server related event, when it happened? what was the source? which SQL Server process generated it ETC.  You can further filter these results if you like, you can search for a particular string and even export this SQL Server log to a text file if you need to save it or email it to somebody.

Sometimes the SQL Server error log does not load properly using the SQL Server Management Studio.  For these occasions, SQL Server has an undocumented feature that will let you let you load up SQL Server logs and SQL Server Agent logs using an extended stored procedure.  The procedure is this one xp_readerrorlog and I have included an example of how to use this.



/*------------------------------------------------------------------------------------------------------------

In this script we are looking at two important stored procedures

-master..xp_readerrorlog
-master..xp_fixeddrives

we cover xp_cmdshell in this script using_xp_cmdshell_0011.sql

------------------------------------------------------------------------------------------------------------*/



--reads the current sql server log

exec master..xp_readerrorlog
exec master..xp_readerrorlog 0, 1


--reads the previous sql server log

exec master..xp_readerrorlog 1, 1




--reads the current sql server agent log

exec master..xp_readerrorlog 0, 2


--reads the current sql server agent log

exec master..xp_readerrorlog 1, 2



--get information on disk drives from within sql server


exec master..xp_fixeddrives

/* --OUTPUT

C    30371
D    25803
Q    1011
R    189
S    80834
T    19013

*/


For more information on SQL Server tips and tricks, please visit our site on SQL Server 2008
http://sqlserver2008tutorial.com/


TAGS include SQL Server Error logs, SQL Server Agent logs, Windows NT Log


PS. Happy Birthday baby Sofia, she turns 6 today!!

Tuesday, April 13, 2010

Timeout expired. The timeout period elapsed prior to completion of the operation

Timeout expired. The timeout period elapsed prior to completion of the operation


This is by far my favorite error in Microsoft SQL Server 2008 to date!!!
Let us say that you are trying to modify an existing table using SQL server management studio. Using SSMS Object Explorer, you browse down to the Database, Tables down to the specific table. Right click on the table and select Modify. Next you find the field that needs to be renamed or maybe the size needs to be changed or worse the field needs to be a new data type (yes this does happen in REAL life all the time). Regardless you go ahead and make the change and then try to save your work and then BAMM!! You get this nice wonderful error. In my case I was trying to add a Primary key to a table when this happened. I have included screen shots and some description here.





'stock_price_historical2' table



- Unable to create index 'PK_stock_price_historical'.


Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.


Could not create constraint. See previous errors.
--Error 2

===================================

Next I get this fine dialog box show below with error description after it;



User canceled out of save dialog



(MS Visual Database Tools)

------------------------------


Program Location:


at Microsoft.SqlServer.Management.DataTools.Interop.IDTDocTool.Save(Object dsRef, String path, Boolean okToOverwrite)


at Microsoft.SqlServer.Management.UI.VSIntegration.Editors.DatabaseDesignerNode.Save(VSSAVEFLAGS dwSave, String strSilentSaveAsName, IVsUIShell pIVsUIShell, IntPtr punkDocDataIntPtr, String& strMkDocumentNew, Int32& pfCanceled)

So how do you get around this issue. One option is to change the timeout limit under Tools - Options. In my case it is already set to 0 (infinite!)
 
This is what I have discovered when wrestling with the issue in SQL Server Management Studio. If you go ahead and make the change using the graphic user interface, then right before saving the change, you can go ahead and generate a SQL script that will encompass the modification that you are trying to make through SQL 2008 Management Studio. I know the real DBA'S as are saying, why even bother with this and use the TRANSACT SQL (TSQL) from the getgo. Good point and I am in agreement here 100%. However if you are new to these DBA tasks, this may be your only option.

Getting back to the point, I’m going to show you an example where I was trying to add a primary key to my table, a simple task that you would think, however I’m getting my favorite error so this is what I’m going to do next. I’m going to go to modify the table, right click and choose Set Primary Key as shown below.


I

Next instead of saving this change, I’m going to right click in the empty space and select Generate Change Script. This is also shown below so you can see this in action.



SQL server will then go ahead and generate the change script including all the necessary sql code that you need. You can either select the portion that you like or you can save the whole SQL code to a SQL script. In our case I have just highlighted the portion (ALTER TABLE) that I need.



Finally you can open up a new SQL window, paste the code as shown above and execute the bad boy!!Pretty cool to get around the Annoying Timeout error in my opinion. Hope that helps.

Tags:Timeout expired. The timeout period elapsed prior to completion of the operation

Monday, April 5, 2010

How do you do loop through records one at a time in SQL server?

How do you do loop through records one at a time in SQL server?


This task is quite elementary when it comes to regular programming, however this can be challenging when we are talking about programming in SQL server. The reason for this is that Transact SQL is best at fetching recordsets altogether and not one record at a time. It is optimized for performance and hence is the happiest when working with a bunch of records.

Nevertheless we need to be able to loop through records one at a time. You may want to get customer id from a CUSTOMER table, then use this primary key to pull related data from the Orders table. One way you can do this is using CURSORS which will offer you the ability to loop through records one at a time. Cursors should never be your first choice as they can add a performance hit when it comes to database tuning. Instead you could use while loop or temp tables to do the same action.
Regardless for this blog post I am including an example of a CURSOR that will loop through all the databases and then switch RECOVERY mode to SIMPLE, one by one.



--declaration of variables

declare
@dbnm sysname,
@sql varchar(100)


-- begin cursor to get the database names

declare cursor_db cursor
for select name from sys.databases where name != 'tempdb'

-- using a cursor to loop through database names and change recovery model

open cursor_db
fetch next from cursor_db into @dbnm

while @@fetch_status = 0

begin

--print 'database is ' + @dbnm

set @sql='alter database ' + @dbnm + ' set recovery simple'
print 'sql is ' + @sql
exec (@sql)


fetch next from cursor_db into @dbnm
end

close cursor_db
deallocate cursor_db