Académique Documents
Professionnel Documents
Culture Documents
INT = 100
1.2 In SQL Server 2005(Yukon), We can declare and initialize the variables in separate lines, Otherwise It will through an Error
INT = 100
Msg 139, Level 15, State 1, Line Cannot assign a default value to Msg 137, Level 15, State 2, Line Must declare the scalar variable
DECLARE @intA INT SELECT @intA = 100 --(or) SET SELECT @intA
Result: 100
@intA = 100
DECLARE @intA INT = 100 SELECT @intA += 1000 --(or) SELECT @intA = @intA + 1000 SELECT @intA [@intA]
@intA ----1100
DECLARE @intA INT = 100 SELECT @intA -= 1000 --(or) SELECT @intA = @intA - 1000 SELECT @intA [@intA]
@intA -----900
DECLARE @intA INT = 100 SELECT @intA *= 1000 --(or) SELECT @intA = @intA * 1000 SELECT @intA [@intA]
@intA ------
100000
DECLARE @intA INT = 100 SELECT @intA /= 1000 --(or) SELECT @intA = @intA / 1000 SELECT @intA [@intA]
@intA ----0
DECLARE @intA INT = 100 SELECT @intA %= 1000 --(or) SELECT @intA = @intA % 1000 SELECT @intA [@intA]
@intA ----100
IF OBJECT_ID('TBL_TABLE1','U') IS NOT NULL DROP TABLE TBL_TABLE1 GO CREATE TABLE TBL_TABLE1 ( ID INT IDENTITY(1,1) , COL1 VARCHAR(10) , COL2 VARCHAR(15) ) GO INSERT TBL_TABLE1 (COL1, COL2) VALUES ('A' ,'AA'), ('B' ,'BB'), ('C' ,'CC') GO
Insteadof:
INSERT TBL_TABLE1 (COL1, COL2) VALUES('A' ,'AA') INSERT TBL_TABLE1 (COL1, COL2) VALUES('B' ,'BB') INSERT TBL_TABLE1 (COL1, COL2) VALUES('C' ,'CC') GO SELECT ID, COL1,COL2 FROM TBL_TABLE1
Result:
ID ----------1 2 3 COL1 ---------A B C COL2 --------------AA BB CC
(3 row(s) affected)
DATETIMEOFFSET 8 to 10 Bytes January-01-0001 to December-01-9999 (YYYY-MM-DD hh:mm:ss.nnnnnnn +/- hh:mm) 1947-08-15 12:02:13.1234567 + 02:05 SQL Server 2005: DATETIME SMALLDATETIME 4 Bytes January-01-1753 to December-01-9999 2 Bytes January-01-1900 to June-06-2079
Result: 1947-08-15 12:02:14 The SMALLDATETIMEOFFSET Data type based on 24 hour clock. It can be local (or) UTC date time.
DECLARE SELECT
AS AS AS AS
Date 1947-08-15
Datetime 1947-08-15
[SYSDATETIME()]
Similar to SQL Server 2005 : GETDATE(),CURRENT_TIMESTAMP except nanoseconds 7 format. GETDATE() 2010-04-13 23:49:29.230 CURRENT_TIMESTAMP 2010-04-13 23:49:29.230
SYSUTCDATETIME ()
[SWITCHOFFSET()]
TODATETIMEOFFSET()
2010-04-14 21:43:08.5937500 -02:12
The following code demonstrates how to use the HIERARCHYID type, creating a table named Tbl_Structure
IF OBJECT_ID('dbo.Tbl_Structure', 'U') IS NOT NULL DROP TABLE dbo.Tbl_Structure; GO CREATE TABLE dbo.Tbl_Structure ( FunctionID INT NOT NULL, Hierarchy_ID HIERARCHYID NOT NULL, Hierarchy_Level AS Hierarchy_ID.GetLevel() PERSISTED, FunctionName VARCHAR(50) NOT NULL, CONSTRAINT PK_Tbl_Structure PRIMARY KEY NONCLUSTERED(FunctionID) ); GO CREATE UNIQUE CLUSTERED INDEX idx_One ON dbo.Tbl_Structure(Hierarchy_ID); CREATE UNIQUE INDEX idx_Two ON dbo.Tbl_Structure(Hierarchy_Level, Hierarchy _ID); GO
To insert a node into the hierarchy, you must first produce a new HIERARCHYID value that represents the correct position in the hierarchy. Use the HIERARCHYID::GetRoot() method to produce the value for the root node. You use the GetDescendant method to produce a value below a given parent. The GetDescendant method accepts two optional HIERARCHYID input values representing the two nodes between which you want to position the new node. Note that the GetDescendant method does not guarantee that HIERARCHYID values are unique. To enforce uniqueness, you must define a primary key, a unique constraint, or a unique index on the column. For example, the following code creates the usp_AddStructure stored procedure, which adds a new node to the hierarchy:
IF OBJECT_ID('dbo.usp_AddStructure', 'P') IS NOT NULL DROP PROC dbo.usp_AddStructure; GO CREATE PROC dbo.usp_AddStructure @FunctionID AS INT, @CategoryID AS INT = NULL,
IF @CategoryID IS NULL SET @Hierarchy_ID = HIERARCHYID::GetRoot(); ELSE BEGIN SET @Category_Hierarchy_ID = (SELECT Hierarchy_ID FROM dbo.Tbl_Stru cture WHERE FunctionID= @CategoryID); SET @last_child_Hierarchy_ID = (SELECT MAX(Hierarchy_ID) FROM dbo.Tbl_Structure WHERE Hierarchy_ID.GetAncestor(1) = @Category_Hierarchy_ID); SET @Hierarchy_ID = @Category_Hierarchy_ID.GetDescendant(@last_chil d_Hierarchy_ID, NULL); END INSERT INTO dbo.Tbl_Structure(FunctionID, Hierarchy_ID, Functio nName) VALUES(@FunctionID, @Hierarchy_ID, @FunctionName); END GO
The following procedure inserts the Root and hierarchy node.
EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC EXEC
dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure dbo.usp_AddStructure
1, NULL,'Director' 2, 1, 'Project Manager - I' 4, 2, 'Project Lead - I' 5, 4, 'Team Lead - I' 6, 5, 'Application Developer - IA' 7, 5, 'Application Developer - IIA' 8, 5, 'Application Developer - IIIA' 9, 5, 'SQL Developer - IA' 3, 1, 'Project Manager - II' 10,3, 'Project Lead - II' 11,10, 'Team Lead - II' 12,11, 'Application Developer - IB' 13,11, 'Application Developer - IIB' 14,11, 'Application Developer - IIIB' 15,11, 'SQL Developer - IB'
SELECT REPLICATE(' |..', Hierarchy_Level) + FunctionName AS FunctionName, Hierarchy_ID.ToString() AS path FROM dbo.Tbl_Structure ORDER BY Hierarchy_ID;
Result Director |..Project Manager - I |.. |..Project Lead - I |.. |.. |..Team Lead - I |.. |.. |.. |..Application Developer - IA |.. |.. |.. |..Application Developer - IIA |.. |.. |.. |..Application Developer - IIIA
|.. |.. |.. |..SQL Developer - IA |..Project Manager - II |.. |..Project Lead - II |.. |.. |..Team Lead - II |.. |.. |.. |..Application Developer - IB |.. |.. |.. |..Application Developer - IIB |.. |.. |.. |..Application Developer - IIIB |.. |.. |.. |..SQL Developer - IB
DECLARE @tblValue Typ_Sample INSERT @tblValue VALUES (1,'Aequea'), (2,'Salino'), (3,'Calcalino'), (4,'Setaceo'), (5,'Socaprio'), (6,'Alumino'), (7,'Vitriolic') SELECT * FROM @tblValue
8. Table-Values parameters :
We can use table type parameters as an Input for Stored procedure and Functions. The Table value parameter is Read-Only, So we have to define as READONLY. But, In previous version of SQL Servers, We have to use some special character value to separate the bulk values, XML type data and we have to use Split function inside the Stored procedure and functions. Using the XML, separated value is non-relational and It will produce the SQL Injection and It will not provide the effective plan for re-use the optimizer. In SQL Server 2008, By using the table value parameter we can avoid the SQL Injection We created a table with data
IF OBJECT_ID('Tbl_One','U') IS NOT NULL DROP TABLE Tbl_One GO CREATE TABLE Tbl_One ( ID INT, COL1 VARCHAR(50) ) GO INSERT Tbl_One VALUES (1,'Table'), (2,'View'), (3,'Stored Procedure'), (4,'Trigger'), (5,'Cursor') GO
Creating Table type for the actual table
IF NOT EXISTS(SELECT 1 FROM SYS.TYPES WHERE [NAME] = 'Typ_One') CREATE TYPE Typ_One AS TABLE ( ID INT ) GO
We have created a Stored procedure with table value type parameter
IF OBJECT_ID('USP_GetData','P') IS NOT NULL DROP PROC USP_GetData GO CREATE PROC USP_GetData ( @IDs AS Typ_One READONLY )AS BEGIN SET NOCOUNT ON SELECT ID, Col1 FROM Tbl_One WHERE ID IN(SELECT ID FROM @IDs) END
Accessing the stored procedure
We have created one variable : @Para for table type : Typ_One and Inserting 3 values. The table value parameter passed as an Input to the Stored procedure and inside the procedure will perform based on the table value parameters value.
If we not inserting and passing any data to the table value parameter, The parameter will have empty table structure without any data. But We cannot set the table value parameter as NULL.
9. MERGE Statement
The Merge statement is used to perform INSERT, UPDATE & DELETE operations as a single based on condition. The Merge operation is better when comparing with individual operations. The Merge statement uses two tables (Source and Target tables). The Source table is specified with USING clause. The Target table is specified with MERGE INTO clause. Merge statement is similar to OUTER joins. We can use condition with Merge statement like WHEN MATCHED THEN, WHEN NOT MATCHED [BY TARGET] THEN , WHEN NOT MATCHED BY SOURCE THEN. If the record is already there in target table then we can update the data, If its not there in target table then we an insert. The OUTPUT clause can be used with Merge statement to return an output as INSERTED / DELETED like magic tables. We can use $action function to identity that what kind of action taken place like INSERT / UPDATE / DELETE. We can synchronize the difference on tables (source / target) by INSERT/UPDATE/DELETE operations. The Merge statement comprises Five clauses
1. 2. 3. 4.
MERGE - Used to specify the Target tables to be inserted/updated/deleted. USING - Used to specify the Source table. ON - Used to specify the join condition on source and target tables. WHEN - Used to specify the action to be taken place based on the result of the ON clause. 5. OUTPUT - Used to return the value of Insert/Update/Delete operations using the INSERTED / DELETED magic tables.
USE master GO
Creating a table named : TB_SAMPLE1 :
INSERT TB_SAMPLE1 VALUES (1,'Aequea',1000), (2,'Salino',2000), (1,'Calcalino',3000), (3,'Setaceo',4000), (4,'Socaprio',5000), (4,'Alumino',6000), (5,'Vitriolic',7000) GO
(7 row(s) affected)
IF OBJECT_ID('TB_SAMPLE2','U') IS NOT NULL DROP TABLE TB_SAMPLE2 GO CREATE TABLE TB_SAMPLE2 ( ID INT , TOTAL INT ) GO
Command(s) completed successfully.
GO
Inserting the Unmatched record from the TB_SAMPLE1 table to TB_SAMPLE2 : (Without MERGE)
INSERT TB_SAMPLE2 SELECT SOURCE.* FROM (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE LEFT J OIN TB_SAMPLE2 [TARGET] ON (SOURCE.ID = [TARGET].ID) WHERE [TARGET].ID IS NULL GO SELECT * FROM TB_SAMPLE2 GO
Inserting the Unmatched record from the TB_SAMPLE1 table to TB_SAMPLE2 : (Without MERGE + OUTPUT Clause)
INSERT TB_SAMPLE2 OUTPUT Inserted.* SELECT SOURCE.* FROM (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE LEFT J OIN TB_SAMPLE2 [TARGET] ON (SOURCE.ID = [TARGET].ID) WHERE [TARGET].ID IS NULL GO SELECT * FROM TB_SAMPLE2 GO
Inserting the Unmatched record from the TB_SAMPLE1 table to TB_SAMPLE2 : (With MERGE)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN NOT MATCHED BY TARGET THEN INSERT VALUES(SOURCE.ID, SOURCE.AMOUNT); GO SELECT * FROM TB_SAMPLE2 GO
Inserting the Unmatched record from the TB_SAMPLE1 table to TB_SAMPLE2 : (With MERGE + OUTPUT Clause)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN NOT MATCHED BY TARGET THEN INSERT VALUES(SOURCE.ID, SOURCE.AMOUNT) OUTPUT Inserted.*; GO SELECT * FROM TB_SAMPLE2 GO
Update SUM of amount from TB_SAMPLE1 to TB_SAMPLE2 comparing with ID from the both table : (Without MERGE)
UPDATE [TARGET] SET [TARGET].TOTAL = SOURCE.AMOUNT FROM ( SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID )AS SOURCE, TB_SAMPLE2 [TARGET] WHERE SOURCE.ID = [TARGET].ID GO SELECT * FROM TB_SAMPLE2 GO
Update SUM of amount from TB_SAMPLE1 to TB_SAMPLE2 comparing with ID from the both table : (Without MERGE + OUTPUT Clause)
UPDATE [TARGET] SET [TARGET].TOTAL = SOURCE.AMOUNT OUTPUT Inserted.*, Dele ted.* FROM ( SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID )AS SOURCE, TB_SAMPLE2 [TARGET] WHERE SOURCE.ID = [TARGET].ID GO SELECT * FROM TB_SAMPLE2 GO
Note: When we update the data, The already existing record will be there in DELETED magic table, The Updated record will be there in INSERTED magic table. Update SUM of amount from TB_SAMPLE1 to TB_SAMPLE2 comparing with ID from the both table : (With MERGE)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN MATCHED THEN UPDATE SET TARGET.TOTAL = SOURCE.AMOUNT; GO SELECT * FROM TB_SAMPLE2 GO
Update SUM of amount from TB_SAMPLE1 to TB_SAMPLE2 comparing with ID from the both table : (With MERGE + OUTPUT Clause)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN MATCHED THEN UPDATE SET TARGET.TOTAL = SOURCE.AMOUNT OUTPUT Inserted.*, Deleted.*; GO SELECT * FROM TB_SAMPLE2 GO
Deleting the Unmatched record from the TB_SAMPLE2 table : (Without MERGE)
DELETE [TARGET] FROM TB_SAMPLE2 [TARGET] LEFT JOIN TB_SAMPLE1 [SOURCE] ON ([SOURCE].ID = [TARGET].ID) WHERE [SOURCE].ID IS NULL GO SELECT * FROM TB_SAMPLE2 GO
Deleting the Unmatched record from the TB_SAMPLE2 table : (Without MERGE + OUTPUT Clause)
DELETE [TARGET] OUTPUT Deleted.* FROM TB_SAMPLE2 [TARGET] LEFT JOIN TB_SAMPLE1 [SOURCE] ON ([SOURCE].ID = [TARGET].ID) WHERE [SOURCE].ID IS NULL GO SELECT * FROM TB_SAMPLE2 GO
Deleting the Unmatched record from the TB_SAMPLE2 table : (With MERGE)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN NOT MATCHED BY SOURCE THEN DELETE; GO SELECT * FROM TB_SAMPLE2 GO
Deleting the Unmatched record from the TB_SAMPLE2 table : (With MERGE + OUTPUT Clause)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN NOT MATCHED BY SOURCE THEN DELETE OUTPUT Deleted.*; GO SELECT * FROM TB_SAMPLE2 GO
Inserting, Updating & Deleting the record from the TB_SAMPLE2 table : (With MERGE + OUTPUT Clause We can use $Action to identity that what kind of action taken place (Insert, Update, Delete)
MERGE TB_SAMPLE2 AS TARGET USING (SELECT ID,SUM(AMOUNT) AMOUNT FROM TB_SAMPLE1 GROUP BY ID) AS SOURCE ON (TARGET.ID = SOURCE.ID) WHEN NOT MATCHED BY TARGET THEN INSERT VALUES(SOURCE.ID, SOURCE.AMOUNT) WHEN MATCHED THEN UPDATE SET TARGET.TOTAL = SOURCE.AMOUNT WHEN NOT MATCHED BY SOURCE THEN DELETE OUTPUT $Action, Inserted.*,Deleted.*; GO SELECT * FROM TB_SAMPLE2 GO
USE master GO IF OBJECT_ID('TB_SAMPLE1','U') IS NOT NULL DROP TABLE TB_SAMPLE1 GO CREATE TABLE TB_SAMPLE1 ( ID INT IDENTITY, FunctionCategory VARCHAR(100), FunctionName VARCHAR(100) ) GO INSERT TB_SAMPLE1(FunctionCategory,FunctionName) VALUES ('Aggregate Functions','AVG'), ('Aggregate Functions','MIN'), ('Aggregate Functions','CHECKSUM_AGG'), ('Aggregate Functions','SUM'), ('Aggregate Functions','COUNT'), ('Aggregate Functions','STDEV'), ('Aggregate Functions','COUNT_BIG'), ('Aggregate Functions','STDEVP'), ('Aggregate Functions','GROUPING'), ('Aggregate Functions','VAR'), ('Aggregate Functions','MAX'), ('Aggregate Functions','VARP'), ('Configuration Functions','@@DATEFIRST'), ('Configuration Functions','@@OPTIONS'), ('Configuration Functions','@@DBTS'), ('Configuration Functions','@@REMSERVER'), ('Configuration Functions','@@LANGID'), ('Configuration Functions','@@SERVERNAME'), ('Configuration Functions','@@LANGUAGE'), ('Configuration Functions','@@SERVICENAME'), ('Configuration Functions','@@LOCK_TIMEOUT'), ('Configuration Functions','@@SPID'),
('Configuration Functions','@@MAX_CONNECTIONS'), ('Configuration Functions','@@TEXTSIZE'), ('Configuration Functions','@@MAX_PRECISION'), ('Configuration Functions','@@VERSION'), ('Configuration Functions','@@NESTLEVEL'), ('Cryptographic Functions','EncryptByKey'), ('Cryptographic Functions','DecryptByKey'), ('Cryptographic Functions','EncryptByPassPhrase'), ('Cryptographic Functions','DecryptByPassPhrase'), ('Cryptographic Functions','Key_ID'), ('Cryptographic Functions','Key_GUID'), ('Cryptographic Functions','EncryptByAsmKey'), ('Cryptographic Functions','DecryptByAsmKey'), ('Cryptographic Functions','EncryptByCert'), ('Cryptographic Functions','DecryptByCert'), ('Cryptographic Functions','Cert_ID'), ('Cryptographic Functions','AsymKey_ID'), ('Cryptographic Functions','CertProperty'), ('Cryptographic Functions','SignByAsymKey'), ('Cryptographic Functions','VerifySignedByAsmKey'), ('Cryptographic Functions','SignByCert'), ('Cryptographic Functions','VerifySignedByCert'), ('Cryptographic Functions','DecryptByKeyAutoCert'), ('Cursor Functions','@@CURSOR_ROWS'), ('Cursor Functions','CURSOR_STATUS'), ('Cursor Functions','@@FETCH_STATUS'), ('Ranking Functions','RANK'), ('Ranking Functions','NTILE'), ('Ranking Functions','DENSE_RANK'), ('Ranking Functions','ROW_NUMBER') GO
Fetching No. of functions inside the each category :
Fetching No. of functions with starting characters inside the each category :
If we need the both result set as a whole, We have to use UNION ALL :
SELECT
GROUP BY FunctionCategory UNION ALL SELECT SUBSTRING(FunctionCategory,1,1) FunctionCategory, COUNT(1) 'Counts' FROM TB_SAMPLE1 GROUP BY SUBSTRING(FunctionCategory,1,1) GO
Is there any way to combine the two result set to single without using UNION ALL :
SELECT GROUPING_ID(FunctionCategory,[First Character Wise]) 'Grouping', FunctionCategory,[First Character Wise], COUNT(1) 'Counts' FROM ( SELECT FunctionCategory, SUBSTRING(FunctionCategory,1,1) 'First Character Wise' FROM TB_SAMPLE1 )AS SubQuery GROUP BY GROUPING SETS ( (SubQuery.FunctionCategory), (SubQuery.[First Character Wise]) ) GO
IF EXISTS(SELECT * FROM sys.triggers WHERE [name] ='Trg_Rename') DROP TRIGGER Trg_Rename ON DATABASE GO CREATE TRIGGER Trg_Rename ON DATABASE FOR RENAME AS BEGIN DECLARE @SchemaName AS SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname') , @TargetObjectName AS SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'sys name'), @ObjectName AS SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname') , @NewObjectName AS SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/NewObjectName)[1]', 'sysnam e'); DECLARE @msg AS NVARCHAR(1000) = N'RENAME event occurred. SchemaName: ' + @SchemaName + N' TargetObjectName: ' + @TargetObjectName + N' ObjectName: ' + @ObjectName + N' NewObjectName: ' + @NewObjectName; PRINT @msg; END GO
Creating a Table : Tb_Table1 :
sp_rename 't1.col1','col2','column'
When we try to rename a column of table (or) name of a table the trigger fires. The following are the system stored procedures which triggers in various EVENTS (ie: Rename)
IF OBJECT_ID('Tb_Table2','U') IS NOT NULL DROP TABLE Tb_Table2 GO CREATE TABLE Tb_Table2 ( ID INT,
COL1 COL2 ) GO
DECLARE @I INT = 1 WHILE(@I <= 100000) BEGIN INSERT Tb_Table2(ID, COL1) VALUES (@i,'DotnetFunda' + CAST(@I AS VARCHAR)) SELECT @I += 1 END GO
Validating the space allocated and used :
SP_SPACEUSED Tb_Table2
Inserting some amount of data into a table : Tb_Table1 ( With SPARSE column ) We have created one table with SPARSE definition and inserted 100000 rows.
IF OBJECT_ID('Tb_Table1','U') IS NOT NULL DROP TABLE Tb_Table1 GO CREATE TABLE Tb_Table1 ( ID INT, COL1 VARCHAR(50), COL2 CHAR(4000) SPARSE NULL ) GO DECLARE @I INT = 1 WHILE(@I <= 100000) BEGIN INSERT Tb_Table1(ID, COL1) VALUES (@i,'DotnetFunda' + CAST(@I AS VARCHAR)) SELECT @I += 1 END GO
Validating the space allocated and used :
SP_SPACEUSED Tb_Table1
Microsoft Books Online : Restrictions for using Sparse columns : 1. A sparse column must be NULLable and cannot have the ROWGUIDCOL or IDENTITY properties. 2. A sparse column cannot be of the following data types: text, ntext, image, timestamp, userdefined data type, geometry, or geography; or have the FILESTREAM attribute. 3. A sparse column cannot be bound to a rule, default value 4. Computed column can contain a sparse column. But it cannot be marked as SPARSE. 5. A sparse column cannot be part of a clustered index or a unique primary key index. 6. A sparse column cannot be used as a partition key of a clustered index or heap. However, a sparse column can be used as the partition key of a nonclustered index. 7. A sparse column cannot be part of a user-defined table type, which are used in table variables and table-valued parameters. 8. Using sparse columns reduces the maximum size of a row from 8,060 bytes to 8,018 bytes. 9. Adding or removing a sparse column can fail when the row size is near 4,009 bytes. When an existing table is modified to add the first sparse column, the rows are modified by making a copy of them on the data page and then deleting the original row. Rows that are larger than 4,009 bytes cannot be written to the page while the existing row is present. This causes the addition of the column to fail. 10. The same problem exists when the last sparse column is removed from the table. If any rows have more than 4,009 bytes, the removal of the column will fail. This restriction does not apply to new tables that contain no data. 11. To change the rows in a table in which the data exceeds 4,009 bytes per row, create a new table, and transfer the data into the new table. Then, either delete the original table and rename the new table; or truncate the original table, modify the rows in the original table, and then move the data back into it. 12. When you change a nonsparse column to a sparse column, the sparse column will consume more space for nonnull values. When a row is close to the maximum row size limit, the operation can fail.
GO CREATE TABLE Tb_Table1 ( ID INT, COL1 VARCHAR(50), COL2 CHAR(4000) NULL ) GO DECLARE @I INT = 1 WHILE(@I <= 100000) BEGIN INSERT Tb_Table1(ID, COL1) VALUES (@i,'DotnetFunda' + CAST(@I AS VARCHAR)) SELECT @I += 1 END GO
Creating a Non-Clustered Filtered index :
IF OBJECT_ID('VW_VIEW1','V') IS NOT NULL DROP VIEW VW_VIEW1 GO CREATE VIEW VW_VIEW1 AS SELECT * FROM Tb_Sample GO
Creating Stored procedure references the View :
IF OBJECT_ID('USP_PROC2','P') IS NOT NULL DROP PROC USP_PROC2 GO CREATE PROC USP_PROC2 AS BEGIN SET NOCOUNT ON SELECT * FROM VW_VIEW1 END GO
Identifying the referencing objects :
CREATE DATABASE DotnetFunda GO USE DotnetFunda GO IF OBJECT_ID('Tb_cdcTable','U') IS NULL CREATE TABLE Tb_cdcTable ( ID INT, COL1 VARCHAR(50) ) GO
Recommendation : 1. The Database must be enabled for Change Data Capture : sys.sp_cdc_enable_db 2. SQL Server Agent must be running 3. Table must be enable which we want to capture the changes : sys.sp_cdc_enable_table 1. Enabling Change Data Capture for a Database :
EXEC sys.sp_cdc_enable_db
We can query and determine the CDC is already enabled by using the Is_CDC_Enabled column of Sys.Databases catalog view.
Once enable the Change Data Capture (CDC), Some system table will be created under current database.
2. Enabling Change Data Capture for a Table : Enabling Change data capture for a table : Tb_cdcTable
We can query and determine the CDC is already enabled by the column is_tracked_by_cdc of using SYS.tables the table catalog view
UPDATE Tb_cdcTable SET COL1 = 'SQL Server 2008 Enterprise Edition' WHERE id = 2 SELECT * FROM cdc.dbo_Tb_cdcTable_CT
UPDATE Tb_cdcTable SET COL1 = 'SQL Server 2008 DBA' WHERE id = 2 SELECT * FROM cdc.dbo_Tb_cdcTable_CT
The column _$operation indicates that what kind of operations taken place on the table.
16. Collations :
SQL Server 2008 adds new collations by finding the number 100 in their names.
Conclusion The new and enhanced features in SQL Server 2008 help you improve the performance of your database. Please let me know your feedback, if any on this article to improve it further. Thank you.