: +91-265-2775555
 : +1-856-831-0505
 : +44-788-443-25-28
 : +45-4052-3137
Prakash software blogs - software development,custom sharepoint,MOSS 2007,Telerik development,C#.net,sharepoint webparts > Tag Clouds
Sql server 2005: OUTPUT Clause

Sql server 2005: OUTPUT Clause

What:    OUTPUT Clause is used to return the rows affected by Insert, Update or Delete Statement on
             Sql table

Why:     to perform an action on the rows which are affected by any of the table manipulation statements
             i.e. Insert, Update and Delete.

Example: suppose, we have a requirement to maintain a log file after any operation on a table. Here             operation refers Insert, Update and Delete operation.

The role of an Output Clause comes here, Instead of using a trigger we could use the OUTPUT clause.

How:     For the example here uses a 2 tables:

1.       tblExternalFile: a parents Table

2.       tblExternalFileBackup : a Backup Table

Structures of these 2 tables are bellow:

1.       tblExternalFile

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE TABLE [dbo].[tblExternalFile](

                  [Id] [int] IDENTITY(1,1) NOT NULL,

                  [FileXml] [xml] NULL,

                  CONSTRAINT [PK_tblExternalFile] PRIMARY KEY CLUSTERED

                  (

                        [Id] ASC

                  )WITH (    

                        PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,

IGNORE_DUP_KEY = OFF,

                        ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON

                  ) ON [PRIMARY]

) ON [PRIMARY]

2.       tblExternalFileBackup

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

   CREATE TABLE [dbo].[tblExternalFileBackup](

         [Id] [int] IDENTITY(1,1) NOT NULL,

         [FileXml] [xml] NULL,

         CONSTRAINT [PK_tblExternalFileBackup] PRIMARY KEY CLUSTERED

         (

               [Id] ASC

         )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,

               IGNORE_DUP_KEY = OFF,

               ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON

   ) ON [PRIMARY]

 

Here both tables have same numbers of column,

 

OUTPUT clause with Insert:

                Here is a code that will automatically insert a new record in - tblExternalFileBackup
            table,whenever an insert operation fires on – tblExternalFile table.

            GO

            -- Create Temp Table variable

            DECLARE @MyTableVar table( Id int,

                                       FileXml xml,

                                       ModifiedDate smallDateTime);

 

            -- Insert Operation Fires on tblExternalFile

            INSERT tblExternalFile([FileXml])

                OUTPUT INSERTED.Id,INSERTED.FileXml,GetDate()

                    INTO @MyTableVar

                        VALUES (N'<DatabaseData                               xmlns=""><MappingMeta>123</MappingMeta></DatabaseData>');

 

            -- Insert a newly Added Record to tblExternalFileBackup

            INSERT INTO tblExternalFileBackup(FileXml)

                  SELECT FileXml FROM @MyTableVar

 

            --Display the result set of the table variable.

            SELECT * FROM tblExternalFileBackup;

      GO

OUTPUT clause with Delete:

                                DELETE FROM tblExternalFile

            OUTPUT DELETED.*

            WHERE ID=17

      All Deleted rows will be displayed whose Id is 17.

OUTPUT clause with Update:

                                -- Create Temp Table variable

            DECLARE @MyTableVar table( Id int,

                                       OldFileXml xml,

                                       NewFileXml xml,

                                       ModifiedDate smallDateTime);

 

            -- Update Operation

            UPDATE tblExternalFile

                  SET FileXml = '<Employee xmlns=""><ID>007</ID></Employee>'

                  OUTPUT INSERTED.Id,

                   DELETED.FileXml,

                   INSERTED.FileXml,

                   GETDATE()

            INTO @MyTableVar

            WHERE iD=17;

 

            -- Insert a newly Added/ Updated Record to tblExternalFileBackup

            INSERT INTO tblExternalFileBackup(FileXml)

                  SELECT FileXml FROM @MyTableVar

 

      SELECT * FROM tblExternalFileBackup

 

                @MyTableVar is a table Variable we use it to store the Updated records of a Table.
                            Here an Id Number ‘17’ will be updated with the New Xml String and new row will be
                            added in tblExternalFileBackup table.

Alternative of OUTPUT Clause:

                You can write a trigger on table to manage a log on a table. The benefits/ Limitation of
                            triggers over OUTPUT clause are not in the scope of this blog.

 

 

Ref. Site: http://msdn.microsoft.com/en-us/library/ms177564(SQL.90).aspx


Thanks,

Vivek Shah

SQL QUERY OPTIMIZATION

1.    Use Clustered Indexes

Having the clustered index on the primary key is sometimes not the most efficient place for the clustered index to be. A clustered index is the most performant type of index. The whole table is sorted according to the clustered index. If the table is involved in lots of joins based on the primary key, it is probably the USE place for it to be, but if you are continually filtering or grouping on other columns in a table, then you should possibly consider changing the primary key index to Non-Clustered, and putting the clustered index on those filtered or grouped columns.

