There are many components involved with reading and writing data to files. Starting from an application (SQL Server or SQLIOSim) the IO request is handed over to the Operating system via an API call. Once in the hands of the OS the request will travel through levels of filter drivers installed by things like antivirus software, backup utilities and finally find its way to a driver that will hand the actual data over to a disk controller, and eventually find its way to a disk or array of disks. There may be caching on the disks, and in the case of high end arrays there may also be logic to determine whether or not to service the request immediately or defer. If even one of these pieces get it wrong the results for your data would be disastrous.
Wouldn’t you rather know there is a problem before you entrust your data to such a complex process?
SQLIOSim is designed to generate exactly the same type and patterns of IO requests at a disk subsystem as SQL Server would, and verify the written data exactly as SQL Server would.
More details and download links are available here
A blog about SQL Server, Books, Movies and life in general
Saturday, October 07, 2006
Yahoo Launches .NET Developer Center, Windows Vista RC2 Available For Download
Yahoo Launches .NET Developer Center
Yahoo! Developer Network has launched .NET Developer Center.This site is your source for information about using the .NET Framework with Yahoo! Web Services and APIs. Here you'll find:
HOWTO Articles to help you understand our technologies and how you can use them better with .NET.
Download the sample browser, utility libraries and source code.
Other Resources on the web where you can find source code and helpful tools.
Community Resources where you can join our mailing list and discuss the Yahoo! APIs with us and with other .NET developers.
Windows Vista RC2 Available For Download
From the site: "Today, Microsoft is excited to announce the availability of Windows Vista RC2 to Technical Beta Testers, TAP Testers, and MSDN/TechNet subscribers. This new build of Windows Vista offers users a higher level of performance and stability – improving what was established in Windows Vista RC1. We were able to also fix many of your bugs reported from RC1 and implement them for RC2. Thank you to our beta testers for the bugs and feedback you submitted for RC1. The improvement shows as we raised our quality bar even higher!
"
Download it here
Yahoo! Developer Network has launched .NET Developer Center.This site is your source for information about using the .NET Framework with Yahoo! Web Services and APIs. Here you'll find:
HOWTO Articles to help you understand our technologies and how you can use them better with .NET.
Download the sample browser, utility libraries and source code.
Other Resources on the web where you can find source code and helpful tools.
Community Resources where you can join our mailing list and discuss the Yahoo! APIs with us and with other .NET developers.
Windows Vista RC2 Available For Download
From the site: "Today, Microsoft is excited to announce the availability of Windows Vista RC2 to Technical Beta Testers, TAP Testers, and MSDN/TechNet subscribers. This new build of Windows Vista offers users a higher level of performance and stability – improving what was established in Windows Vista RC1. We were able to also fix many of your bugs reported from RC1 and implement them for RC2. Thank you to our beta testers for the bugs and feedback you submitted for RC1. The improvement shows as we raised our quality bar even higher!
"
Download it here
Friday, October 06, 2006
SQL Server Blog Of The Week: Snaps & Snippets By Mi Lambda (Matija Lah)
So here we are it's Friday and you know what that means; it's time for our blog of the week. The blog of the week is snaps & snippets by Mi Lambda (Matija Lah). Matija Lah lives in Slovenia, I have visited Slovenia many times; I have been to Ljubljana, Maribor, Koper and Bled. The first I heard about this blog was in the microsoft public sql server programming forum, if you visit the forum look out for the author ML
What do I like about this blog
There are some cool tricks and tips in this blog and the posting go into a lot of detail. it's like reading a book
What are some at the posts I like the most
Column Dependencies and Consequences
Unidirectional synchronisation
Full synchronisation
Date[Time] constructor SQL-style
Where can I see/read/hear more about the author?
check the microsoft.public.sqlserver.programming forum
So there you have it; the SQL Server blog of the week
What do I like about this blog
There are some cool tricks and tips in this blog and the posting go into a lot of detail. it's like reading a book
What are some at the posts I like the most
Column Dependencies and Consequences
Unidirectional synchronisation
Full synchronisation
Date[Time] constructor SQL-style
Where can I see/read/hear more about the author?
check the microsoft.public.sqlserver.programming forum
So there you have it; the SQL Server blog of the week
Thursday, October 05, 2006
SQL Challenge: Random Grouping Of Data
After Omnibuzz's challenge this morning I decided to come up with a challenge of my own
Let's say you have a table with data (what else would be in the table bananas? )The data looks like this
sony 4
sony 6
toshiba 1
toshiba 3
mitsubishi 2
mitsubishi 5
You want to return the results grouped together by company name but in random order
So for example the first resultset is
sony 4
sony 6
toshiba 1
toshiba 3
mitsubishi 2
mitsubishi 5
you highlight the query hit F5 and the next result is
toshiba 1
toshiba 3
sony 4
sony 6
mitsubishi 2
mitsubishi 5
See where I am going? The resultset is random but the company names are grouped together
Here is the deal no CTE or windowing functions (RANK, DENSE_RANK, ROWNUMBER or NTILE) you know what forget about SQL Server 2005, this has to be able to run on SQL Server 2000
Also no temp tables or table variables (added after first response ;-) )
I have 2 solutions to this, I will post the solutions some time tomorrow
Below is DDL + Insert script
Enjoy
CREATE TABLE #Testcompanies (
Name VARCHAR(50),
ID INT)
INSERT INTO #Testcompanies
SELECT 'toshiba' ,1
UNION ALL
SELECT 'mitsubishi', 2
UNION ALL
SELECT 'toshiba', 3
UNION ALL
SELECT 'sony', 4
UNION ALL
SELECT 'mitsubishi', 5
UNION ALL
SELECT 'sony', 6
Here are the 2 solutions I had in mind
--Query using a sub query and NEWID()
SELECT T.*
FROM #Testcompanies T
JOIN (SELECT DISTINCT TOP 100 PERCENT Name,
NEWID() AS GroupedOrder
FROM #Testcompanies
GROUP BY Name
ORDER BY NEWID()) Z
ON T.Name = Z.Name
ORDER BY Z.GroupedOrder
--Query using RAND()
DECLARE @R FLOAT
SET @R = RAND()
SELECT TOP 100 PERCENT *
FROM #TESTCOMPANIES
ORDER BY RAND(@R * CHECKSUM(NAME))
Does anyone else have a different solution than these two or the two in the comments?
Let's say you have a table with data (what else would be in the table bananas? )The data looks like this
sony 4
sony 6
toshiba 1
toshiba 3
mitsubishi 2
mitsubishi 5
You want to return the results grouped together by company name but in random order
So for example the first resultset is
sony 4
sony 6
toshiba 1
toshiba 3
mitsubishi 2
mitsubishi 5
you highlight the query hit F5 and the next result is
toshiba 1
toshiba 3
sony 4
sony 6
mitsubishi 2
mitsubishi 5
See where I am going? The resultset is random but the company names are grouped together
Here is the deal no CTE or windowing functions (RANK, DENSE_RANK, ROWNUMBER or NTILE) you know what forget about SQL Server 2005, this has to be able to run on SQL Server 2000
Also no temp tables or table variables (added after first response ;-) )
I have 2 solutions to this, I will post the solutions some time tomorrow
Below is DDL + Insert script
Enjoy
CREATE TABLE #Testcompanies (
Name VARCHAR(50),
ID INT)
INSERT INTO #Testcompanies
SELECT 'toshiba' ,1
UNION ALL
SELECT 'mitsubishi', 2
UNION ALL
SELECT 'toshiba', 3
UNION ALL
SELECT 'sony', 4
UNION ALL
SELECT 'mitsubishi', 5
UNION ALL
SELECT 'sony', 6
Here are the 2 solutions I had in mind
--Query using a sub query and NEWID()
SELECT T.*
FROM #Testcompanies T
JOIN (SELECT DISTINCT TOP 100 PERCENT Name,
NEWID() AS GroupedOrder
FROM #Testcompanies
GROUP BY Name
ORDER BY NEWID()) Z
ON T.Name = Z.Name
ORDER BY Z.GroupedOrder
--Query using RAND()
DECLARE @R FLOAT
SET @R = RAND()
SELECT TOP 100 PERCENT *
FROM #TESTCOMPANIES
ORDER BY RAND(@R * CHECKSUM(NAME))
Does anyone else have a different solution than these two or the two in the comments?
Answer To A SQL Challenge By Omnibuzz (SQL Garbage Collector)
Omnibuzz has posted the following challenge: A scenario to ponder #1
This challenge is about returning a random number of customers and returnig them in random order, here is what he said:
Say you have a table:
Customers (CustomerID int primary key, CustomerName varchar(50))
A pretty simple table structure. And it has 1000 rows.
Now, I am conducting a contest for the customers where I will randomly pick up 5 to 20 customers every week and give away prizes.
How will I go about doing it?
I need to create a stored procedure/query/function that will accept no parameters but will return random list of customers and random number of customers (between 5 and 20)
And here is my solution
CREATE PROCEDURE ReturnRandomCustomers
AS
SET NOCOUNT ON
DECLARE @value INT
SELECT @value = CAST(5 + (RAND() * (20 - 5 + 1)) AS INT)
SELECT TOP @value *
FROM Customers
ORDER BY NEWID()
SET NOCOUNT OFF
GO
Since we are using SQL Server 2005 we can use TOP with a variable, and to set that variable we us the RAND function
The SQL Server 2000 version would look like this
CREATE PROCEDURE ReturnRandomCustomers
AS
SET NOCOUNT ON
DECLARE @value INT
SELECT @value = CAST(5 + (RAND() * (20 - 5 + 1)) AS INT)
SET ROWCOUNT @value
SELECT *
FROM Customers
ORDER BY NEWID()
SET ROWCOUNT 0
SET NOCOUNT OFF
GO
This challenge is about returning a random number of customers and returnig them in random order, here is what he said:
Say you have a table:
Customers (CustomerID int primary key, CustomerName varchar(50))
A pretty simple table structure. And it has 1000 rows.
Now, I am conducting a contest for the customers where I will randomly pick up 5 to 20 customers every week and give away prizes.
How will I go about doing it?
I need to create a stored procedure/query/function that will accept no parameters but will return random list of customers and random number of customers (between 5 and 20)
And here is my solution
CREATE PROCEDURE ReturnRandomCustomers
AS
SET NOCOUNT ON
DECLARE @value INT
SELECT @value = CAST(5 + (RAND() * (20 - 5 + 1)) AS INT)
SELECT TOP @value *
FROM Customers
ORDER BY NEWID()
SET NOCOUNT OFF
GO
Since we are using SQL Server 2005 we can use TOP with a variable, and to set that variable we us the RAND function
The SQL Server 2000 version would look like this
CREATE PROCEDURE ReturnRandomCustomers
AS
SET NOCOUNT ON
DECLARE @value INT
SELECT @value = CAST(5 + (RAND() * (20 - 5 + 1)) AS INT)
SET ROWCOUNT @value
SELECT *
FROM Customers
ORDER BY NEWID()
SET ROWCOUNT 0
SET NOCOUNT OFF
GO
Wednesday, October 04, 2006
Red Gate's SQL Refactor Public CTP Released
That great company Red Gate has released a public CTP of their latest tool SQL Refactor. Thanks to Louis Davidson for sharing this info, you can get all the details including a download link on his blog right here: http://drsql.spaces.live.com/blog/cns!80677FB08B3162E4!1422.entry
Download it, play with it and let me know what you think
Download it, play with it and let me know what you think
Tuesday, October 03, 2006
Three Team Edition for Database Professionals Screencasts On Channel 9
Channel 9 has three screencast about Team Edition for Database Professionals
Team Edition for DB Pros 5 min Demo
"I'd like to introduce you to the latest edition of Visual Studio Team System - Team Edition for Database Professionals.
Check out this quick 5 minute demo to get a whirlwind tour of exactly what Team Data can do for you."
Creating a database project with Team Edition for Database Professionals
"I'd like to introduce you to how to create your database project using the latest edition of Visual Studio Team System - Team Edition for Database Professionals.
Check out this quick 10 minute demo to get a whirlwind tour of project creation within VSTE for DB Pro."
Configuring Design DB for Team Edition for Database Professionals
"This video will describe how to install and configure SQL Server 2005 to support Visual Studio Team Edition for Database Professionals database projects.
Richard Waymire is the Program Management Architect for Visual Studio Team System for Database Professionals. He’s been with Microsoft for more than 8 years, having been in the SQL Server team for most of that time. He’s the author of several books on SQL Server, a contributing editor to SQL Server Magazine, and a frequent speaker at SQL Server events."
Enjoy them.
Team Edition for DB Pros 5 min Demo
"I'd like to introduce you to the latest edition of Visual Studio Team System - Team Edition for Database Professionals.
Check out this quick 5 minute demo to get a whirlwind tour of exactly what Team Data can do for you."
Creating a database project with Team Edition for Database Professionals
"I'd like to introduce you to how to create your database project using the latest edition of Visual Studio Team System - Team Edition for Database Professionals.
Check out this quick 10 minute demo to get a whirlwind tour of project creation within VSTE for DB Pro."
Configuring Design DB for Team Edition for Database Professionals
"This video will describe how to install and configure SQL Server 2005 to support Visual Studio Team Edition for Database Professionals database projects.
Richard Waymire is the Program Management Architect for Visual Studio Team System for Database Professionals. He’s been with Microsoft for more than 8 years, having been in the SQL Server team for most of that time. He’s the author of several books on SQL Server, a contributing editor to SQL Server Magazine, and a frequent speaker at SQL Server events."
Enjoy them.
Monday, October 02, 2006
SQL Server Teaser
Here is a quick SQL Server teaser
Create the following table
CREATE TABLE [barney ]
(
barneyId INT
)
Then look at the following 4 statements which one will fail?
Do not run the statements try to guess, Is it A, B, C or D (or more than one?)
--A
INSERT [barney ] VALUES (1)
--B
INSERT barney VALUES (1)
--C
INSERT "barney" VALUES (1)
--D
INSERT [barney] VALUES (1)
BTW the idea for this post came after reading "Another reason to hate quoted identifiers..." on Louis Davidson's blog
Create the following table
CREATE TABLE [barney ]
(
barneyId INT
)
Then look at the following 4 statements which one will fail?
Do not run the statements try to guess, Is it A, B, C or D (or more than one?)
--A
INSERT [barney ] VALUES (1)
--B
INSERT barney VALUES (1)
--C
INSERT "barney" VALUES (1)
--D
INSERT [barney] VALUES (1)
BTW the idea for this post came after reading "Another reason to hate quoted identifiers..." on Louis Davidson's blog
Top 5 Posts For September 2006
Below are the top 5 posts according to Google Analytics for the month of September 2006 in order by pageviews descending
Login failed for user 'sa'. Reason: Not associated with a trusted SQL Server connection. SQL 2005
COALESCE And ISNULL Differences
Top 10 Articles of all time
OPENROWSET And Excel Problems
Store The Output Of A Stored Procedure In A Table Without Creating A Table
Login failed for user 'sa'. Reason: Not associated with a trusted SQL Server connection. SQL 2005
COALESCE And ISNULL Differences
Top 10 Articles of all time
OPENROWSET And Excel Problems
Store The Output Of A Stored Procedure In A Table Without Creating A Table
Top SQL Server Google Searches For September 2006
These are the top SQL Searches on this site for the month of September I have left out searches that have nothing to do with SQL Server or programming (for example atlantic city escorts)
calculating application availability
pl/sql code to calculate application availability
vb .net Datagrid column naming
does not have the identity property
application availability report and pl/sql
autoincrement
datetime string
sqldatareader stored proc clr
OUTER JOIN
OUTER JOIN SQL 2000 example
I always find it interesting to see what people are searching for and it also gives me ideas for things to write about
calculating application availability
pl/sql code to calculate application availability
vb .net Datagrid column naming
does not have the identity property
application availability report and pl/sql
autoincrement
datetime string
sqldatareader stored proc clr
OUTER JOIN
OUTER JOIN SQL 2000 example
I always find it interesting to see what people are searching for and it also gives me ideas for things to write about
Sunday, October 01, 2006
iWoz: From Computer Geek to Cult Icon: How I Invented the Personal Computer, Co-Founded Apple, and Had Fun Doing It
How I wish I had more time and needed less sleep (less than the 4-5 hours I am getting now) I am very excited about this book and will for sure put it on my Christmas list
Book Description
The mastermind behind Apple sheds his low profile and steps forward to tell his story for the first time.
Before cell phones that fit in the palm of your hand and slim laptops that fit snugly into briefcases, computers were like strange, alien vending machines. They had cryptic switches, punch cards and pages of encoded output. But in 1975, a young engineering wizard named Steve Wozniak had an idea: What if you combined computer circuitry with a regular typewriter keyboard and a video screen? The result was the first true personal computer, the Apple I, a widely affordable machine that anyone could understand and figure out how to use.
Wozniak's life—before and after Apple—is a "home-brew" mix of brilliant discovery and adventure, as an engineer, a concert promoter, a fifth-grade teacher, a philanthropist, and an irrepressible prankster. From the invention of the first personal computer to the rise of Apple as an industry giant, iWoz presents a no-holds-barred, rollicking, firsthand account of the humanist inventor who ignited the computer revolution. 16 pages of illustrations.
Amazon link is here for those interested
Book Description
The mastermind behind Apple sheds his low profile and steps forward to tell his story for the first time.
Before cell phones that fit in the palm of your hand and slim laptops that fit snugly into briefcases, computers were like strange, alien vending machines. They had cryptic switches, punch cards and pages of encoded output. But in 1975, a young engineering wizard named Steve Wozniak had an idea: What if you combined computer circuitry with a regular typewriter keyboard and a video screen? The result was the first true personal computer, the Apple I, a widely affordable machine that anyone could understand and figure out how to use.
Wozniak's life—before and after Apple—is a "home-brew" mix of brilliant discovery and adventure, as an engineer, a concert promoter, a fifth-grade teacher, a philanthropist, and an irrepressible prankster. From the invention of the first personal computer to the rise of Apple as an industry giant, iWoz presents a no-holds-barred, rollicking, firsthand account of the humanist inventor who ignited the computer revolution. 16 pages of illustrations.
Amazon link is here for those interested
Return All 78498 Prime Numbers Between 1 and 1000000 Continues in the Land Down Under
So this Prime Number challenge won't die, the other day I wrote about it in THIS post. Rob Farley from Down Under let me a comment with two approaches he took, I decided to link to them from a seperate post. His first attempt is primes and his second attempt is More On Primes. His approach is interesting since he doesn't delete from the table but actually inserts into the table. Make sure you check it out
Friday, September 29, 2006
Trouble With ISDATE And Converting To SMALLDATETIME
If you want to use the ISDATE function to convert a value to a SMALLDATETIME you also have to take into consideration that SMALLDATETIME stores date and time data from January 1, 1900, through June 6, 2079 but DATETIME stores date and time data from January 1, 1753 through December 31, 9999
So even though the ISDATE function returns 1 for the date 1890-01-01 this can not be converted to SMALLDATETIME and you will receive an error message after you run the following statement
SELECT CONVERT(SMALLDATETIME,'18900101')
Server: Msg 296, Level 16, State 3, Line 1
The conversion of char data type to smalldatetime data type resulted in an out-of-range smalldatetime value.
Also be careful with rounding
Run these four statements
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29.998')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29.999')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:30')
The first two are fine , the second two blow up because the value gets rounded up to the next day after it gets rounded up to the next minute (and hour)
I decided to roll out my own fnIsSmallDateTime() function because who wants to write the same CASE ISDATE when Value between this and that code all over the place?
Here is the code for the user defined function
CREATE FUNCTION fnIsSmallDateTime(@d VARCHAR(50))
RETURNS BIT
AS
BEGIN
DECLARE @bitReturnValue BIT
SELECT @bitReturnValue =CASE
WHEN ISDATE(@d) = 1 THEN CASE
WHEN CONVERT(DATETIME,@d) > ='19000101'
AND CONVERT(DATETIME,@d) <= '20790606 23:59:29.998' THEN 1
ELSE 0
END
ELSE 0
END
RETURN @bitReturnValue
END
GO
Let's create a test table with values
CREATE TABLE TestSmallDate (SomeDate VARCHAR(40))
INSERT TestSmallDate VALUES ('19000101')
INSERT TestSmallDate VALUES ('18991231')
INSERT TestSmallDate VALUES ('19010101')
INSERT TestSmallDate VALUES('20790607')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.677')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.998')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.999')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:59.000')
INSERT TestSmallDate VALUES('2079-06-06 01:00:00')
INSERT TestSmallDate VALUES ('2079-06-06 00:00:00')
INSERT TestSmallDate VALUES ('2079-06-06 00:00:01')
INSERT TestSmallDate VALUES('WhoIsYourDaddy')
If you want NULL for values that can not be converted to SMALLDATETIME use this code
SELECT dbo.fnIsSmallDateTime(SomeDate),
CASE dbo.fnIsSmallDateTime(SomeDate)
WHEN 1 THEN CONVERT(SMALLDATETIME,SomeDate) END AS ConvertedToSmallDate,
SomeDate
FROM TestSmallDate
if you want to convert the values that can not be converted to SMALLDATETIME to '1901-01-01 00:00:00' use the code below
SELECT dbo.fnIsSmallDateTime(SomeDate),
CASE dbo.fnIsSmallDateTime(SomeDate)
WHEN 1 THEN CONVERT(SMALLDATETIME,SomeDate)
ELSE CONVERT(SMALLDATETIME,'19000101') END AS ConvertedToSmallDate,
SomeDate
FROM TestSmallDate
Return only data that can be converted to SMALLDATETIME
SELECT * FROM TestSmallDate
WHERE dbo.fnIsSmallDateTime(SomeDate) =1
Return only data that can not converted to SMALLDATETIME
SELECT * FROM TestSmallDate
WHERE dbo.fnIsSmallDateTime(SomeDate) =0
So even though the ISDATE function returns 1 for the date 1890-01-01 this can not be converted to SMALLDATETIME and you will receive an error message after you run the following statement
SELECT CONVERT(SMALLDATETIME,'18900101')
Server: Msg 296, Level 16, State 3, Line 1
The conversion of char data type to smalldatetime data type resulted in an out-of-range smalldatetime value.
Also be careful with rounding
Run these four statements
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29.998')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:29.999')
SELECT CONVERT(SMALLDATETIME,'2079-06-06 23:59:30')
The first two are fine , the second two blow up because the value gets rounded up to the next day after it gets rounded up to the next minute (and hour)
I decided to roll out my own fnIsSmallDateTime() function because who wants to write the same CASE ISDATE when Value between this and that code all over the place?
Here is the code for the user defined function
CREATE FUNCTION fnIsSmallDateTime(@d VARCHAR(50))
RETURNS BIT
AS
BEGIN
DECLARE @bitReturnValue BIT
SELECT @bitReturnValue =CASE
WHEN ISDATE(@d) = 1 THEN CASE
WHEN CONVERT(DATETIME,@d) > ='19000101'
AND CONVERT(DATETIME,@d) <= '20790606 23:59:29.998' THEN 1
ELSE 0
END
ELSE 0
END
RETURN @bitReturnValue
END
GO
Let's create a test table with values
CREATE TABLE TestSmallDate (SomeDate VARCHAR(40))
INSERT TestSmallDate VALUES ('19000101')
INSERT TestSmallDate VALUES ('18991231')
INSERT TestSmallDate VALUES ('19010101')
INSERT TestSmallDate VALUES('20790607')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.677')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.998')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:29.999')
INSERT TestSmallDate VALUES ('2079-06-06 23:59:59.000')
INSERT TestSmallDate VALUES('2079-06-06 01:00:00')
INSERT TestSmallDate VALUES ('2079-06-06 00:00:00')
INSERT TestSmallDate VALUES ('2079-06-06 00:00:01')
INSERT TestSmallDate VALUES('WhoIsYourDaddy')
If you want NULL for values that can not be converted to SMALLDATETIME use this code
SELECT dbo.fnIsSmallDateTime(SomeDate),
CASE dbo.fnIsSmallDateTime(SomeDate)
WHEN 1 THEN CONVERT(SMALLDATETIME,SomeDate) END AS ConvertedToSmallDate,
SomeDate
FROM TestSmallDate
if you want to convert the values that can not be converted to SMALLDATETIME to '1901-01-01 00:00:00' use the code below
SELECT dbo.fnIsSmallDateTime(SomeDate),
CASE dbo.fnIsSmallDateTime(SomeDate)
WHEN 1 THEN CONVERT(SMALLDATETIME,SomeDate)
ELSE CONVERT(SMALLDATETIME,'19000101') END AS ConvertedToSmallDate,
SomeDate
FROM TestSmallDate
Return only data that can be converted to SMALLDATETIME
SELECT * FROM TestSmallDate
WHERE dbo.fnIsSmallDateTime(SomeDate) =1
Return only data that can not converted to SMALLDATETIME
SELECT * FROM TestSmallDate
WHERE dbo.fnIsSmallDateTime(SomeDate) =0
SQL Server Application Platform Podcast About SQL Server Service Broker On Channel 9
Channel 9 has a two part podcast with Roger Wolter about SQL Server Service Broker. WMA, MP3 and Video formats are available for download
From the site: "You are thinking of a messaging solution for your application. A solution that can exchange messages reliably, predictably and in-order. A solution that offers queue like functionality only better. What is it you ask? None other than SQL Server 2005 and this very interesting technology known as SQL Service Broker that is built right into it. On today’s program I’m joined by my colleague Roger Wolter who is going to give us all the juicy details"
Get the episodes here --> part1, part2
From the site: "You are thinking of a messaging solution for your application. A solution that can exchange messages reliably, predictably and in-order. A solution that offers queue like functionality only better. What is it you ask? None other than SQL Server 2005 and this very interesting technology known as SQL Service Broker that is built right into it. On today’s program I’m joined by my colleague Roger Wolter who is going to give us all the juicy details"
Get the episodes here --> part1, part2
Wednesday, September 27, 2006
Cool And Sexy New SQL Server Blog
That's right! What is more cool or sexy than Query Optimizations? It doesn't matter how beautiful or complex your data model is, if you show to your boss that a query used to take 17 seconds and now runs in 300 milli-seconds then you are the new SQL superhero.
If some of the following terms are foreign to you (CTRL + K, Index Scan, Index Seek, Table Scan, Sargable, Index Hint, Parameter Sniffing, Missing Statistics, L2 Cache, Compilation, Optimal Plans) then I have the blog for you right here
Tips, Tricks, and Advice from the SQL Server Query Processing Team
Even if you do know about those terms then this is still the blog for you since there is tons of stuff that you did not know yet. so make sure to check it out and add it to your feed
If some of the following terms are foreign to you (CTRL + K, Index Scan, Index Seek, Table Scan, Sargable, Index Hint, Parameter Sniffing, Missing Statistics, L2 Cache, Compilation, Optimal Plans) then I have the blog for you right here
Tips, Tricks, and Advice from the SQL Server Query Processing Team
Even if you do know about those terms then this is still the blog for you since there is tons of stuff that you did not know yet. so make sure to check it out and add it to your feed
Tuesday, September 26, 2006
Return A Rowcount By Using Count Or Sign
Sometimes you are asked by the front-end/middle-tier developers to return a rowcount as well with the result set. However the developers want you to return 1 if there are rows and 0 if there are none. How do you do such a thing?
Well I am going to show you two ways. the first way is by using CASE and @@ROWCOUNT, the second way is by using the SIGN function
For CASE we will do this
RETURN CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END
So that's pretty simple, if @@ROWCOUNT is greater than 0 return 1 for everything else return 0
Using the SIGN function is even easier, all you have to do is this
RETURN SIGN(@@ROWCOUNT)
That's all, SIGN Returns the positive (+1), zero (0), or negative (-1) sign of the given expression. In this case -1 is not possible but the other two values are
So let's see this in action
USE pubs
GO
--Case Proc
CREATE PROCEDURE TestReturnValues
@au_id VARCHAR(49) ='172-32-1176'
AS
SELECT *
FROM authors
WHERE au_id =@au_id
RETURN CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END
GO
--Sign Proc
CREATE PROCEDURE TestReturnValues2
@au_id VARCHAR(49) ='172-32-1176'
AS
SELECT *
FROM authors
WHERE au_id =@au_id
RETURN SIGN(@@ROWCOUNT)
GO
--Case Proc, 1 will be returned; default value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues
SELECT @Rowcount
GO
--Case Proc, 0 will be returned; dummy value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues 'ABC'
SELECT @Rowcount
GO
--Sign Proc, 1 will be returned; default value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues2
SELECT @Rowcount
GO
--Sign Proc, 0 will be returned; dummy value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues2 'ABC'
SELECT @Rowcount
GO
--Help the environment by recycling ;-)
DROP PROCEDURE TestReturnValues2,TestReturnValues
GO
Well I am going to show you two ways. the first way is by using CASE and @@ROWCOUNT, the second way is by using the SIGN function
For CASE we will do this
RETURN CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END
So that's pretty simple, if @@ROWCOUNT is greater than 0 return 1 for everything else return 0
Using the SIGN function is even easier, all you have to do is this
RETURN SIGN(@@ROWCOUNT)
That's all, SIGN Returns the positive (+1), zero (0), or negative (-1) sign of the given expression. In this case -1 is not possible but the other two values are
So let's see this in action
USE pubs
GO
--Case Proc
CREATE PROCEDURE TestReturnValues
@au_id VARCHAR(49) ='172-32-1176'
AS
SELECT *
FROM authors
WHERE au_id =@au_id
RETURN CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END
GO
--Sign Proc
CREATE PROCEDURE TestReturnValues2
@au_id VARCHAR(49) ='172-32-1176'
AS
SELECT *
FROM authors
WHERE au_id =@au_id
RETURN SIGN(@@ROWCOUNT)
GO
--Case Proc, 1 will be returned; default value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues
SELECT @Rowcount
GO
--Case Proc, 0 will be returned; dummy value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues 'ABC'
SELECT @Rowcount
GO
--Sign Proc, 1 will be returned; default value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues2
SELECT @Rowcount
GO
--Sign Proc, 0 will be returned; dummy value is used
DECLARE @Rowcount int
EXEC @Rowcount = TestReturnValues2 'ABC'
SELECT @Rowcount
GO
--Help the environment by recycling ;-)
DROP PROCEDURE TestReturnValues2,TestReturnValues
GO
Monday, September 25, 2006
Happy One Year Anniversary
So here we are one year and 236 posts later. I can not believe that it has been one year already. First of all I will make 2 small changes. The first change is that I will feature a blog/site of the week; this will always happen on a Friday. I will link to the blog and link to the 5 most interesting posts/articles. If possible I will say a little something about the person whose site it is, something like author of this book and an interview is available here.
The second change is that I will write some stuff that has nothing to do with SQL Server but might still be of interest to you. This I will publish on weekends so that you can skip that easily if you check on weekdays only. What will I write? Maybe something that goes on in my life or a book or movie review. However I will not review the Matrix, Titanic or some other well know movie. No I will pick something that is not as popular for example Ghost In The Machine, The Seven Samurai, Animatrix. For books this could be Crypto, The Cobra Event or The Coming Plague
Or I could write that once you have kids and you do NOT have TIVO then Comcast On Demand really rocks. For example Jericho is a show that I just started to watch, this show reminded me a little bit of The Stand by Stephen King (his best book together with Thinner, It and Salems Lot)
So what is so cool about On Demand? No commercials, that’s right; nada. Pause and Resume for up to 24 hours, this is a must have with newborns.
Comcast announced a deal with CBS to have the following shows free the day after it airs: CSI: Crime Scene Investigation, CSI: Miami, CSI: NY, Survivor, NCIS, Numb3rs, Jericho and Big Brother
That’s it for now
The second change is that I will write some stuff that has nothing to do with SQL Server but might still be of interest to you. This I will publish on weekends so that you can skip that easily if you check on weekdays only. What will I write? Maybe something that goes on in my life or a book or movie review. However I will not review the Matrix, Titanic or some other well know movie. No I will pick something that is not as popular for example Ghost In The Machine, The Seven Samurai, Animatrix. For books this could be Crypto, The Cobra Event or The Coming Plague
Or I could write that once you have kids and you do NOT have TIVO then Comcast On Demand really rocks. For example Jericho is a show that I just started to watch, this show reminded me a little bit of The Stand by Stephen King (his best book together with Thinner, It and Salems Lot)
So what is so cool about On Demand? No commercials, that’s right; nada. Pause and Resume for up to 24 hours, this is a must have with newborns.
Comcast announced a deal with CBS to have the following shows free the day after it airs: CSI: Crime Scene Investigation, CSI: Miami, CSI: NY, Survivor, NCIS, Numb3rs, Jericho and Big Brother
That’s it for now
Return All 78498 Prime Numbers Between 1 and 1000000 In 3 seconds
That is right folks; SQL Server is capable of returning all 78498 prime numbers between 1 and 1000000 in 3 seconds. Who said that SQL Server isn't suitable for this task?
Let's start with a little bit of history; Ward Pond had a posting on his blog on how to create a table with 1000000 rows. Hugo Kornelis replied with a solution that ran in 1110 ms. For fun I left the following comment: “How about the next challenge is to return all 78498 prime numbers between 1 and 1000000?”
Ward took the challenge and posted a solution that would take hours to complete. Then Hugo Kornelis posted a solution that took 8 seconds. After that Ward tweaked Hugo’s solution and got it down to 3 seconds. That is just unbelievable. I wonder how long it would run if you were to code something like that in C, C++, C# or your favorite language?
Any takers?
Let's start with a little bit of history; Ward Pond had a posting on his blog on how to create a table with 1000000 rows. Hugo Kornelis replied with a solution that ran in 1110 ms. For fun I left the following comment: “How about the next challenge is to return all 78498 prime numbers between 1 and 1000000?”
Ward took the challenge and posted a solution that would take hours to complete. Then Hugo Kornelis posted a solution that took 8 seconds. After that Ward tweaked Hugo’s solution and got it down to 3 seconds. That is just unbelievable. I wonder how long it would run if you were to code something like that in C, C++, C# or your favorite language?
Any takers?
Wednesday, September 20, 2006
Five Ways To Return Values From Stored Procedures
I have answered a bunch of questions over the last couple of days and some of them had to do with returning values from stored procedures
Everyone knows that you can return a value by using return inside a stored procedure. What everyone doesn't know is that return can only be an int data type
So how do you return something that is not an int (bigint, smallint etc etc) datatype
Let's take a look
We will start with a regular return statement, everything works as expected
--#1 return
CREATE PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i int
SELECT @i = DATEPART(hh,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue int
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Now let's try returning a varchar
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i VARCHAR(50)
SELECT @i = DATENAME(mm,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Oops, it doesn't work the following message is returned (if you run it in September)
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'September' to a column of data type int.
Let's try hard coding a character value
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
RETURN 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
It is interesting that the procedure compiles without a problem. But when we try to run it the following message is displayed
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'ab' to a column of data type int.
So what can we do? well we can use an OUTPUT parameter. By the way the following 4 ways to return a varchar values are in the order from best to worst
--#2 OUTPUT
ALTER PROCEDURE TestReturn @SomeParm VARCHAR(50) OUTPUT
AS
SET NOCOUNT ON
SELECT @SomeParm = 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC TestReturn @SomeParm = @SomeValue OUTPUT
SELECT @SomeValue
GO
Another way is to create a temp table and call the proc with insert..exec
--#3 Insert Into TEMP Table outside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
INSERT INTO #Test
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
GO
This one is almost the same as the previous example, the only difference is that ther insert happens inside the proc
And of course if you call the proc without creating the table you will get a nice error message
--#4 Insert Into TEMP Table inside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
INSERT INTO #Test
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
And last you create a permanent table with an identity, in the proc you insert into that table and you return the identity value. You can then use that identity value to get the varchar value
--#5 Insert Into A Table And Return The Identity value
CREATE TABLE HoldingTable(ID INT IDENTITY,SomeValue VARCHAR(50))
GO
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i INT
INSERT INTO HoldingTable
SELECT 'ab'
SELECT @I = SCOPE_IDENTITY()
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50), @i INT
EXEC @i = TestReturn
SELECT @SomeValue = SomeValue
FROM HoldingTable
WHERE ID = @i
SELECT @SomeValue
DROP PROCEDURE TestReturn
Everyone knows that you can return a value by using return inside a stored procedure. What everyone doesn't know is that return can only be an int data type
So how do you return something that is not an int (bigint, smallint etc etc) datatype
Let's take a look
We will start with a regular return statement, everything works as expected
--#1 return
CREATE PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i int
SELECT @i = DATEPART(hh,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue int
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Now let's try returning a varchar
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i VARCHAR(50)
SELECT @i = DATENAME(mm,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Oops, it doesn't work the following message is returned (if you run it in September)
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'September' to a column of data type int.
Let's try hard coding a character value
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
RETURN 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
It is interesting that the procedure compiles without a problem. But when we try to run it the following message is displayed
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'ab' to a column of data type int.
So what can we do? well we can use an OUTPUT parameter. By the way the following 4 ways to return a varchar values are in the order from best to worst
--#2 OUTPUT
ALTER PROCEDURE TestReturn @SomeParm VARCHAR(50) OUTPUT
AS
SET NOCOUNT ON
SELECT @SomeParm = 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC TestReturn @SomeParm = @SomeValue OUTPUT
SELECT @SomeValue
GO
Another way is to create a temp table and call the proc with insert..exec
--#3 Insert Into TEMP Table outside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
INSERT INTO #Test
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
GO
This one is almost the same as the previous example, the only difference is that ther insert happens inside the proc
And of course if you call the proc without creating the table you will get a nice error message
--#4 Insert Into TEMP Table inside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
INSERT INTO #Test
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
And last you create a permanent table with an identity, in the proc you insert into that table and you return the identity value. You can then use that identity value to get the varchar value
--#5 Insert Into A Table And Return The Identity value
CREATE TABLE HoldingTable(ID INT IDENTITY,SomeValue VARCHAR(50))
GO
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i INT
INSERT INTO HoldingTable
SELECT 'ab'
SELECT @I = SCOPE_IDENTITY()
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50), @i INT
EXEC @i = TestReturn
SELECT @SomeValue = SomeValue
FROM HoldingTable
WHERE ID = @i
SELECT @SomeValue
DROP PROCEDURE TestReturn
Tuesday, September 19, 2006
You Can Rollback Tables That You Have Truncated (Inside A Transaction)
There seems to be a misconception that when you issue a TRUNCATE command against a table you will not be able to roll back.
That simply is not true; TRUNCATE TABLE removes the data by deallocating the data pages used to store the table's data, and only the page deallocations are recorded in the transaction log.
What does this mean? This means that SQL Server will use the mimimum amount of logging that it can to delete the data and still make it recoverable. in contrast to that the DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row
You see why TRUNCATE is so much faster; it deals with pages not with rows. and we all know that 1 extent is 8 pages and a page is 8K and can hold 8060 bytes. Well if you rows are 20 bytes wide then you need to log 403 delete statements with DELETE but TRUNCATE just uses a pointer to the page
So let's see how that works
--Create the table and inser 6 values
CREATE TABLE RollBacktest(id INT)
INSERT RollBacktest VALUES( 1 )
INSERT RollBacktest VALUES( 2 )
INSERT RollBacktest VALUES( 3 )
INSERT RollBacktest VALUES( 4 )
INSERT RollBacktest VALUES( 5 )
INSERT RollBacktest VALUES( 6 )
GO
--Should be 6 rows
SELECT 'Before The Transaction',* FROM RollBacktest
BEGIN TRAN RollBackTestTran
TRUNCATE TABLE RollBacktest
--Should be empty resultset
SELECT * FROM RollBacktest
--should be 0
SELECT COUNT(*) AS 'TruncatedCount' FROM RollBacktest
ROLLBACK TRAN RollBackTestTran
--Yes it is 6 again
SELECT 'ROLLED BACK',* FROM RollBacktest
DROP TABLE RollBacktest
That simply is not true; TRUNCATE TABLE removes the data by deallocating the data pages used to store the table's data, and only the page deallocations are recorded in the transaction log.
What does this mean? This means that SQL Server will use the mimimum amount of logging that it can to delete the data and still make it recoverable. in contrast to that the DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row
You see why TRUNCATE is so much faster; it deals with pages not with rows. and we all know that 1 extent is 8 pages and a page is 8K and can hold 8060 bytes. Well if you rows are 20 bytes wide then you need to log 403 delete statements with DELETE but TRUNCATE just uses a pointer to the page
So let's see how that works
--Create the table and inser 6 values
CREATE TABLE RollBacktest(id INT)
INSERT RollBacktest VALUES( 1 )
INSERT RollBacktest VALUES( 2 )
INSERT RollBacktest VALUES( 3 )
INSERT RollBacktest VALUES( 4 )
INSERT RollBacktest VALUES( 5 )
INSERT RollBacktest VALUES( 6 )
GO
--Should be 6 rows
SELECT 'Before The Transaction',* FROM RollBacktest
BEGIN TRAN RollBackTestTran
TRUNCATE TABLE RollBacktest
--Should be empty resultset
SELECT * FROM RollBacktest
--should be 0
SELECT COUNT(*) AS 'TruncatedCount' FROM RollBacktest
ROLLBACK TRAN RollBackTestTran
--Yes it is 6 again
SELECT 'ROLLED BACK',* FROM RollBacktest
DROP TABLE RollBacktest
Subscribe to:
Posts (Atom)