Tuesday, January 27, 2009
How to increase the size of a database (Enterprise Manager)
How to Get Available space on Database
Friday, January 16, 2009
Minus Keyword in SQL Server 2000
Oracle supports "Minus" Keyword, but today suddenly when i tried to execute same in SQL Server it won't work. So, here is an alternate way to use "Minus" in SQL Server:-
Example:
Select City, Statefrom Employee Minus Select City, State from Customer
This will work fine with Oracle, but won't work with SQL Server. So alternate way to use "Minus" Keyword in SQL Server:-
Select City, Statefrom Employee Except Select City, State from Customer
Tuesday, January 13, 2009
Create A Comma Delimited List From a Column
Create A Comma Delimited List From a Column
Create Sample Data for Both Solutions
-- Suppress data loading messages SET NOCOUNT ON -- Create Sample Data CREATE TABLE TeamInfo ( MemberID int IDENTITY, TeamID int, FirstName varchar(50) ) -- Load Sample Data INSERT INTO TeamInfo VALUES ( 1, 'Jim' ) INSERT INTO TeamInfo VALUES ( 1, 'Mary' ) INSERT INTO TeamInfo VALUES ( 1, 'Bob' ) INSERT INTO TeamInfo VALUES ( 2, 'Sue' ) INSERT INTO TeamInfo VALUES ( 2, 'Ralph' ) INSERT INTO TeamInfo VALUES ( 2, 'Ellen' ) INSERT INTO TeamInfo VALUES ( 3, 'Bill' ) INSERT INTO TeamInfo VALUES ( 3, 'Linda' )
create function -- SQL 2000, Retrieve desired data
-- With SQL 2000, we will create a User Defined Function to do the concatenation. -- While this solution can also be used with SQL Server 2005/SQL Server 2008, -- the previous suggestion is more efficient. CREATE FUNCTION dbo.fnMakeTeamList ( @TeamID int ) RETURNS varchar(1000) AS BEGIN DECLARE @TempTeam table ( Firstname varchar(20) ) DECLARE @TeamList varchar(1000) SET @TeamList = '' INSERT INTO @TempTeam SELECT FirstName FROM TeamInfo WHERE TeamID = @TeamID IF @@ROWCOUNT > 0 UPDATE @TempTeam SET @TeamList = ( @TeamList + FirstName + ', ' ) RETURN substring( @TeamList, 1, ( len( @TeamList ) - 1 )) END -- Usage SELECT TeamID, MemberList = dbo.fnMakeTeamList( TeamId ) FROM TeamInfo GROUP BY TeamID -- Results TeamID MemberList 1 Jim, Mary, Bob 2 Sue, Ralph, Ellen 3 Bill, LindaS
QL Server 2005 / SQL Server 2008 Solution
--Retrieve desired data SELECT t1.TeamID, MemberList = substring((SELECT ( ', ' + FirstName ) FROM TeamInfo t2 WHERE t1.TeamID = t2.TeamID ORDER BY TeamID, FirstName FOR XML PATH( '' ) ), 3, 1000 )FROM TeamInfo t1 GROUP BY TeamID -- Results TeamID MemberList 1 Bob, Jim, Mary 2 Ellen, Ralph, Sue 3 Bill, Linda
ISNULL() and COALESCE()
ISNULL() and COALESCE()
In dealing with NULL values in SQL Server, the developer is often faced with the requirement to evaluate the content of a field, and when said field in null, return another value (or field). There are two functions in SQL Server which support this requirement: ISNULL() and COALESCE.()
ISNULL() accepts two parameters. The first is evaluated, and if the value is null, the second value is returned (regardless of whether or not it is null). The following queries will return the second parameter in both cases:
SELECT ISNULL(NULL, 1) --Returns 1 SELECT ISNULL(NULL, NULL) --Returns NULL
COALESCE()
COALESCE() is a TSQL function which, like ISNULL, is built into SQL Server. Unlike ISNULL, COALESCE is also a part of the ANSI-92 SQL Standard. Coalesce returns the first non-null expression in a list of expressions. The list can contain two or more items, and each item can be of a different data type. The following are valid examples of COALESCE:SELECT COALESCE(NULL, 1) --Returns 1 SELECT COALESCE(NULL, 3, NULL, 1) --Returns 3
ISNULL vs. COALESCE
Whenever multiple methods exist for addressing a single problem, the inevitable question is: which method is better? There are a few differences between the two functions which make COALESCE come out on top more often than not:- COALESCE is ANSI-92 compliant. In the event that you need to port your code to another RDBMS, COALESCE will not require rework.
- COALESCE accepts greater than two expressions, whereas ISNULL accepts only two. In order to compare three expressions with ISNULL, you would have to nest expressions:
SELECT ISNULL(ISNULL(Col1, Col2), Col3)
- ISNULL constrains the result of a comparison of parameterrs to the datatype of the first value. For example, the following query will produce some often undesirable results using ISNULL, however it will behave as expected with COALESCE:
DECLARE @Field1 char(3), @Field2 char(50) SET @Field2 = 'Some Long String' SELECT ISNULL(@Field1, @Field2) --Returns 'Som' SELECT COALESCE(@Field1, @Field2) --Returns 'Some Long String'Note: In other situations, COALESCE will produce unexpected results. COALESCE by nature promotes it's arguments to the highest datatype among compatable arguments (arguments which are not explicitly case, and which aren't compatable, will of course throw an error). When using COALESCE on an integer and a datetime, in that order, COALESCE will cast the integer as a datetime. For example:
SELECT COALESCE(5, GETDATE())
Will not return 5, it will return 1900-01-06 00:00:00.000 (5 as a datetime).
Performance
For most purposes, ISNULL and COALESCE perform in an almost identical fashion. It is generally accepted that ISNULL is slightly quicker than COALESCE, but not sufficiently to outweigh it's inherent limitations. As with any performance related issue, if performance is a significant concern, write it both ways, and test!SQL2008: Lock a Stored Procedure for Single Use Only
SQL2008: Lock a Stored Procedure for Single Use Only
Create a Custom Error Message, Designating an User assigned Error Number, starting at 50000, or higher, and a user designated Error Message.
USE Northwind GO EXECUTE sp_addmessage @msgnum = 51001, @severity = 16, @msgtext = N'Resource NOT Available', @lang = 'us_english', @replace = REPLACE
Create a Stored Procedure that Can be 'locked'
CREATE PROCEDURE dbo.Employees_U_LastName ( @EmployeeID int, @LastName varchar(20) ) AS BEGIN SET TRANSACTION ISOLATION LEVEL REPEATABLE READ BEGIN TRANSACTION DECLARE @LockResult int EXECUTE @LockResult = sp_getapplock @Resource = 'RepeatableRead_TRANSACTION', @LockMode = 'Exclusive', @LockTimeout = 0 IF @LockResult <> 0 BEGIN ROLLBACK TRANSACTION RAISERROR ( 51001, 16, 1 ) RETURN END -- All code between the use of sp_getapplock above, -- and sp_releaseapplock below will be restricted to -- only one user at a time. -- Ten Second delay for Demonstration Purposes WAITFOR DELAY '00:00:10' -- Remove these three lines for 'Normal' use UPDATE Employees SET LastName = @LastName WHERE EmployeeID = @EmployeeID EXECUTE sp_releaseapplock @Resource = 'RepeatableRead_TRANSACTION' COMMIT TRANSACTION END Demonstration
Open two separate Query Windows, and place the following code in one of the windows.
DO NOT Execute the code until both Query Windows are in place and connected to the database.
Query Window 1
EXECUTE dbo.Employees_U_LastName @EmployeeID = 1, @LastName = 'Davolio-Jones' SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = 1
Place the following code in Query window 2
Query Window 2
EXECUTE dbo.Employees_U_LastName @EmployeeID = 1, @LastName = 'Davolio' SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = 1Execute the code in Query window 1, and then immediately execute the code in Query window 2.
Results in Query Window 2
Msg 51001, Level 16, State 1, Procedure Employees_U_LastName, Line 21 Resource NOT AvailableAs you can see, it becomes possible to control code to single use only.
Clean up the test environment
DROP PROCEDURE dbo.Employees_U_LastName
Concurrency and Performance Considerations
Applications should capture the error, and handle appropriately, perhaps attempting to EXECUTE the query after a brief delay.Finding the Last Occurrence of a Pattern in a String
When dealing with string data, one of the most useful Transact-SQL functions you can have in your toolbox is PATINDEX. Aside from it’s many creative uses (and there are quite a few), it allows you to search for an expression (including wildcard operators) within any valid SQL Server character type. It returns the position of the first occurrence of the pattern within the string, and returns zero (0) if the pattern is not found. As always, an example is worth 1000 bon mots:
SELECT PATINDEX('%c%', 'abcdefgabcdefga')
The above snippet returns 3, because the first instance of “c” within “abcdefgabcdefga” is at the third character.
On occasion, you may be required to find the last occurrence of the pattern rather than the first. This usually happens when you’re dealing with data from external systems, or when you’ve inherited custody of an inappropriately denormalized system (one where more than one “logical” data item has been stored in a single, concatenated field). I have the same requirement for my “mad science” series, so I developed a function to take care of it. Here it is:
CREATE FUNCTION dbo.REVERSEPATINDEX(@StringToFind nvarchar(max),
@StringToSearch nvarchar(max))
RETURNS bigint
AS
BEGIN
--LastIndex will store the "previous" index of the pattern
--while we search for the "next" index inside our string.
DECLARE @LastIndex bigint, @NextIndex bigint
--We will chop off the "searched" portion of our string
--After each search iteration
DECLARE @CurrentStringToSearch nvarchar(max)
--Assign the value of the input parameter to @CurrentStringToSearch
SET @CurrentStringToSearch = @StringToSearch
--Grab the first occurrence, if it exists, using PATINDEX
SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)
--If we've found the pattern within the string, continue and find
--subsequent occurrences until there are no more to find.
WHILE @NextIndex > 0
BEGIN
--Add @NextIndex to @LastIndex, effectively storing within
--@LastIndex the index of the occurence that we have just found,
--based upon the original (non-truncated) string.
SET @LastIndex = COALESCE(@LastIndex,0) + @NextIndex
--Truncate @CurrentStringToSearch, removing the portion of the
--string that we have already searched.
SET @CurrentStringToSearch
= RIGHT(@CurrentStringToSearch, LEN(@CurrentStringToSearch) - @NextIndex)
--Find the NEXT occurence of the pattern in the remaining portion of
--the string to search.
SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)
END
--We will COALESCE @LastIndex and @NextIndex; @LastIndex will be NULL
--if the pattern does not exist in the string (as the loop above will
--never have been executed).
RETURN COALESCE(@LastIndex, @NextIndex)
END
GO
And to test:
SELECT dbo.REVERSEPATINDEX('%c%', 'abcdefgabcdefga')
Returns 10 – the correct answer, given that the last occurrence of “c” in “abcdefgabcdefga” is at the tenth character.