The following statement removes and existing clustered index on the primary key and replaces it with a non-clustered index:

ALTER TABLE MySchema.SalesOrderHeaderDROP CONSTRAINT PK_SalesOrderHeader

GO

ALTER TABLE MySchema.SalesOrderHeaderADD CONSTRAINT PK_SalesOrderHeaderPRIMARY KEY NONCLUSTERED (SalesOrderID);

Then the following statement adds a new clustered index to a table.

CREATE CLUSTERED INDEX MyClusteredIndexON MySchema.SalesOrderHeader (OrderID)

2.    Use Indexed Views

 

Indexed Views have been around for a while. A view is like a named query, and these days you can add indexes to them. If used correctly, they can cause a massive improvement in execution times, often better than a clustered index with covering columns on the original table. Also, in SQL Server Developer Edition and Enterprise Edition, a view index will also be automatically used if it is the best index even if you don’t actually specify the view in your query!

 

CREATE VIEW MySchema.SalesByCustomer

WITH SCHEMABINDING

AS

SELECT

soh.SalesTerritoryID, soh.CustomerID,   SUM (sod.Quantity * sod.UnitPrice)

FROM

MySchema.SalesOrderHeader soh

INNER JOIN MySchema.SalesOrderDetail sod   ON (soh.SalesOrderID = sod.SalesOrderID)

GROUP BY

soh.SalesOrderTerritory, soh.CustomerID

Note the use of the schema binding attribute. This prevents you from changing underlying tables while this view exists, and is necessary if you want to add an index. Some people avoid indexed views for this reason, as the maintenance becomes more complicated as further dependencies to the view are created. The following statement adds an index:

CREATE UNIQUE CLUSTERED INDEX IdxSalesOrderView ON MySchema.SalesByCustomer (   SalesTerritoryID, CustomerID   )

Use Indexed Views (SCHEMABINDING cannot be specified if the view contains alias data type columns)

3.    Use Covering Indexes

Covering indexes are a feature that was newly added to SQL 2005. Basically, you can create an index optimized for the query itself based on joins, filters and grouping, and then add additional columns that can be retrieved directly from the index for use in select statements, as follows:

CREATE NONCLUSTERED INDEX TestIndex  

ON MySchema.SalesOrderDetail (OrderId) INCLUDE (Quantity, UnitPrice)

The above statement causes a non-clustered index to be created on the SalesOrderDetail table. If queries are executed on the OrderId column, the index will be used, and if the only other columns being retrieved are Quantity and UnitPrice, then the query optimizer doesn’t need to retrieve any extra columns from the underlying table. It can just use the index. Because the query optimizer doesn’t need to query the original table, performance is improved. 

4.    Restrict the queries result set

Try to restrict the queries result set by returning only the particular columns from the table, not all table's columns.

5.    Use views and stored procedures

This can reduce network traffic, because your client will send to server only stored procedure or view name (perhaps with some parameters) instead of large heavy-duty queries text. This can be used to facilitate permission management also, because you can restrict user access to table columns they should not see.

6.    Avoid using cursors, whenever possible.

SQL Server cursors can result in some performance degradation in comparison with select statements. Try to use correlated sub query or derived tables, if you need to perform row-by-row operations.

7.    Use constraints instead of triggers.

Constraints are much more efficient than triggers and can boost performance. So, you should use constraints instead of triggers, whenever possible.

8.    Use table variables instead of temporary tables.

Table variables require less locking and logging resources than temporary tables, so table variables should be used whenever possible.

9.    Include SET NOCOUNT ON

This can reduce network traffic, because your client will not receive the message indicating the number of rows affected by a T-SQL statement.

Include SET NOCOUNT ON statement into your stored procedures to stop the message indicating the number of rows affected by a T-SQL statement.

10. use UNION ALL statement instead of UNION

 

The UNION ALL statement is much faster than UNION, because UNION ALL statement does not look for duplicate rows, and UNION statement does look for duplicate rows, whether or not they exist.

 

11. Avoid data type mismatch for index columns

AVOID

Select

barcode, price

From

products

Where

barcode = 5467;

          USE

Select

barcode, price

From

products

Where

barcode = ‘5467’;

          barcode is a type of CHAR (10)

12. Index Usage and Functions

AVOID

Select COUNT (*)

From products

Where SUBSTR (brand, 1, 3) =’Arr’;

USE

Select COUNT (*)

From products

Where brand like =’Arr%’;

The reason why application of a function renders the index seek operation useless is because the index pages do not store the data after the application of that function and thus the optimizer cannot perform a seek operation.

13. Composite Index

 

AVOID

 

Select

count (*)

From

products

Where

price < 1000

 

USE

Select

count (*)

From

products

Where

brand > ‘0’ AND price < 1000

 

Ensure all columns are specified when using composite index

14. Group By, Having

 

AVOID

 

Select brand, SUM (price)

From products

