Showing posts with label SQL Server 2005. Show all posts
Showing posts with label SQL Server 2005. Show all posts

Tuesday, September 11, 2007

Cumulative update package 3 for SQL Server 2005 Service Pack 2 is available

Cumulative update package 3 for SQL Server 2005 Service Pack 2 is available.

How to obtain Cumulative Update 3 for SQL Server 2005 Service Pack 2
A supported cumulative update package is now available from Microsoft. However, it is intended to correct only the problems that are described in this article. Apply it only to systems that are experiencing these specific problems. This cumulative update package may receive additional testing. Therefore, if you are not severely affected by any of these problems, we recommend that you wait for the next SQL Server 2005 service pack that contains the hotfixes in this cumulative update package.

To resolve this problem, submit a request to Microsoft Online Customer Services to obtain the cumulative update package. To submit an online request to obtain the cumulative update package, visit the following Microsoft Web site:
http://go.microsoft.com/?linkid=6294451

Here is what is fixed:
50001581
938243 (http://support.microsoft.com/kb/938243/)
FIX: Error message when you run a full-text query against a catalog in SQL Server 2005: “The execution of a full-text query failed. The content index is corrupt."

50001585
938712 (http://support.microsoft.com/kb/938712/)
FIX: Some records in the fact table may not be processed when you process a dimension that contains many attributes or many members in SQL Server 2005


50001499
938962 (http://support.microsoft.com/kb/938962/)
FIX: You may receive an access violation or error 942 when you drop a database in SQL Server 2005


50001524
939563 (http://support.microsoft.com/kb/939563/)
FIX: Error message when you synchronize a merge replication in Microsoft SQL Server 2005: "MSmerge_del_, Line 42 String or binary data would be truncated"

50001582
939942 (http://support.microsoft.com/kb/939942/)
FIX: You receive an error message when you try to access a report after you configure SQL Server 2005 Reporting Services to run under the SharePoint integrated mode

50001583
940128 (http://support.microsoft.com/kb/940128/)
FIX: You receive error 8623 when you run a complex query in SQL Server 2005


50001586
940129 (http://support.microsoft.com/kb/940129/)
FIX: An MDX query does not return results when you execute the query against a cube that contains an unnatural hierarchy in a dimension in SQL Server 2005 Analysis Services


50001517
940160 (http://support.microsoft.com/kb/940160/)
FIX: Error message when you deploy a SQL Server 2005 Analysis Service project that contains many cubes, and the cubes contain linked measure groups: "Unexpected internal error"


50001449
940210 (http://support.microsoft.com/kb/940210/)
FIX: Error message when you try to insert more than 3 megabytes of data into a distributed partitioned view in SQL Server 2005: "A system assertion check has failed"


50001447
940220 (http://support.microsoft.com/kb/940220/)
FIX: Error message when you run a SQL Server 2005 Integration Services package that contains an FTP task: “An error occurred in the requested FTP operation"


50001448
940221 (http://support.microsoft.com/kb/940221/)
FIX: Error message when you try to create an Oracle publication by using the New Publication Wizard in Microsoft SQL Server 2005 Service Pack 2: “OLE DB Provider "OraOLEDB.ORACLE" for Linked server returned message "ORA-02074: Cannot RO


50001451
940223 (http://support.microsoft.com/kb/940223/)
FIX: Error message when you synchronize a subscription by using Windows Synchronization Manager in SQL Server 2005: “The merge process failed to get correct information about the Interactive Resolver component from the Registry"


50001416
940260 (http://support.microsoft.com/kb/940260/)
FIX: Error message when you use Service Broker in SQL Server 2005: "An error occurred while receiving data: '64(The specified network name is no longer available.)'"


50001435
940269 (http://support.microsoft.com/kb/940269/)
FIX: Error message when you try to edit a SQL Server Agent job or a maintenance plan by using SQL Server Management Studio in SQL Server 2005: "String or binary data would be truncated"


50001567
940281 (http://support.microsoft.com/kb/940281/)
FIX: An access violation may occur, and you may receive an error message, when you query the sys.dm_exe_sessions dynamic management view in SQL Server 2005


50001351
940370 (http://support.microsoft.com/kb/940370/)
FIX: The "User:" prefix is lost for the event information that is generated by a child package in SQL Server 2005 Integration Services after you install SQL Server 2005 Service Pack 2


50001382
940373 (http://support.microsoft.com/kb/940373/)
FIX: The performance of a Multidimensional Expressions query in SQL Server 2005 Analysis Services Service Pack 2 is much slower than the performance in earlier builds of SQL Server 2005 Analysis Services


50001433
940378 (http://support.microsoft.com/kb/940378/)
Fix: Unable to Change Transaction Isolation Level After Cursor Declaration


50001479
940384 (http://support.microsoft.com/kb/940384/)
FIX: You receive a System.InvalidCastException exception when you run an application that calls the Server.JobServer.Jobs.Contains method on a computer that has SQL Server 2005 Service Pack 2 installed


50001494
940386 (http://support.microsoft.com/kb/940386/)
FIX: You cannot install SQL Server 2005 Reporting Services Add-in for Microsoft SharePoint Technologies on a beta version of Windows Server 2008-based computer


50001602
940545 (http://support.microsoft.com/kb/940545/)
FIX: The performance of insert operations against a table that contains an identity column may be slow in SQL Server 2005


50001589
940935 (http://support.microsoft.com/kb/940935/)
FIX: Error message when you run a parallel query in SQL Server 2005 on a computer that has multiple processors: “SQL Server Assertion: File: , line=10850 Failed Assertion = 'GetLocalLockPartition () == xactLockInfo->GetLocalLockPartition ()'"


50001599
940937 (http://support.microsoft.com/kb/940937/)
FIX: Error message when you try to update the index key columns of a non-unique clustered index in SQL Server 2005: " Cannot insert duplicate key row in object 'ObjectName' with unique index 'IndexName'"


50001609
940939 (http://support.microsoft.com/kb/940939/)
FIX: Data is not rolled back after you roll back a transaction that contains a writeback operation in SQL Server 2005 Analysis Services


50001629
940942 (http://support.microsoft.com/kb/940942/)
FIX: Error message when you run a stored procedure that references a table that is upgraded from SQL Server 2000 to SQL Server 2005: “A time-out occurred while waiting for buffer latch"


50001573
940949 (http://support.microsoft.com/kb/940949/)
FIX: You receive an error message when you run an UPDATE CUBE statement to update a cube in SQL Server 2005 Analysis Services


50001576
940962 (http://support.microsoft.com/kb/940962/)
FIX: When processing a dimension on SQL Server 2005 Analysis Services an error is raised with the following format: "The following file is corrupted: Physical file: \\?\\MSMDBuildLevelStores_avl_672_29775_njzs2.tmp. Logical file ."

50001511
940126 (http://support.microsoft.com/kb/940126/)
FIX: Error 9003 is logged in the SQL Server error log file when you use log shipping in SQL Server 2005


50001436
940379 (http://support.microsoft.com/kb/940379/)
FIX: Error message when you use the UNLOAD and REWIND options to back up a database to a tape device in SQL Server 2005: "Operation on device '' exceeded retry count"

50001412
940375 (http://support.microsoft.com/kb/940375/)
FIX: Error message when you use the Copy Database Wizard to move a database from SQL Server 2000 to SQL Server 2005


50001522
939562 (http://support.microsoft.com/kb/939562/)
FIX: Error message when you run a query that fires an INSTEAD OF trigger in SQL Server 2005 Service Pack 2: "Internal Query Processor Error The query processor could not produce a query plan"


50001224
937100 (http://support.microsoft.com/kb/937100/)
FIX: Error message when you run a SQL Server 2005 Integration Services package that contains a Script Component transformation: "Insufficient memory to continue the execution of the program"


50001415
940377 (http://support.microsoft.com/kb/940377/)
FIX: Error message when you process cubes for one of the named instances of SQL Server 2005 Analysis Services: "Error opening file"


50001523
938363 (http://support.microsoft.com/kb/938363/)
FIX: Data is not replicated to a subscriber in a different partition by using parameterized row filters in SQL Server 2005


50001529
940945 (http://support.microsoft.com/kb/940945/)
FIX: Performance is very slow when the same stored procedure is executed at the same time in many connections on a multiple-processor computer that is running SQL Server 2005

50001578
939285 (http://support.microsoft.com/kb/939285/)
FIX: Error message when you run a stored procedure that starts a transaction that contains a Transact-SQL statement in SQL Server 2005: "New request is not allowed to start because it should come with valid transaction descriptor"


50001525
938086 (http://support.microsoft.com/kb/938086/)
FIX: A SQL Server Agent job fails when you run the SQL Server Agent job in the context of a proxy account in SQL Server 2005


50000872
936252 (http://support.microsoft.com/kb/936252/)
The file name of Cumulative Update 3 for SQL Server 2005 Service Pack 2 is incorrectly associated with Microsoft Knowledge Base article 936252


50000872
The MDX query performance is slow in SQL Server 2005 Analysis Services because SQL Server 2005 Analysis Services does not reuse the data cache
50001109
The dta utility stops unexpectedly and an exception occurs in SQL Server 2005
50001224
When you run a SQL Server 2005 Integration Services package that uses the VariableDispenser class, the package fails and you receive an error message
50001365
After you install SQL Server 2005 Service Pack 2, you receive error 8624 if the result set of a fast forward cursor contains a certain number of columns
50001368
After you install SQL Server 2005 Service Pack 2, the performance of a MDX query is 10 times slower than the performance on SQL Server 2005 Analysis Services build 1555
50001396
When you open a SQL Server 2005 Reporting Services report after you install SQL Server 2005 Service pack 2, the parameter toolbar and the report toolbar does not appear correctly if you specify the SP_Full value for the rc:StyleSheet URL access parameter on a report URL
50001412
Error message when you use the Copy Database Wizard to move a database from SQL Server 2000 to SQL Server 2005: "Cannot drop database "Database_Name" because it is currently in use.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly"
50001414
Error message when you use the bcp utility together with the queryout option to bulk copy data from SQL Server 2005 to a file: "SQLState = HY000, NativeError = 0 Error = [Microsoft][SQL Native Client]BCP host-files must contain at least onecolumn"
50001415
After you install SQL Server 2005 Service Pack 2, the Msmdredir.ini file is frequently updated by each instance of SQL Server 2005
50001436
Error message when you use the BACKUP DATABASE statement together with the UNLOAD option and with the REWIND option to back up a tape device in SQL Server 2005: "Operation on device 'TAPE0(<\\.\Tape0>)' exceeded retry count"
50001461
When some MDX queries are executed at the same for the same role or for the same user in SQL Server 2005 Analysis Services, the CPU usage is very high
50001475
When you open a report that contains a date and time picker (DTP) control in SQL Server 2005 Reporting Services, the format of the DTP control appears incorrectly
50001511
Error 9003 occurs when you restore a transaction log backup in SQL Server 2005
50001520
The query syntax of a report is changed when you run the report in SQL Server 2005 Reporting Services Service Pack 2 on SAP BW 3.5
50001522
Error 8624 occurs when you run a query in SQL Server 2005 Service Pack 2 (SP2) or later versions. However, you can successfully run the query in pre-SP2 version of SQL Server 2005
50001523
After you install SQL Server 2005 Service Pack 2, publications that use precomputed partitions can cause the non-convergence of data
50001525
Error message when you use SQL Server Agent to run jobs by using a proxy account: " SQLServer Error: 22046, Encryption error using CryptProtectData, CryptUnprotectData failed (1723)"
50001526
Using SQL Server Agent to run jobs in the context of a proxy account may fail with error "SQLServer Error: 22046, Encryption error using CryptProtectData, CryptUnprotectData failed (1723)"
50001529
The performance of SQL Server 2005 decreases because SQL Server 2005 is waiting for access to memory objects which is indicated by the CMEMTHREAD waittype
50001578
An exception occurs in SQL Native Client: "New request is not allowed to start because it should come with valid transaction descriptor"
50001579
When you use SQL Native Client to retrieve a value in a column of the TEXT data type, you obtain incorrect result if the value contains more than 1024 characters
50001580
Memory leak of the TokenAndPermAccessCheckResult entries occurs in SQL Server 2005
50001595
When you use SQL Native Client for a connection, the connection switches to use the auto-commit mode from the manually-commit mode
50001598
SQL Native Client overwrite error codes which causes that you do not receive informative error messages when some operations fails
50001639
The performance of an INSERT statement or an UPDATE statement that uses the result from a query is much slower in SQL Server 2005 Service Pack 2 than in SQL Server 2005 Service Pack 1 or earlier versions if the query uses the nodes method
50001164
FIX: Error message when you connect to an instance of SQL Server 2008 Analysis Services by using the AMO library that is included with SQL Server 2005 Service Pack 2 Analysis Services: "Cannot connect to Analysis Services version '10.0.1019.17'"

Wednesday, August 22, 2007

geekSpeak recording - Real World SQL Server Integration Services with Matthew Roche

Channel 9 has posted a SQL Server 2005 Integration Services screen cast. From the site:

This geekSpeak is all about SQL Server 2005 Integration Services. We are lucky to have a real expert from the industry, Matthew Roche, to share his experiences with us. Matthew shows us how SSIS is a real development studio, since it's an instance of Visual Studio 2005, with new designers. It's very familiar for folks who are moving from a traditional development environment. He gets us familiar with tools and techniques, solutions and projects, like the drag-and-drop approach to building packages, opportunities to include scripts, and develop your own components as .NET Assemblies.

Matthew answers some great questions around performance, programmability. He helps us understand the distinction between data flows and control flows, and how best to manage SSIS packages. He offers some useful guidance on what scenarios merit what choices for moving data from one place to another - be it .NET app, SSIS, TSQL, BCP and so on.But the most important reason to watch is to find out what Matthew would "chew off his own mouse finger" to avoid having to do. :D
Be sure to check the geekSpeak blog for upcoming geekSpeaks!


Watch the screencast(WMV)

Monday, August 20, 2007

Do you know how NULLIF and non-deterministic functions work?

Run this first

CREATE TABLE #j (n varchar(15))

DECLARE @a int
SET @a = 1
WHILE @a <= 1000 BEGIN
INSERT
#j
SELECT NULLIF(REPLICATE('1', RAND()*2) , ' ')
SET @a = @a + 1
END
Go

After that is done run this query

SELECT * FROM #j WHERE n = ' '

You will get back between 200 and 300 rows. What just happened? In our insert we use this NULLIF(REPLICATE('1', RAND()*2) , ' ')
What this does is the following: if REPLICATE('1', RAND()*2) equals ' ' then it will insert a NULL, so where do the blanks come from? Well let's find out.

Run this

SET SHOWPLAN_TEXT ON

SELECT
NULLIF(REPLICATE('1', RAND()*2) , ' ')

and we see the following
--Compute Scalar(DEFINE:([Expr1000]=If (replicate('1', Convert(rand(NULL)*2))=' ') then NULL else replicate('1', Convert(rand(NULL)*2))))

This can also be written like this

SELECT CASE WHEN REPLICATE('1', RAND()*2) =' '
THEN NULL ELSE REPLICATE('1', RAND()*2) END

See what happens? First SQL evaluates if REPLICATE('1', RAND()*2) is ' ' if that is not ' ' then the same code gets executed again and thus could be a blank
If you use a variable this can never happen.

Here is an example, keep hitting F5 and you will see it will never be blank

DECLARE @val float
SET
@val = RAND()

SELECT NULLIF(REPLICATE('1', CONVERT(int, @val*2)) , ' ')

Article: LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures)

LINQ to SQL is a built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables you to model relational databases using .NET classes. You can use LINQ expressions to query the database with them, as well as update/insert/delete data.

This is the 6th article that Scott Guthrie has written about LINQ. The first 5 can be found below.

Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control

What is covered in the 6th article?

To SPROC or not to SPROC? That is the question....
The Steps to Map and Call a SPROC using LINQ to SQL
How to Map a SPROC to a LINQ to SQL DataContext
How to Call our Newly Mapped SPROC
Mapping the Return Type of SPROC Methods to Data Model Classes
Handling SPROC Output Parameters
Handling Multiple Result Shapes from SPROCs
Supporting User Defined Functions (UDFs)
Summary



Read the article here: http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx

Thursday, August 09, 2007

SQL Server Monitor Gadget for Windows Vista Sidebar

Conchango are making available version 1 of our SQL Server Monitor Gadget for Windows Vista Sidebar

The gadget does exactly what it says on the tin; it monitors a specified SQL Server database for various metrics and displays them on the Windows Vista Sidebar. It is provided for use by SQL Server DBAs that require a nice'n'easy way of monitoring important metrics on their SQL Server installations. In version 1 the gadget provides the following information:

Data file size - total file size of the database data files
Data file used - amount of used space on those data files
Data file used % - The percentage of the total data size that has been used
Log file size - total file size of the database log files
Log file used - amount of used space on those log files
Log file used % - The percentage of the total log size that has been used


Watch the demo, read more and download the gadget here: http://blogs.conchango.com/jamiethomson/archive/2007/08/09/Announcing-SQL-Server-Monitor-Gadget-for-Windows-Vista-Sidebar.aspx

Wednesday, July 04, 2007

SQL Server 2005 Best Practices Analyzer Released, End Of Support For SQL Server 2000 SP3a In 6 Days

End of Support for SQL Server 2000 Service Pack 3a
Support for SQL Server 2000 Service Pack 3a (SP3a) will end on July 10, 2007.
Microsoft will end technical support on this date, which also includes security updates for this Service Pack. Microsoft is ending support for this product as part of our Service Pack support policy, found http://support.microsoft.com/lifecycle.

Customers running SQL Server 2000 Service Pack 3a are encouraged to migrate to SQL Server 2000 Service Pack 4 or SQL Server 2005. Remaining current on your service pack installation ensures that your products remain supported per the Support Lifecycle policy. Additionally, your software benefits from the many enhancements, fixes, and security updates provided through the latest service pack.

Read more here: http://blogs.msdn.com/sqlreleaseservices/archive/2007/07/02/end-of-support-for-sql-server-2000-service-pack-3a.aspx



SQL Server 2005 Best Practices Analyzer (July 2007) Realeased
It does not say CTP anywhere on this page so I assume that this is a 'production' version.
Get it here: http://www.microsoft.com/downloads/details.aspx?FamilyID=da0531e4-e94c-4991-82fa-f0e3fbd05e63&DisplayLang=en

Thursday, June 14, 2007

C# IsNullOrEmpty Function In SQL Server

Mladen Prajdic has created a SQL equivalent of the C# IsNotNullOrEmpty
I looked at it and thought that there was way too much code

Here is my version which I have modified, you pass an additional parameter in to indicate whether you want blanks only to count or not


CREATE FUNCTION dbo.IsNotNullOrEmpty(@text NVARCHAR(4000),@BlanksIsEmpty bit)
RETURNS BIT
AS

BEGIN
DECLARE
@ReturnValue bit

IF
@BlanksIsEmpty = 0
BEGIN
SELECT
@ReturnValue= SIGN(COALESCE(DATALENGTH(@text),0))
END
ELSE
BEGIN
SELECT
@ReturnValue= SIGN(COALESCE(DATALENGTH(RTRIM(@text)),0))
END

RETURN
@ReturnValue
END
Go


Here are some calls where we want blanks to return as empty or null
The function returns = if it is empty and 1 if it is not empty

SELECT dbo.IsNotNullOrEmpty(null,1),dbo.IsNotNullOrEmpty('azas',1),
dbo.IsNotNullOrEmpty(' ',1),dbo.IsNotNullOrEmpty('',1)


Here are some calls where we don't want blanks to return as empty or null

SELECT dbo.IsNotNullOrEmpty(null,0),dbo.IsNotNullOrEmpty('azas',0),
dbo.IsNotNullOrEmpty(' ',0),dbo.IsNotNullOrEmpty('',0)

My function is the opposite of Mladen's I check for is NOT null or empty instead of IS null or empty (easier to code it with the SIGN function)

Wednesday, June 13, 2007

SQL Myth: Truncate Cannot Be Rolled Back Because It Is Not Logged

I am still amazed at how many people still think that TRUNCATE TABLE is not logged. There is some logging going on but it is minimal, here is what Books On Line says:

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.

The DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row.

Let’s prove that we can rollback a truncate

Create this table and do the select

CREATE TABLE dbo.Enfarkulator (ID int IDENTITY PRIMARY KEY, SomeOtherCol varchar(49))
GO
INSERT dbo.Enfarkulator VALUES(1)
INSERT dbo.Enfarkulator VALUES(1)



SELECT * FROM dbo.Enfarkulator

ID SomeOtherCol
1 1
2 1


Now run this part

BEGIN TRAN
TRUNCATE TABLE
dbo.Enfarkulator
SELECT * FROM dbo.Enfarkulator
ROLLBACK TRAN


ID SomeOtherCol
(0 row(s) affected)

As you can see the table was truncated, now select from the table again


SELECT * FROM dbo.Enfarkulator

ID SomeOtherCol
1 1
2 1


Yep, the data is there, proving that you can rollback a truncate and all the data will be there. There are two other major difference between truncate and delete which I will explain below.

Truncate doesn’t preserve the identity value but delete does

This is another difference between truncate and delete, truncate will reset the identity value but delete does not. Run the following code to see how that works


CREATE TABLE dbo.Enfarkulator2 (ID int IDENTITY, SomeOtherCol varchar(49))
GO
INSERT dbo.Enfarkulator2 VALUES(1)
INSERT dbo.Enfarkulator2 VALUES(1)


SELECT * FROM dbo.Enfarkulator2
SELECT * FROM dbo.Enfarkulator


DELETE dbo.Enfarkulator2
TRUNCATE TABLE dbo.Enfarkulator

INSERT dbo.Enfarkulator VALUES(1)
INSERT dbo.Enfarkulator2 VALUES(1)

SELECT * FROM dbo.Enfarkulator2
SELECT * FROM dbo.Enfarkulator

The Enfarkulator id was reset and the Enfarkulator2 id was not. In order to do the same with delete you will need to run a dbcc checkident reseed command. Here is the code for that.

DELETE dbo.Enfarkulator2
TRUNCATE TABLE dbo.Enfarkulator

DBCC CHECKIDENT (Enfarkulator2, RESEED, 0)

Now insert again and you will see that the values are the same.

INSERT dbo.Enfarkulator VALUES(1)
INSERT dbo.Enfarkulator2 VALUES(1)

SELECT * FROM dbo.Enfarkulator2
SELECT * FROM dbo.Enfarkulator



You can’t truncate tables that are referenced by a foreign key constraint.

If you have a table which is referenced by another table with a foreign key constraint then you cannot truncate that table. Here is the code for that

CREATE TABLE dbo.Enfarkulator3 (ID int IDENTITY, SomeOtherCol varchar(49))
GO
INSERT dbo.Enfarkulator3 VALUES(1)



Now let’s add the foreign key

ALTER TABLE dbo.Enfarkulator3 ADD CONSTRAINT [FK_Fark3_Fark]
FOREIGN KEY ([ID]) REFERENCES [dbo].[Enfarkulator] ([ID])


Now try to truncate.

TRUNCATE TABLE Enfarkulator

Server: Msg 4712, Level 16, State 1, Line 1
Cannot truncate table 'Enfarkulator' because it is being referenced by a FOREIGN KEY constraint.

See? You cannot do that

--Clean up time ;-)
DROP TABLE dbo.Enfarkulator3,dbo.Enfarkulator2,dbo.Enfarkulator


Cross-posted from SQLBlog! - http://www.sqlblog.com/

Wednesday, May 30, 2007

Speed Up Performance And Slash Your Table Size By 90% By Using Bitwise Logic

You have all seen websites where you can pick a bunch of categories by selection a bunch of check boxes. usually what you do is store those in a lookup table and then you create another table where you store all the categories for each customer.
What if I tell you that you can store all that info in 1 row instead of 10 rows if a customer picked 10 categories.
Take a look at this




1 Classic Rock
2 Hard Rock
4 Speed/Trash Metal
You will store a value of 1 + 2 + 4 = 7(you just sum the values)

Now run this to check, the result will be 7 for a match and some other value otherwise



select 7 | 1,
7 | 2,
7 |3,
7 |4,
7 |5,
7 |6,
7 |7,
7 |8,
7 |20



What is this |(pipe symbol)?
From Books on line
The bitwise operator performs a bitwise logical OR between the two expressions, taking each corresponding bit for both expressions. The bits in the result are set to 1 if either or both bits (for the current bit being resolved) in the input expressions have a value of 1; if neither bit in the input expressions is 1, the bit in the result is set to 0.
The bitwise operator requires two expressions, and it can be used on expressions of only the integer data type category.




Here is how you would typically use this, first create this table




CREATE TABLE NumbersTable (Num int)
INSERT NumbersTable VALUES(1)
INSERT NumbersTable VALUES(2)
INSERT NumbersTable VALUES(3)
INSERT NumbersTable VALUES(4)
INSERT NumbersTable VALUES(5)
INSERT NumbersTable VALUES(6)
INSERT NumbersTable VALUES(7)
INSERT NumbersTable VALUES(8)
INSERT NumbersTable VALUES(9)
INSERT NumbersTable VALUES(10)
INSERT NumbersTable VALUES(11)
INSERT NumbersTable VALUES(12)
GO

Now run this

SELECT
Num,
CASE 7 |Num WHEN 7 THEN 'Yes' ELSE 'No' END AS COL
FROM NumbersTable

Here is the output




Num COL
---- ---
1 Yes
2 Yes
3 Yes
4 Yes
5 Yes
6 Yes
7 Yes
8 No
9 No
10 No
11 No
12 No




Okay enough theory let's start with some SQL code. First create this table which will hold all the categories




CREATE TABLE MusicChoice (ID INT PRIMARY KEY,
ChoiceDescription VARCHAR(100))




INSERT MusicChoice VALUES(1,'Classic Rock')
INSERT MusicChoice VALUES(2,'Hard Rock')
INSERT MusicChoice VALUES(3,'Speed/Trash Metal')
INSERT MusicChoice VALUES(4,'Classical')
INSERT MusicChoice VALUES(5,'Rap')
INSERT MusicChoice VALUES(6,'Blues')
INSERT MusicChoice VALUES(7,'Jazz')
INSERT MusicChoice VALUES(8,'Alternative Rock')
INSERT MusicChoice VALUES(9,'Easy Listening')
INSERT MusicChoice VALUES(10,'Progressive Rock')
INSERT MusicChoice VALUES(11,'Punk Rock')
INSERT MusicChoice VALUES(12,'Swing')
INSERT MusicChoice VALUES(13,'Techno')
INSERT MusicChoice VALUES(14,'Pop')
INSERT MusicChoice VALUES(15,'Disco')
INSERT MusicChoice VALUES(16,'Big Band')
INSERT MusicChoice VALUES(17,'Gospel')
INSERT MusicChoice VALUES(18,'Heavy Metal')
INSERT MusicChoice VALUES(19,'House')
INSERT MusicChoice VALUES(20,'Celtic')
Now create the Bitwise table

CREATE
TABLE BitwiseMusicChoice (ID INT PRIMARY KEY,
ChoiceDescription VARCHAR(100))





We will use the POWER function to create the correct values
run this

SELECT
id,POWER(2,id-1)BitID,ChoiceDescription
FROM MusicChoice




Here is the output
id BitID ChoiceDescription
1 1 Classic Rock
2 2 Hard Rock
3 4 Speed/Trash Metal
4 8 Classical
5 16 Rap
6 32 Blues
7 64 Jazz
8 128 Alternative Rock
9 256 Easy Listening
10 512 Progressive Rock
11 1024 Punk Rock
12 2048 Swing
13 4096 Techno
14 8192 Pop
15 16384 Disco
16 32768 Big Band
17 65536 Gospel
18 131072 Heavy Metal
19 262144 House
20 524288 Celtic




Now insert it into the BitwiseMusicChoice table




INSERT BitwiseMusicChoice
SELECT POWER(2,id-1)BitID,ChoiceDescription
FROM MusicChoice




Now create this customer table


CREATE
TABLE Customer (CustomerID int identity, CustomerCode uniqueidentifier not null)




Insert these 5 values first, we will use these to compare performance later




INSERT Customer VALUES('1DAB5C03-BC23-4FB5-AC3D-A46489459FE9')
INSERT Customer VALUES('F7DDCDBC-F646-493A-B872-4E2E82EA8E14')
INSERT Customer VALUES('E8A4C3D2-AEB0-4821-A49D-3BF085354448')
INSERT Customer VALUES('52581088-C427-4D2F-A782-250564D44D8C')
INSERT Customer VALUES('1B2622C4-6C17-4E74-99D6-336197FBBCFF')

Now we will insert a total of 10000 customers




SET NOCOUNT ON
BEGIN
TRAN
DECLARE
@LoopCounter INT
SET
@LoopCounter = 6
WHILE @LoopCounter <= 10000
BEGIN
INSERT
Customer VALUES(NEWID())
SET @LoopCounter = @LoopCounter + 1
END
COMMIT
WORK
GO




Now add the primary key




ALTER TABLE Customer ADD CONSTRAINT pk_Customer PRIMARY KEY (CustomerCode)

Create another table to hold the choices

CREATE
TABLE CustomerMusicChoice (id INT identity, MusicChoiceID int, CustomerCode uniqueidentifier)




ALTER TABLE CustomerMusicChoice ADD CONSTRAINT fk_MusicChoice_ID FOREIGN KEY (MusicChoiceID) REFERENCES MusicChoice(ID)




ALTER TABLE CustomerMusicChoice ADD CONSTRAINT fk_CustomerCode FOREIGN KEY (CustomerCode)REFERENCES Customer(CustomerCode)




For each customer insert 10 random choices, this should run less than a minute



SET NOCOUNT ON
BEGIN
TRAN
DECLARE
@LoopCounter INT
DECLARE
@CustID uniqueidentifier
SET
@LoopCounter = 1
WHILE @LoopCounter <= 10000
BEGIN
SELECT
@CustID = CustomerCode
FROM Customer
WHERE CustomerID = @LoopCounter
INSERT Customer VALUES(NEWID())
INSERT CustomerMusicChoice(MusicChoiceID,CustomerCode)
SELECT TOP 10 id,@CustID
FROM MusicChoice
ORDER BY NEWID()
SET @LoopCounter = @LoopCounter + 1
END
COMMIT
WORK
GO

Now add these indexes
CREATE INDEX ix_CustomerMusicChoice_Cust On CustomerMusicChoice(CustomerCode)



CREATE INDEX ix_CustomerMusicChoice_ID On CustomerMusicChoice(MusicChoiceID)




Create the BitwiseCustomerMusicChoice which will hold the Bitwise values




CREATE TABLE BitwiseCustomerMusicChoice (id INT identity, MusicChoiceID int, CustomerCode uniqueidentifier not null)




This will populate the BitwiseCustomerMusicChoice table




INSERT INTO BitwiseCustomerMusicChoice
SELECT SUM(POWER(2,MusicChoiceID-1)) as MusicChoiceID,CustomerCode
FROM CustomerMusicChoice
GROUP BY CustomerCode




Add the index and foreign key




ALTER TABLE BitwiseCustomerMusicChoice ADD CONSTRAINT pk_BitwiseCustomerMusicChoice PRIMARY KEY (CustomerCode)




ALTER TABLE BitwiseCustomerMusicChoice ADD CONSTRAINT fk_BitwiseCustomerCode FOREIGN KEY (CustomerCode)REFERENCES Customer(CustomerCode)

Now let's test performance. Hit CTRL + K (SQL 2000) or CTRL + M (SQL 2005)



These 2 queries will return something like this




ID ChoiceDescription Picked
8 Alternative Rock No
16 Big Band No
6 Blues No
20 Celtic No
1 Classic Rock No
4 Classical Yes
15 Disco Yes
9 Easy Listening Yes
17 Gospel No
2 Hard Rock No
18 Heavy Metal Yes
19 House Yes
7 Jazz Yes
14 Pop Yes
10 Progressive Rock Yes
11 Punk Rock No
5 Rap No
3 Speed/Trash Metal Yes
12 Swing Yes
13 Techno No


SELECT
mc.ID,ChoiceDescription,CASE WHEN CustomerCode IS NULL THEN 'No' ELSE 'Yes' END Picked
FROM CustomerMusicChoice cmc
RIGHT JOIN MusicChoice mc on cmc.MusicChoiceID = mc.id
AND CustomerCode ='1DAB5C03-BC23-4FB5-AC3D-A46489459FE9'
ORDER BY ChoiceDescription




SELECT bmc.ID,ChoiceDescription,
CASE WHEN bmc.ID |MusicChoiceID =MusicChoiceID THEN 'Yes'
ELSE 'No'
END AS Picked
FROM BitwiseCustomerMusicChoice cmc
CROSS JOIN BitwiseMusicChoice bmc
WHERE CustomerCode ='1DAB5C03-BC23-4FB5-AC3D-A46489459FE9'
ORDER BY ChoiceDescription




Look at the execution plan
67.60% against 32.40% not bad right?



Plan1




Now run this, we will add AND bmc.ID > 0 to both queries. This will change an index scan to an index seek in the bottom query




SELECT mc.ID,ChoiceDescription,CASE WHEN CustomerCode IS NULL THEN 'No' ELSE 'Yes' END Picked
FROM CustomerMusicChoice cmc
RIGHT JOIN MusicChoice mc on cmc.MusicChoiceID = mc.id
AND CustomerCode ='1DAB5C03-BC23-4FB5-AC3D-A46489459FE9'
AND mc.ID > 0
ORDER BY ChoiceDescription




SELECT bmc.ID,ChoiceDescription,
CASE WHEN bmc.ID |MusicChoiceID =MusicChoiceID THEN 'Yes'
ELSE 'No'
END AS Picked
FROM BitwiseCustomerMusicChoice cmc
CROSS JOIN BitwiseMusicChoice bmc
WHERE CustomerCode ='1DAB5C03-BC23-4FB5-AC3D-A46489459FE9'
AND bmc.ID > 0
ORDER BY ChoiceDescription



That improved the performance a little. 82.75% against 17.25%





Plan2




Now look at the tables, after running dbcc showcontig you can see that the BitwiseCustomerMusicChoice is about 1/10th the size of the CustomerMusicChoice table which is as expected.


dbcc showcontig ('BitwiseCustomerMusicChoice')
---------------------------------------------------------------------------
DBCC SHOWCONTIG scanning 'BitwiseCustomerMusicChoice' table...
Table: 'BitwiseCustomerMusicChoice' (772197801); index ID: 1, database ID: 26
TABLE level scan performed.
- Pages Scanned................................: 41
- Extents Scanned..............................: 6
- Extent Switches..............................: 5
- Avg. Pages per Extent........................: 6.8
- Scan Density [Best Count:Actual Count].......: 100.00% [6:6]
- Logical Scan Fragmentation ..................: 0.00%
- Extent Scan Fragmentation ...................: 0.00%
- Avg. Bytes Free per Page.....................: 48.0
- Avg. Page Density (full).....................: 99.41%
DBCC execution completed. If DBCC printed error messages, contact your system administrator.




dbcc showcontig ('CustomerMusicChoice')
---------------------------------------------------------------------------
DBCC SHOWCONTIG scanning 'CustomerMusicChoice' table...
Table: 'CustomerMusicChoice' (724197630); index ID: 0, database ID: 26
TABLE level scan performed.
- Pages Scanned................................: 428
- Extents Scanned..............................: 55
- Extent Switches..............................: 54
- Avg. Pages per Extent........................: 7.8
- Scan Density [Best Count:Actual Count].......: 98.18% [54:55]
- Extent Scan Fragmentation ...................: 40.00%
- Avg. Bytes Free per Page.....................: 386.5
- Avg. Page Density (full).....................: 95.22%
DBCC execution completed. If DBCC printed error messages, contact your system administrator.


What happens if you want to get the total count of for example Classical?




SELECT COUNT(*)
FROM CustomerMusicChoice cmc
JOIN MusicChoice mc on cmc.MusicChoiceID = mc.id
WHERE mc.ChoiceDescription ='Classical'

SELECT COUNT(*)
FROM BitwiseCustomerMusicChoice cmc
JOIN BitwiseMusicChoice bmc ON bmc.ID |MusicChoiceID =MusicChoiceID
WHERE bmc.ChoiceDescription ='Classical'

Here are execution plans for SQl Server 2000 and 2005

Plan3A

Plan3B

As you can see SQL Server 2005 has a bigger difference than SQL Server 2000



Now let's look at the overal picture, on a busy system you will have the customer queries running many times an hour/day. The report queries will run maybe a couple a times a day. I think this trade off is perfectly acceptable because overall your system will perform better. Another thing to keep in mind is that instead of 10 inserts you only have to do 1, same with updates, all these little things add up to a lot eventualy.




So as you can see using bitwise logic is a great way to accomplish a couple of things
Reduce table size
Speed up backup and recovery because your table is much smaller
Improve performance



Of course you have to do some testing for yourself because it might not be appropriate for your design. If your system is more of an OLAP than OLTP type of system then don't bother implementing this since it won't help you.




Cross-posted from SQLBlog! - http://www.sqlblog.com

Tuesday, May 29, 2007

Check Your SQL For SQL Injection Vulnerabilities By Using These 15 Free SQL Injection Scanners

Memorial day is over, back to work. Your first task is to check for SQL Injections
Securiry Hacks has listed 15 of them, that list is here:

SQLIer
SQLbftools
SQL Injection Brute-forcer - SQLibf
SQLBrute
BobCat
SQLMap
Absinthe
SQL Injection Pen-testing Tool
SQID
Blind SQL Injection Perl Tool
SQL Power Injection Injector
FJ-Injector Framwork
SQLNinja
Automagic SQL Injector
NGSS SQL Injector

Read the details and get the download links here: http://www.security-hacks.com/2007/05/18/top-15-free-sql-injection-scanners

If you are using a lot of dynamic SQL then don't forget to read The Curse and Blessings of Dynamic SQL written by Erland Sommarskog, SQL Server MVP.

Sunday, April 22, 2007

AdventureWorksLT Sample Database Available For Download, Don't Forget To Attach The DB To See It

There is a new sample database available for SQL Server 2005. The name of this database is AdventureWorksLT , this database is a stripped down version of AdventureWorks.
You can download the installers for the AdventureWorksLT sample databases here
x86 AdventureWorksLT.msi -- 2,251 KB
x64 AdventureWorksLT_x64.msi -- 2,251 KB
Itanium (IA64) AdventureWorksLT_IA64.msi -- 2,251 KB

If you want to read more on the download page go here: http://www.microsoft.com/downloads/details.aspx?familyid=e719ecf7-9f46-4312-af89-6ad8702e4e6e&displaylang=en


Okay so you have downloaded the file and installed the database. But where is the database? You will have to attach the DB, you can use the wizard or this script below (make sure that you change the path and username, both are in bold font)

USE [master]
GO
CREATE DATABASE [AdventureWorksLT] ON
( FILENAME = N'C:\YourPathHere\MSSQL\Data\AdventureWorksLT_Data.mdf' ),
( FILENAME = N'C:\YourPathHere\MSSQL\Data\AdventureWorksLT_Log.ldf' )
FOR ATTACH
GO

if exists (select name from master.sys.databases sd where name = N'AdventureWorksLT' and SUSER_SNAME(sd.owner_sid) = SUSER_SNAME() )
EXEC [AdventureWorksLT].dbo.sp_changedbowner @loginame=N'LoginName', @map=false
GO


Now you can run these scripts to see how many tables, views, procedures and functions there are

SELECT TABLE_SCHEMA + '.' + TABLE_NAME AS FullTableName
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY FullTableName

-------------------------
dbo.BuildVersion
dbo.ErrorLog
SalesLT.Address
SalesLT.Customer
SalesLT.CustomerAddress
SalesLT.Product
SalesLT.ProductCategory
SalesLT.ProductDescription
SalesLT.ProductModel
SalesLT.ProductModelProductDescription
SalesLT.SalesOrderDetail
SalesLT.SalesOrderHeader



SELECT TABLE_SCHEMA + '.' + TABLE_NAME AS FullTableName
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'VIEW'
ORDER BY FullTableName

-------------------------------------
SalesLT.vGetAllCategories
SalesLT.vProductAndDescription
SalesLT.vProductModelCatalogDescription


SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE ='FUNCTION'

-------------------------
ufnGetCustomerInformation
ufnGetSalesOrderStatusText
ufnGetAllCategories


SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE ='PROCEDURE'

-------------------------
uspPrintError
uspLogError