Group by brand

Having brand = ‘Arrow’

 

USE

 

Select brand, SUM (price)

From products

Where brand = ‘Arrow’

Group by brand

 

Move conditions from having clause to where clause

 

15. Nested Selects

 

AVOID

 

Select

COUNT (*)

From

products

Where

itemcode IN (

Select

itemcode

 from

clothing

 where

material = ‘Cotton’

)

USE

 

SELECT

          COUNT (*)

FROM

          PRODUCTS P

          INNER JOIN CLOTHING C

          ON P.BARCODE = C.BARCODE

          AND C.MATERIAL = 'Cotton'

 

Use joins instead of nested selects, whenever possible

 

16. Multi table join

AVOID

SELECT

          COUNT (*)

FROM

          T-SHIRT T

          INNER JOIN SHIRTS S

          ON T.BARCODE = S.BARCODE

          INNER JOIN CLOTHING C

          ON S.BARCODE = C.BARCODE

          INNER JOIN PRODCUT P

          ON C.BARCODE = P.BARCODE

 

USE

 

SELECT

          COUNT (*)

FROM

          PRODUCTS P

          INNER JOIN CLOTHING C

          ON P.BARCODE = C.BARCODE

          INNER JOIN SHIRTS S

          ON C.BARCODE = S.BARCODE

          INNER JOIN T-SHIRT T

          ON S.BARCODE = T.BARCODE

 

When joining multiple tables the smallest table should be specified last

 

17. NOT IN

AVOID

Select

count (*)

From

Products

Where

barcode NOT IN (

Select

barcode

  From

Clothing

      )

USE

Select

COUNT (*)

 From

Produ cts P

 Where

NOT EXISTS (

Select

C.barcode

 From

Clothing C

 Where

C.barcode = P.barcode

)

Replace NOT IN by NOT EXISTS

18. NOT EQUAL TO

 

AVOID

 

SELECT

          P.BRAND

FROM

          PRODUCTS P

          INNER JOIN CLOTHING C

          ON P.BARCODE = C.BARCODE

          INNER JOIN SHIRT S

          ON C.BARCODE = S.BARCODE

WHERE

          C.MATERIAL! ='COTTON’

          USE

SELECT

          P.BRAND

FROM

          PRODUCTS P

          INNER JOIN CLOTHING C

          ON P.BARCODE = C.BARCODE

          INNER JOIN SHIRT S

          ON C.BARCODE = S.BARCODE

WHERE

          C.MATERIAL < 'COTTON'

UNION

SELECT

          P.BRAND

FROM

          PRODUCTS P

          INNER JOIN CLOTHING C

          ON P.BARCODE = C.BARCODE

          INNER JOIN SHIRT S

          ON C.BARCODE = S.BARCODE

WHERE

          C.MATERIAL > 'COTTON’

Replace “! =” by Union of “<” and “> “

 

19. COUNT(*)

 

AVOID

 

Select

COUNT (*)

From

PRODUCTS

          USE

SELECT

TOP 1 ROWS

FROM

SYSINDEXES

WHERE

ID = OBJECT_ID('PRODUCT') AND INDID < 2

 

 

 

T-SQL: The difference between @@identity, scope_identity(), and ident_current()

First of all, when discussing the three methods, you need to understand two concepts: session and scope. Session means the current connection that's executing the command. Scope means the immediate context of a command. Every stored procedure call executes in its own scope, and nested calls execute in a nested scope within the calling procedure's scope. Likewise, a SQL command executed from an application or SSMS executes in its own scope, and if that command fires any triggers, each trigger executes within its own nested scope.

Now that these two concepts are defined, here are the differences between the three identity retrieval methods:

  • @@identity returns the last identity value generated in this session but any scope
  • scope_identity() returns the last identity value generated in this session and this scope
  • ident_current() returns the last identity value generated for a particular table in any session and any scope

To illustrate, imagine the following scenario: You execute an insert command on a Customer table, which fires an insert trigger that inserts a default Order for that customer in the Order table. Immediately after, before you execute another command, another session does the same thing.

  • @@identity will return the identity value of the Order table, because the trigger on the Customer table executes after the insert into the Customer table, so the Order identity is the last identity generated in your session but any scope.
  • scope_identity() will return the identify value of the row you inserted into the Customer table, because that's the last identity value generated at this level of scope in your session
  • ident_current( Customer ) and ident_current( Order ) will return the identity of the rows inserted by the other session.

For most scenarios most of the time, what you will want is the value returned by scope_identity().

The Baker's Dozen: 13 Tips for SQL Server 2008 and SSRS 2008
Follow the link below to have some quick look at SQL 2008 and Reporting Services.
 
 
Highlight:
 
SQL Server 2008 includes a new and completely re-written version of SQL Server Reporting Services (SSRS)—complete with a new interface, new charting features, and (get ready to applaud) no more reliance on Internet Information Services (IIS).
Courtesy: SQLServerCentral.com