Pages

Tuesday, October 11, 2011

Calculate the Day You Were Born.


This simple day born javascript calculates the day you were born from the date that you supply. Very useful script which is easy to install. 2 step copy and paste installation with nothing at all to alter.
STEP 1
Copy and paste the script below and place this into the <head> of your html document.


<SCRIPT LANGUAGE="JavaScript"> 
<!-- Distributed by Hypergurl http://www.hypergurl.com --> <!-- Begin 
function calculate() { month = document.form.month.selectedIndex; month = document.form.month.options[month].value; 
day = document.form.day.selectedIndex; day = document.form.day.options[day].value; 
year = document.form.year.value; var oyear=year var dob = " "+ year 
+", "+month + ", "+day; var thenx = new Date(dob); var year=thenx.getYear(); 
if (year<100) year="19" + thenx.getYear(); else year=thenx.getYear(); 
if (year > 1969) wyear=year; else { if (oyear<1900) { if (oyear>1800) 
{ wrelyear= (eval(oyear)-1801)%(28); wyear = wrelyear+1981; } else wyear = 1970 
} else if (oyear>1900) {wrelyear= (eval(oyear)-1901)%(28); wyear= wrelyear+1985 
} else if (oyear==1900) {wyear= 1990; } } var dob = " "+ wyear +", 
"+month + ", "+day; var thenx = new Date(dob); var theday = thenx.getDay()+1; 
var date=thenx.getDate(); var weekday = new Array(6); weekday[1]="Sunday"; 
weekday[2]="Monday"; weekday[3]="Tuesday"; weekday[4]="Wednesday"; 
weekday[5]="Thursday"; weekday[6]="Friday"; weekday[7]="Saturday"; 
if (day != date) alert("Sorry! That appears to be an invalid date!"+day+" 
..."+date+"::"+oyear+"..."+year+" "+dob+"=="+wyear+".-.-"+thenx+" 
"+day+" "+month); else { dayborn = weekday[theday]; dob = dayborn 
+ ", " + month + " " + date + ", " + oyear + "."; 
alert("You were born on " + dob); } } // End --> </script>





STEP 2
Copy and paste the script below and place this into the <body> of your html document where you want the form to appear.



<form 
name=form> <center> <table border=2 cellspacing=0 cellpadding=0 bgcolor=white> 
<tr><td colspan=3 align=center><font face="verdana, arial" 
size="-1">When were you born?</font></td></tr> 
<tr><td align=center> <select name="month"> <option 
value="" selected>Month <option value="January">Jan 
<option value="February">Feb <option value="March">Mar 
<option value="April">Apr <option value="May">May 
<option value="June">Jun <option value="July">Jul 
<option value="August">Aug <option value="September">Sep 
<option value="October">Oct <option value="November">Nov 
<option value="December">Dec </select> </td> <td 
align=center> <select name="day"> <option value="" 
selected>Day <option value="1">01 <option value="2">02 
<option value="3">03 <option value="4">04 <option 
value="5">05 <option value="6">06 <option value="7">07 
<option value="8">08 <option value="9">09 <option 
value="10">10 <option value="11">11 <option value="12">12 
<option value="13">13 <option value="14">14 <option 
value="15">15 <option value="16">16 <option value="17">17 
<option value="18">18 <option value="19">19 <option 
value="20">20 <option value="21">21 <option value="22">22 
<option value="23">23 <option value="24">24 <option 
value="25">25 <option value="26">26 <option value="27">27 
<option value="28">28 <option value="29">29 <option 
value="30">30 <option value="31">31 </select> 
</td> <td align=center> <input type=text name=year value="19" 
size=4 maxlength=4> </td></tr> </table><p> <input 
type=button value="Calculate" onClick="calculate()"> </center> 
</form> 



Code to find out the statement that caused the trigger to fire!

Sometimes you may want to find out what exact statement that updated your table. Or you may want to find out how the WHERE clause of the DELETE statement (Executed by someone) looked like.

DBCC INPUTBUFFER can provide you with this kind of information. You can create a trigger on your table, that uses DBCC INPUTBUFFER command to find out the exact command that caused the trigger to fire.

The following trigger code works in SQL Sever 2000 (In SQL Server 7.0, you can't create tables inside a trigger. So, you'll have to create a permanent table before hand and use that inside the trigger). This code only displays the SQL statement, login name, user name and current time, but you can alter the code, so that this information gets logged in a table for tracking/auditing purposes.


CREATE TRIGGER TriggerName
ON TableName
FOR INSERT, UPDATE, DELETE AS
BEGIN
SET NOCOUNT ON

DECLARE @ExecStr varchar(50), @Qry nvarchar(255)

CREATE TABLE #inputbuffer
(
EventType nvarchar(30),
Parameters int,
EventInfo nvarchar(255)
)

SET @ExecStr = 'DBCC INPUTBUFFER(' + STR(@@SPID) + ')'

INSERT INTO #inputbuffer
EXEC (@ExecStr)

SET @Qry = (SELECT EventInfo FROM #inputbuffer)

SELECT @Qry AS 'Query that fired the trigger',
SYSTEM_USER as LoginName,
USER AS UserName,
CURRENT_TIMESTAMP AS CurrentTime
END
From the above code, replace the TableName and TriggerName with your table name and trigger name respectively and you can test the trigger by creating the trigger first and then by inserting/updating/deleting data.

Procedure to script your data (to generate INSERT statements from the existing data)

This procedure generates INSERT statements using existing data from the given tables and views. Later, you can use these INSERT statements to generate the data. It's very useful when you have to ship or package a database application. This procedure also comes in handy when you have to send sample data to your vendor or technical support provider for troubleshooting purposes.


SET NOCOUNT ON
GO

PRINT 'Using Master database'
USE master
GO

PRINT 'Checking for the existence of this procedure'
IF (SELECT OBJECT_ID('sp_generate_inserts','P')) IS NOT NULL --means, the procedure already exists
BEGIN
PRINT 'Procedure already exists. So, dropping it'
DROP PROC sp_generate_inserts
END
GO

--Turn system object marking on
EXEC master.dbo.sp_MS_upd_sysobj_category 1
GO

CREATE PROC sp_generate_inserts
(
@table_name varchar(776), -- The table/view for which the INSERT statements will be generated using the existing data
@target_table varchar(776) = NULL, -- Use this parameter to specify a different table name into which the data will be inserted
@include_column_list bit = 1, -- Use this parameter to include/ommit column list in the generated INSERT statement
@from varchar(800) = NULL, -- Use this parameter to filter the rows based on a filter condition (using WHERE)
@include_timestamp bit = 0, -- Specify 1 for this parameter, if you want to include the TIMESTAMP/ROWVERSION column's data in the INSERT statement
@debug_mode bit = 0, -- If @debug_mode is set to 1, the SQL statements constructed by this procedure will be printed for later examination
@owner varchar(64) = NULL, -- Use this parameter if you are not the owner of the table
@ommit_images bit = 0, -- Use this parameter to generate INSERT statements by omitting the 'image' columns
@ommit_identity bit = 0, -- Use this parameter to ommit the identity columns
@top int = NULL, -- Use this parameter to generate INSERT statements only for the TOP n rows
@cols_to_include varchar(8000) = NULL, -- List of columns to be included in the INSERT statement
@cols_to_exclude varchar(8000) = NULL, -- List of columns to be excluded from the INSERT statement
@disable_constraints bit = 0, -- When 1, disables foreign key constraints and enables them after the INSERT statements
@ommit_computed_cols bit = 0 -- When 1, computed columns will not be included in the INSERT statement

)
AS
BEGIN

/***********************************************************************************************************
Procedure: sp_generate_inserts (Build 22)
(Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.)

Purpose: To generate INSERT statements from existing data.
These INSERTS can be executed to regenerate the data at some other location.
This procedure is also useful to create a database setup, where in you can
script your data along with your table definitions.

Written by: Narayana Vyas Kondreddi
http://vyaskn.tripod.com

Acknowledgements:
Divya Kalra -- For beta testing
Mark Charsley -- For reporting a problem with scripting uniqueidentifier columns with NULL values
Artur Zeygman -- For helping me simplify a bit of code for handling non-dbo owned tables
Joris Laperre -- For reporting a regression bug in handling text/ntext columns

Tested on: SQL Server 7.0 and SQL Server 2000

Date created: January 17th 2001 21:52 GMT

Date modified: May 1st 2002 19:50 GMT

Email: vyaskn@hotmail.com

NOTE: This procedure may not work with tables with too many columns.
Results can be unpredictable with huge text columns or SQL Server 2000's sql_variant data types
Whenever possible, Use @include_column_list parameter to ommit column list in the INSERT statement, for better results
IMPORTANT: This procedure is not tested with internation data (Extended characters or Unicode). If needed
you might want to convert the datatypes of character variables in this procedure to their respective unicode counterparts
like nchar and nvarchar


Example 1: To generate INSERT statements for table 'titles':

EXEC sp_generate_inserts 'titles'

Example 2: To ommit the column list in the INSERT statement: (Column list is included by default)
IMPORTANT: If you have too many columns, you are advised to ommit column list, as shown below,
to avoid erroneous results

EXEC sp_generate_inserts 'titles', @include_column_list = 0

Example 3: To generate INSERT statements for 'titlesCopy' table from 'titles' table:

EXEC sp_generate_inserts 'titles', 'titlesCopy'

Example 4: To generate INSERT statements for 'titles' table for only those titles
which contain the word 'Computer' in them:
NOTE: Do not complicate the FROM or WHERE clause here. It's assumed that you are good with T-SQL if you are using this parameter

EXEC sp_generate_inserts 'titles', @from = "from titles where title like '%Computer%'"

Example 5: To specify that you want to include TIMESTAMP column's data as well in the INSERT statement:
(By default TIMESTAMP column's data is not scripted)

EXEC sp_generate_inserts 'titles', @include_timestamp = 1

Example 6: To print the debug information:

EXEC sp_generate_inserts 'titles', @debug_mode = 1

Example 7: If you are not the owner of the table, use @owner parameter to specify the owner name
To use this option, you must have SELECT permissions on that table

EXEC sp_generate_inserts Nickstable, @owner = 'Nick'

Example 8: To generate INSERT statements for the rest of the columns excluding images
When using this otion, DO NOT set @include_column_list parameter to 0.

EXEC sp_generate_inserts imgtable, @ommit_images = 1

Example 9: To generate INSERT statements excluding (ommiting) IDENTITY columns:
(By default IDENTITY columns are included in the INSERT statement)

EXEC sp_generate_inserts mytable, @ommit_identity = 1

Example 10: To generate INSERT statements for the TOP 10 rows in the table:

EXEC sp_generate_inserts mytable, @top = 10

Example 11: To generate INSERT statements with only those columns you want:

EXEC sp_generate_inserts titles, @cols_to_include = "'title','title_id','au_id'"

Example 12: To generate INSERT statements by omitting certain columns:

EXEC sp_generate_inserts titles, @cols_to_exclude = "'title','title_id','au_id'"

Example 13: To avoid checking the foreign key constraints while loading data with INSERT statements:

EXEC sp_generate_inserts titles, @disable_constraints = 1

Example 14: To exclude computed columns from the INSERT statement:
EXEC sp_generate_inserts MyTable, @ommit_computed_cols = 1
***********************************************************************************************************/

SET NOCOUNT ON

--Making sure user only uses either @cols_to_include or @cols_to_exclude
IF ((@cols_to_include IS NOT NULL) AND (@cols_to_exclude IS NOT NULL))
BEGIN
RAISERROR('Use either @cols_to_include or @cols_to_exclude. Do not use both the parameters at once',16,1)
RETURN -1 --Failure. Reason: Both @cols_to_include and @cols_to_exclude parameters are specified
END

--Making sure the @cols_to_include and @cols_to_exclude parameters are receiving values in proper format
IF ((@cols_to_include IS NOT NULL) AND (PATINDEX('''%''',@cols_to_include) = 0))
BEGIN
RAISERROR('Invalid use of @cols_to_include property',16,1)
PRINT 'Specify column names surrounded by single quotes and separated by commas'
PRINT 'Eg: EXEC sp_generate_inserts titles, @cols_to_include = "''title_id'',''title''"'
RETURN -1 --Failure. Reason: Invalid use of @cols_to_include property
END

IF ((@cols_to_exclude IS NOT NULL) AND (PATINDEX('''%''',@cols_to_exclude) = 0))
BEGIN
RAISERROR('Invalid use of @cols_to_exclude property',16,1)
PRINT 'Specify column names surrounded by single quotes and separated by commas'
PRINT 'Eg: EXEC sp_generate_inserts titles, @cols_to_exclude = "''title_id'',''title''"'
RETURN -1 --Failure. Reason: Invalid use of @cols_to_exclude property
END


--Checking to see if the database name is specified along wih the table name
--Your database context should be local to the table for which you want to generate INSERT statements
--specifying the database name is not allowed
IF (PARSENAME(@table_name,3)) IS NOT NULL
BEGIN
RAISERROR('Do not specify the database name. Be in the required database and just specify the table name.',16,1)
RETURN -1 --Failure. Reason: Database name is specified along with the table name, which is not allowed
END

--Checking for the existence of 'user table' or 'view'
--This procedure is not written to work on system tables
--To script the data in system tables, just create a view on the system tables and script the view instead

IF @owner IS NULL
BEGIN
IF ((OBJECT_ID(@table_name,'U') IS NULL) AND (OBJECT_ID(@table_name,'V') IS NULL))
BEGIN
RAISERROR('User table or view not found.',16,1)
PRINT 'You may see this error, if you are not the owner of this table or view. In that case use @owner parameter to specify the owner name.'
PRINT 'Make sure you have SELECT permission on that table or view.'
RETURN -1 --Failure. Reason: There is no user table or view with this name
END
END
ELSE
BEGIN
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @table_name AND (TABLE_TYPE = 'BASE TABLE' OR TABLE_TYPE = 'VIEW') AND TABLE_SCHEMA = @owner)
BEGIN
RAISERROR('User table or view not found.',16,1)
PRINT 'You may see this error, if you are not the owner of this table. In that case use @owner parameter to specify the owner name.'
PRINT 'Make sure you have SELECT permission on that table or view.'
RETURN -1 --Failure. Reason: There is no user table or view with this name
END
END

--Variable declarations
DECLARE @Column_ID int,
@Column_List varchar(8000),
@Column_Name varchar(128),
@Start_Insert varchar(786),
@Data_Type varchar(128),
@Actual_Values varchar(8000), --This is the string that will be finally executed to generate INSERT statements
@IDN varchar(128) --Will contain the IDENTITY column's name in the table

--Variable Initialization
SET @IDN = ''
SET @Column_ID = 0
SET @Column_Name = ''
SET @Column_List = ''
SET @Actual_Values = ''

IF @owner IS NULL
BEGIN
SET @Start_Insert = 'INSERT INTO ' + '[' + RTRIM(COALESCE(@target_table,@table_name)) + ']'
END
ELSE
BEGIN
SET @Start_Insert = 'INSERT ' + '[' + LTRIM(RTRIM(@owner)) + '].' + '[' + RTRIM(COALESCE(@target_table,@table_name)) + ']'
END


--To get the first column's ID

SELECT @Column_ID = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS (NOLOCK)
WHERE TABLE_NAME = @table_name AND
(@owner IS NULL OR TABLE_SCHEMA = @owner)



--Loop through all the columns of the table, to get the column names and their data types
WHILE @Column_ID IS NOT NULL
BEGIN
SELECT @Column_Name = QUOTENAME(COLUMN_NAME),
@Data_Type = DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS (NOLOCK)
WHERE ORDINAL_POSITION = @Column_ID AND
TABLE_NAME = @table_name AND
(@owner IS NULL OR TABLE_SCHEMA = @owner)



IF @cols_to_include IS NOT NULL --Selecting only user specified columns
BEGIN
IF CHARINDEX( '''' + SUBSTRING(@Column_Name,2,LEN(@Column_Name)-2) + '''',@cols_to_include) = 0
BEGIN
GOTO SKIP_LOOP
END
END

IF @cols_to_exclude IS NOT NULL --Selecting only user specified columns
BEGIN
IF CHARINDEX( '''' + SUBSTRING(@Column_Name,2,LEN(@Column_Name)-2) + '''',@cols_to_exclude) <> 0
BEGIN
GOTO SKIP_LOOP
END
END

--Making sure to output SET IDENTITY_INSERT ON/OFF in case the table has an IDENTITY column
IF (SELECT COLUMNPROPERTY( OBJECT_ID(QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + @table_name),SUBSTRING(@Column_Name,2,LEN(@Column_Name) - 2),'IsIdentity')) = 1
BEGIN
IF @ommit_identity = 0 --Determing whether to include or exclude the IDENTITY column
SET @IDN = @Column_Name
ELSE
GOTO SKIP_LOOP
END

--Making sure whether to output computed columns or not
IF @ommit_computed_cols = 1
BEGIN
IF (SELECT COLUMNPROPERTY( OBJECT_ID(QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + @table_name),SUBSTRING(@Column_Name,2,LEN(@Column_Name) - 2),'IsComputed')) = 1
BEGIN
GOTO SKIP_LOOP
END
END

--Tables with columns of IMAGE data type are not supported for obvious reasons
IF(@Data_Type in ('image'))
BEGIN
IF (@ommit_images = 0)
BEGIN
RAISERROR('Tables with image columns are not supported.',16,1)
PRINT 'Use @ommit_images = 1 parameter to generate INSERTs for the rest of the columns.'
PRINT 'DO NOT ommit Column List in the INSERT statements. If you ommit column list using @include_column_list=0, the generated INSERTs will fail.'
RETURN -1 --Failure. Reason: There is a column with image data type
END
ELSE
BEGIN
GOTO SKIP_LOOP
END
END

--Determining the data type of the column and depending on the data type, the VALUES part of
--the INSERT statement is generated. Care is taken to handle columns with NULL values. Also
--making sure, not to lose any data from flot, real, money, smallmomey, datetime columns
SET @Actual_Values = @Actual_Values +
CASE
WHEN @Data_Type IN ('char','varchar','nchar','nvarchar')
THEN
'COALESCE('''''''' + REPLACE(RTRIM(' + @Column_Name + '),'''''''','''''''''''')+'''''''',''NULL'')'
WHEN @Data_Type IN ('datetime','smalldatetime')
THEN
'COALESCE('''''''' + RTRIM(CONVERT(char,' + @Column_Name + ',109))+'''''''',''NULL'')'
WHEN @Data_Type IN ('uniqueidentifier')
THEN
'COALESCE('''''''' + REPLACE(CONVERT(char(255),RTRIM(' + @Column_Name + ')),'''''''','''''''''''')+'''''''',''NULL'')'
WHEN @Data_Type IN ('text','ntext')
THEN
'COALESCE('''''''' + REPLACE(CONVERT(char(8000),' + @Column_Name + '),'''''''','''''''''''')+'''''''',''NULL'')'
WHEN @Data_Type IN ('binary','varbinary')
THEN
'COALESCE(RTRIM(CONVERT(char,' + 'CONVERT(int,' + @Column_Name + '))),''NULL'')'
WHEN @Data_Type IN ('timestamp','rowversion')
THEN
CASE
WHEN @include_timestamp = 0
THEN
'''DEFAULT'''
ELSE
'COALESCE(RTRIM(CONVERT(char,' + 'CONVERT(int,' + @Column_Name + '))),''NULL'')'
END
WHEN @Data_Type IN ('float','real','money','smallmoney')
THEN
'COALESCE(LTRIM(RTRIM(' + 'CONVERT(char, ' + @Column_Name + ',2)' + ')),''NULL'')'
ELSE
'COALESCE(LTRIM(RTRIM(' + 'CONVERT(char, ' + @Column_Name + ')' + ')),''NULL'')'
END + '+' + ''',''' + ' + '

--Generating the column list for the INSERT statement
SET @Column_List = @Column_List + @Column_Name + ','

SKIP_LOOP: --The label used in GOTO

SELECT @Column_ID = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS (NOLOCK)
WHERE TABLE_NAME = @table_name AND
ORDINAL_POSITION > @Column_ID AND
(@owner IS NULL OR TABLE_SCHEMA = @owner)


--Loop ends here!
END

--To get rid of the extra characters that got concatenated during the last run through the loop
SET @Column_List = LEFT(@Column_List,len(@Column_List) - 1)
SET @Actual_Values = LEFT(@Actual_Values,len(@Actual_Values) - 6)

IF LTRIM(@Column_List) = ''
BEGIN
RAISERROR('No columns to select. There should at least be one column to generate the output',16,1)
RETURN -1 --Failure. Reason: Looks like all the columns are ommitted using the @cols_to_exclude parameter
END

--Forming the final string that will be executed, to output the INSERT statements
IF (@include_column_list <> 0)
BEGIN
SET @Actual_Values =
'SELECT ' +
CASE WHEN @top IS NULL OR @top < 0 THEN '' ELSE ' TOP ' + LTRIM(STR(@top)) + ' ' END + '''' + RTRIM(@Start_Insert) + ' ''+' + '''(' + RTRIM(@Column_List) + '''+' + ''')''' + ' +''VALUES(''+ ' + @Actual_Values + '+'')''' + ' ' + COALESCE(@from,' FROM ' + CASE WHEN @owner IS NULL THEN '' ELSE '[' + LTRIM(RTRIM(@owner)) + '].' END + '[' + rtrim(@table_name) + ']' + '(NOLOCK)') END ELSE IF (@include_column_list = 0) BEGIN SET @Actual_Values = 'SELECT ' + CASE WHEN @top IS NULL OR @top < 0 THEN '' ELSE ' TOP ' + LTRIM(STR(@top)) + ' ' END + '''' + RTRIM(@Start_Insert) + ' '' +''VALUES(''+ ' + @Actual_Values + '+'')''' + ' ' + COALESCE(@from,' FROM ' + CASE WHEN @owner IS NULL THEN '' ELSE '[' + LTRIM(RTRIM(@owner)) + '].' END + '[' + rtrim(@table_name) + ']' + '(NOLOCK)') END --Determining whether to ouput any debug information IF @debug_mode =1 BEGIN PRINT '/*****START OF DEBUG INFORMATION*****' PRINT 'Beginning of the INSERT statement:' PRINT @Start_Insert PRINT '' PRINT 'The column list:' PRINT @Column_List PRINT '' PRINT 'The SELECT statement executed to generate the INSERTs' PRINT @Actual_Values PRINT '' PRINT '*****END OF DEBUG INFORMATION*****/' PRINT '' END PRINT '--INSERTs generated by ''sp_generate_inserts'' stored procedure written by Vyas' PRINT '--Build number: 22' PRINT '--Problems/Suggestions? Contact Vyas @ vyaskn@hotmail.com' PRINT '--http://vyaskn.tripod.com' PRINT '' PRINT 'SET NOCOUNT ON' PRINT '' --Determining whether to print IDENTITY_INSERT or not IF (@IDN <> '')
BEGIN
PRINT 'SET IDENTITY_INSERT ' + QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + QUOTENAME(@table_name) + ' ON'
PRINT 'GO'
PRINT ''
END


IF @disable_constraints = 1 AND (OBJECT_ID(QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + @table_name, 'U') IS NOT NULL)
BEGIN
IF @owner IS NULL
BEGIN
SELECT 'ALTER TABLE ' + QUOTENAME(COALESCE(@target_table, @table_name)) + ' NOCHECK CONSTRAINT ALL' AS '--Code to disable constraints temporarily'
END
ELSE
BEGIN
SELECT 'ALTER TABLE ' + QUOTENAME(@owner) + '.' + QUOTENAME(COALESCE(@target_table, @table_name)) + ' NOCHECK CONSTRAINT ALL' AS '--Code to disable constraints temporarily'
END

PRINT 'GO'
END

PRINT ''
PRINT 'PRINT ''Inserting values into ' + '[' + RTRIM(COALESCE(@target_table,@table_name)) + ']' + ''''


--All the hard work pays off here!!! You'll get your INSERT statements, when the next line executes!
EXEC (@Actual_Values)

PRINT 'PRINT ''Done'''
PRINT ''


IF @disable_constraints = 1 AND (OBJECT_ID(QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + @table_name, 'U') IS NOT NULL)
BEGIN
IF @owner IS NULL
BEGIN
SELECT 'ALTER TABLE ' + QUOTENAME(COALESCE(@target_table, @table_name)) + ' CHECK CONSTRAINT ALL' AS '--Code to enable the previously disabled constraints'
END
ELSE
BEGIN
SELECT 'ALTER TABLE ' + QUOTENAME(@owner) + '.' + QUOTENAME(COALESCE(@target_table, @table_name)) + ' CHECK CONSTRAINT ALL' AS '--Code to enable the previously disabled constraints'
END

PRINT 'GO'
END

PRINT ''
IF (@IDN <> '')
BEGIN
PRINT 'SET IDENTITY_INSERT ' + QUOTENAME(COALESCE(@owner,USER_NAME())) + '.' + QUOTENAME(@table_name) + ' OFF'
PRINT 'GO'
END

PRINT 'SET NOCOUNT OFF'


SET NOCOUNT OFF
RETURN 0 --Success. We are done!
END

GO

PRINT 'Created the procedure'
GO


--Turn system object marking off
EXEC master.dbo.sp_MS_upd_sysobj_category 2
GO

PRINT 'Granting EXECUTE permission on sp_generate_inserts to all users'
GRANT EXEC ON sp_generate_inserts TO public

SET NOCOUNT OFF
GO

PRINT 'Done'

User Defined Function (UDF) to convert a given string to proper case

T-SQL has no built-in function to convert a string to proper case (In a proper case string, the first letter of each word would be in upper case. E.g: Bill Gates). So, I ended up writing my own PROPERCASE function.

****************************
Copyright © 2001 Narayana Vyas Kondreddi. All rights reserved.

Purpose: To convert a given string to proper case

Written by: Narayana Vyas Kondreddi
http://vyaskn.tripod.com

Tested on: SQL Server 2000

Date modified: December-5-2001 16:55 AM IST

Email: vyaskn@hotmail.com

Examples:

To convert the string 'william h gates' to proper case:
SELECT dbo.PROPERCASE('william h gates')

To convert the Notes field of titles table in pubs database to proper case:
SELECT dbo.PROPERCASE(notes) FROM pubs..titles
***************************/
CREATE FUNCTION PROPERCASE
(
--The string to be converted to proper case
@input varchar(8000)
)
--This function returns the proper case string of varchar type
RETURNS varchar(8000)
AS
BEGIN
IF @input IS NULL
BEGIN
--Just return NULL if input string is NULL
RETURN NULL
END

--Character variable declarations
DECLARE @output varchar(8000)
--Integer variable declarations
DECLARE @ctr int, @len int, @found_at int
--Constant declarations
DECLARE @LOWER_CASE_a int, @LOWER_CASE_z int, @Delimiter char(3), @UPPER_CASE_A int, @UPPER_CASE_Z int

--Variable/Constant initializations
SET @ctr = 1
SET @len = LEN(@input)
SET @output = ''
SET @LOWER_CASE_a = 97
SET @LOWER_CASE_z = 122
SET @Delimiter = ' ,-'
SET @UPPER_CASE_A = 65
SET @UPPER_CASE_Z = 90

WHILE @ctr <= @len BEGIN --This loop will take care of reccuring white spaces WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) > 0
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
SET @ctr = @ctr + 1
END

IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @LOWER_CASE_a AND @LOWER_CASE_z
BEGIN
--Converting the first character to upper case
SET @output = @output + UPPER(SUBSTRING(@input,@ctr,1))
END
ELSE
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
END

SET @ctr = @ctr + 1

WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) = 0 AND (@ctr <= @len)
BEGIN
IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @UPPER_CASE_A AND @UPPER_CASE_Z
BEGIN
SET @output = @output + LOWER(SUBSTRING(@input,@ctr,1))
END
ELSE
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
END
SET @ctr = @ctr + 1
END

END
RETURN @output
END

Stored procedure to generate a simple or complex random password

his procedure generates random passwords using RAND() function. It can be configured to generate a simple or a complex password. You can also customize the length of the password generated. Complex passwords will include upper and lower case letters, numbers and special characters. See the code to realize how useful the RAND() function is! When you choose to generate a simple password (default behavior), SPECIAL CARE is taken to generate meaningful/easy to remember passwords.

CREATE PROC random_password
(
@len int = 8, --Length of the password to be generated
@password_type char(7) = 'simple'
--Default is to generate a simple password with lowecase letters.
--Pass anything other than 'simple' to generate a complex password.
--The complex password includes numbers, special characters, upper case and lower case letters
)
AS
/****************************************************
Copyright © 2001 Narayana Vyas Kondreddi. All rights reserved.
Purpose: To generate a random password
Written by: Narayana Vyas Kondreddi http://vyaskn.tripod.com
Tested on: SQL Server 7.0 and SQL Server 2000
Date modified: March-29-2001 01:15 PM
Email: vyaskn@hotmail.com

Examples:
To generate a simple password with a length of 8 characters:
EXEC random_password
To generate a simple password with 6 characters:
EXEC random_password 6
To generate a complex password with 8 characters:
EXEC random_password @Password_type = 'complex'
To generate a comples password with 6 characters:
EXEC random_password 6, 'complex'
*************************************************/
BEGIN
DECLARE @password varchar(25), @type tinyint, @bitmap char(6)
SET @password=''
SET @bitmap = 'uaeioy'
--@bitmap contains all the vowels, which are a, e, i, o, u and y. These vowels are used to generate slightly readable/rememberable simple passwords

WHILE @len > 0
BEGIN
IF @password_type = 'simple' --Generating a simple password
BEGIN
IF (@len%2) = 0 --Appending a random vowel to @password

SET @password = @password + SUBSTRING(@bitmap,CONVERT(int,ROUND(1 + (RAND() * (5)),0)),1)
ELSE --Appending a random alphabet
SET @password = @password + CHAR(ROUND(97 + (RAND() * (25)),0))

END
ELSE --Generating a complex password
BEGIN
SET @type = ROUND(1 + (RAND() * (3)),0)

IF @type = 1 --Appending a random lower case alphabet to @password
SET @password = @password + CHAR(ROUND(97 + (RAND() * (25)),0))
ELSE IF @type = 2 --Appending a random upper case alphabet to @password
SET @password = @password + CHAR(ROUND(65 + (RAND() * (25)),0))
ELSE IF @type = 3 --Appending a random number between 0 and 9 to @password
SET @password = @password + CHAR(ROUND(48 + (RAND() * (9)),0))
ELSE IF @type = 4 --Appending a random special character to @password
SET @password = @password + CHAR(ROUND(33 + (RAND() * (13)),0))
END

SET @len = @len - 1
END

SELECT @password --Here's the result

END

T-SQL code to concatenate all the values of a column into one row

/****************************************/
Purpose: To concatenate the values of a column in all rows into one row.
Written by: Allan Mitchel    http://www.allisonmitchell.com
Tested on: SQL Server 7.0 and SQL Server 2000
Date modified: March-22-2001 6:30 PM
Email: vyaskn@hotmail.com
NOTE: A limitation to be aware of is that varchar can go upto a max size of
8000 characters. If your data occupies more space, the output will be
truncated.
****************************/

USE pubs
GO
DECLARE @title_ids varchar(150), @delimiter char
SET @delimiter = ','
SELECT @title_ids = COALESCE(@title_ids + @delimiter, '') + title_id FROM titles
SELECT @title_ids AS [List of Title IDs]

Scripting permissions using catalog views in SQL Server 2005

Have you ever been asked to copy or clone the database permissions of one user to another database user? Or how about creating a new database role based on an existing database role? Basically, there isn't a direct command or interface for duplicating the permissions of a user or database role. One way of doing this would be to generate scripts for all objects within the database using SQL Server Enterprise Manager (SQL EM) or SQL Server Management Studio (SSMS), and then manually extract all the GRANT and DENY commands from the script. But it is a manual and tedious process.

Recently, I faced a situation where I had to create a new database role, that would get all the permissions of an existing role, plus some additional permissions. I really didn't want to nest the roles (adding a role as a member of another role), as I prefer to keep things simple. So, I came up with a SQL script, that generates the required commands to duplicate the permissions of a specified database user or role. This script makes use of the newly added SQL Server 2005 security catalog views to recreate the permissions.

This script queries the following SQL Server 2005 security catalog views:

sys.database_role_members: This catalog view maps database users to database roles that they are members of

sys.database_permissions: Contains information about all the permissions held by users and roles

sys.objects: Contains information about all user-defined database objects

sys.database_principals: Contains information about all database users and database roles

sys.columns: Contains data about each column of an object that has columns, such as views or tables

Note:In SQL Server 2000, the above catalog views are not available and the equivalent system tables are: syspermissions, sysprotects, sysobjects, sysusers, syscolumns

To use the below script, you will have to change the values of the @OldUser and @NewUser to the names of 'the user or role from which to copy the permissions from', and 'the user or role to which to copy the permissions to' respectively.

Note: This script will not automatically run the commands to copy the permissions. It will simply generate the commands that are required to copy the permissions from one user or role to another user or role. You will have to copy these commands, verify the generated commands, and run those commands manually in either Query Analyzer or Management Studio. It is better to run the below script with the output set to text mode, instead of grid mode. Also note that, this script cannot be used to script permissions for fixed database roles like db_datareader and db_datawriter. It is meant to script permissions for database users and user defined database roles.

If you just want to script the permissions of an existing user (and not copy them to a different user), then simply set the values of the variables @OldUserand @NewUser to the same user or role name.

The output of the script contains three sections:

- sp_addrolemember calls to copy the database role memberships of the specified user or role

- GRANT and DENY commands to copy the object level permissions of the specified user or role

- GRANT and DENY commands to copy the database level permissions of the specified user or role
SET NOCOUNT ON


DECLARE @OldUser sysname, @NewUser sysname


SET @OldUser = 'HRUser'
SET @NewUser = 'PersonnelAdmin'


SELECT 'USE' + SPACE(1) + QUOTENAME(DB_NAME()) AS '--Database Context'


SELECT '--Cloning permissions from' + SPACE(1) + QUOTENAME(@OldUser) + SPACE(1) + 'to' + SPACE(1) + QUOTENAME(@NewUser) AS '--Comment'


SELECT 'EXEC sp_addrolemember @rolename ='
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''') + ', @membername =' + SPACE(1) + QUOTENAME(@NewUser, '''') AS '--Role Memberships'
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC


SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1) + 'ON ' + QUOTENAME(USER_NAME(obj.schema_id)) + '.' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE '(' + QUOTENAME(cl.name) + ')' END
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Object Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC


SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Database Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC

How to search all columns of all tables in a database for a keyword?

While browsing the SQL Server newsgroups, every once in a while, I see a request for a script that can search all the columns of all the tables in a given database for a specific keyword. I never took such posts seriously. But then recently, one of my network administrators was troubleshooting a problem with Microsoft Operations Manager (MOM). MOM uses SQL Server for storing all the computer, alert and performance related information. He narrowed the problem down to something specific, and needed a script that can search all the MOM tables for a specific string. I had no such script handy at that time, so we ended up searching manually.

That's when I really felt the need for such a script and came up with this stored procedure "SearchAllTables". It accepts a search string as input parameter, goes and searches all char, varchar, nchar, nvarchar columns of all tables (only user created tables. System tables are excluded), owned by all users in the current database. Feel free to extend this procedure to search other datatypes.

The output of this stored procedure contains two columns:

- 1) The table name and column name in which the search string was found
- 2) The actual content/value of the column (Only the first 3630 characters are displayed)

Here's a word of caution, before you go ahead and run this procedure. Though this procedure is quite quick on smaller databases, it could take hours to complete, on a large database with too many character columns and a huge number of rows. So, if you are trying to run it on a large database, be prepared to wait (I did use the locking hint NOLOCK to reduce any locking). It is efficient to use Full-Text search feature for free text searching, but it doesn't make sense for this type of ad-hoc requirements.

Create this procedure in the required database and here is how you run it:



CREATE PROC SearchAllTables
(
@SearchStr nvarchar(100)
)
AS
BEGIN

-- Copyright © 20011 SIVANANDA REDDY G. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: SIVANANDA REDDY G
-- Site: http://sivanandareddy.com
-- Tested on: SQL Server 2005 and SQL Server 2008
-- Date modified: 11th October 2011 20:10 IST


CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))

SET NOCOUNT ON

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)

WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)

IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END

SELECT ColumnName, ColumnValue FROM #Results
END

--==================================================
--To search all columns of all tables in Pubs database for the keyword "siva"
EXEC SearchAllTables 'siva'
GO



Link

Tuesday, October 4, 2011

Microsoft SQL Server 2008 Advanced SQL Best Practices


How to calculate last (previous) date periods?
Execute the following Microsoft SQL Server T-SQL script in SSMS Query Editor to demonstrate the creation and test of a stored procedure to calculate last week, last month, last quarter and last year date limits using datetime variable types.

use AdventureWorks2008;
go
create proc sprocLastPeriodRange
      @Period varchar(8),
      @PeriodStart datetime output,
      @PeriodEnd datetime output,
      @PeriodEndPlusOneDay datetime output
as
begin
declare @FirstDayOfCurrentPeriod datetime = getdate(),
        @FirstDayOfLastPeriod datetime = getdate()

if @Period in ('Week','wk','ww')
begin
      set @FirstDayOfCurrentPeriod = DATEADD(DD, 1 - DATEPART(DW, CONVERT(VARCHAR(10),
                      getdate(), 111)), CONVERT(VARCHAR(10), getdate(), 111))
      set @FirstDayOfLastPeriod = dateadd(dd, -7, @FirstDayOfCurrentPeriod)
end

else if @Period in ('Month', 'mm', 'm')
begin
      set @FirstDayOfCurrentPeriod = convert(datetime,
                               left(convert(varchar, getdate(), 111),8) + '01')
      set @FirstDayOfLastPeriod = dateadd(mm, -1, @FirstDayOfCurrentPeriod)
end
else if @Period in ('Quarter','qq', 'q')
begin
      set @FirstDayOfCurrentPeriod = CONVERT(CHAR(4), YEAR(getdate())) +
                       CASE WHEN MONTH(getdate()) between 1 and 3 THEN '/01/01'
                            WHEN MONTH(getdate()) between 4 and 6 THEN '/04/01'
                            WHEN MONTH(getdate()) between 7 and 9 THEN '/07/01'
                            ELSE '/10/01'
                       END

      set @FirstDayOfLastPeriod = dateadd(mm, -3, @FirstDayOfCurrentPeriod)
end
else if @Period in ('Year', 'yyyy', 'yy')
begin

      set @FirstDayOfCurrentPeriod = convert(datetime,
                               left(convert(varchar, getdate(), 111),5) + '01/01')
      set @FirstDayOfLastPeriod = dateadd(yy, -1, @FirstDayOfCurrentPeriod)
end
set @PeriodStart = @FirstDayOfLastPeriod
set @PeriodEndPlusOneDay = @FirstDayOfCurrentPeriod
set @PeriodEnd = DATEADD (dd,-1, @FirstDayOfCurrentPeriod)
end
go

-- Test
declare @LastPeriodBegin datetime, @LastPeriodEnd datetime
declare @ThisPeriodBegin datetime

exec sprocLastPeriodRange 'qq',
                          @LastPeriodBegin output,
                          @LastPeriodEnd output,
                          @ThisPeriodBegin output
select Period='qq',
       LastBegin=@LastPeriodBegin,
       LastEnd=@LastPeriodEnd,
       ThisBegin=@ThisPeriodBegin                         

-- To use it for WHERE range filtering
-- Note that < is used at period upper limit
select * from Purchasing.PurchaseOrderHeader
where OrderDate >= @LastPeriodBegin
and   OrderDate <  @ThisPeriodBegin
go

Partial results:
Period
LastBegin
LastEnd
ThisBegin
qq
7/1/08 0:00
9/30/08 0:00
10/1/08 0:00

How to upsert with the MERGE statement?
Execute the following Microsoft SQL Server T-SQL scripts in SSMS Query Editor to demonstrate UPSERT, update or insert, operation using the MERGE statement. If the row exists as identified by the 3 key columns, UPDATE is performed on OrderQuantity and SalesAmount, otherwise INSERT action is carried out. MERGE can do INSERT, UPDATE and DELETE in a single statement.

use tempdb;

select top (5000) ResellerKey, OrderDateKey, ProductKey, OrderQuantity, SalesAmount
into FactResellerSales
from AdventureWorksDW2008.dbo.FactResellerSales
go

select top (8000) ResellerKey, OrderDateKey, ProductKey, OrderQuantity, SalesAmount
into ResellerSalesTransaction
from AdventureWorksDW2008.dbo.FactResellerSales
go

delete rsc
from  ResellerSalesTransaction rsc
join (select top 1000 * from ResellerSalesTransaction order by ResellerKey desc) x
on x.ResellerKey=rsc.ResellerKey
go


update top (6000) ResellerSalesTransaction
set SalesAmount = SalesAmount * 1.1
go

select top (10) * from FactResellerSales
order by ResellerKey, OrderDateKey, ProductKey
go

select BeforeFactCount=COUNT(*) from FactResellerSales
go

-------------------------------------------------------------------- 
-- Test data sets created, ready for the MERGE (update or insert)
-------------------------------------------------------------------- 
MERGE FactResellerSales AS fact
USING (
  SELECT *  FROM ResellerSalesTransaction
) AS feed
ON (    fact.ProductKey = feed.ProductKey
    AND fact.ResellerKey = feed.ResellerKey
    AND fact.OrderDateKey = feed.OrderDateKey )
WHEN MATCHED THEN
    UPDATE SET
        fact.OrderQuantity = fact.OrderQuantity + feed.OrderQuantity
        ,fact.SalesAmount = fact.SalesAmount + feed.SalesAmount 
WHEN NOT MATCHED THEN
    INSERT (ResellerKey, OrderDateKey, ProductKey, OrderQuantity, SalesAmount)
    VALUES (feed.ResellerKey, feed.OrderDateKey, feed.ProductKey,
            feed.OrderQuantity, feed.SalesAmount);
--------------------------------------------------------------------  
go

select top (10) * from FactResellerSales
order by ResellerKey, OrderDateKey, ProductKey
go

select AfterFactCount=COUNT(*) from FactResellerSales
go



-- Cleanup
use tempdb;
drop table ResellerSalesTransaction
go
drop table FactResellerSales
go

How to create date series with multiple-value assignment?
Execute the following Microsoft SQL Server Transact-SQL script in Management Studio Query Editor to demonstrate the creation of integer and date series with the use of the multiple-value assignment operator within an UPDATE statement. The construct avoids the use of cursor WHILE loop, therefore it is a scalable solution.


use tempdb;

select ID = CONVERT(int,SalesOrderID),
TestDate=convert(date,ModifiedDate) into DateSeries
from AdventureWorks2008.Sales.SalesOrderHeader
go

select top 100 * from DateSeries
go

-- Multi-value assignment UPDATE
declare @Date  date = dateadd(day,1,getdate()), @id int = 0
update DateSeries
set @id = ID = @id + 1,
    @Date = TestDate = dateadd (Day, -1, @Date)
   
go

select top 100 * from DateSeries
go

use tempdb;
drop table DateSeries
go

First and second partial results:
ID
TestDate
43659
7/8/2001
43660
7/8/2001
43661
7/8/2001
43662
7/8/2001
43663
7/8/2001
ID
TestDate
1
11/26/2008
2
11/25/2008
3
11/24/2008
4
11/23/2008
5
11/22/2008
6
11/21/2008
7
11/20/2008
8
11/19/2008

How to design for stored procedure missing (NULL) parameter?
Execute the following Microsoft SQL Server T-SQL script in Query Editor to demonstrate the design for missing filter parameter(s). In case of all 3 parameters missing, the entire JOINed Production.Product table content is returned without the WHERE filter.
USE AdventureWorks2008;
GO

CREATE PROCEDURE sprocProductFilter
                @LowPrice    SMALLMONEY  = NULL,
                @SubCategory VARCHAR(32)  = NULL,
                @Color       VARCHAR(16)  = NULL
AS
  SET nocount  ON;
  
  SELECT p.*
  FROM   Production.Product p
         INNER JOIN Production.ProductSubcategory sc
           ON p.ProductSubcategoryID = sc.ProductSubcategoryID
  WHERE  1 = 1
         AND (@LowPrice <= ListPrice
               OR @LowPrice IS NULL)
         AND (@SubCategory = sc.Name
               OR @SubCategory IS NULL)
         AND (@Color = Color
               OR @Color IS NULL)

GO

exec sprocProductFilter 700.0, 'Road Frames', 'Red'
go

exec sprocProductFilter NULL, 'Road Frames', 'Red'
go

exec sprocProductFilter NULL, NULL, 'Red'
go

exec sprocProductFilter 700.0, 'Road Frames'
go

exec sprocProductFilter 700.0
go

exec sprocProductFilter
go

How to measure stored procedure execution time?
Execute the following Microsoft SQL Server T-SQL script in SSMS Query Editor take execution time measurement for a stored procedure. The timing is the average of 10 measurements.
DECLARE @i int = 0, @TestLimit int = 10
DECLARE @Timing TABLE ( Timing int)

WHILE (@i < @TestLimit)
BEGIN
      DECLARE @RC int, @ManagerID int =1
      DBCC DROPCLEANBUFFERS
      DECLARE @Start datetime = getdate()
      EXECUTE @RC = [AdventureWorks2008].[dbo].[uspGetManagerEmployees] @ManagerID
      INSERT @Timing
      SELECT ExecutionMsec = datediff (millisecond, @Start, getdate())
      SET @i=@i+1
END
SELECT ExecutionMsec = avg(Timing) FROM @Timing
Go

How to combine detail data with GROUP BY aggregate?
Execute the following Microsoft SQL Server T-SQL script in SSMS Query Editor demonstrate the usage of CTE GROUP BY aggregate to JOIN to detail data lines.
Use AdventureWorks2008;

WITH ctePOTotal AS
 (
        SELECT
            PurchaseOrderID,
            Sum(OrderQty) as [TotalQty]
        FROM Purchasing.PurchaseOrderDetail T2
        GROUP BY PurchaseOrderID
    )
SELECT
    PO = pod.PurchaseOrderID,
    LineItem=ROW_NUMBER()OVER (PARTITION BY pod.PurchaseOrderID ORDER BY ProductId),
    OrderDate = convert(varchar,OrderDate,110),
    ProductId,
    UnitPrice,
    OrderQty,
    TotalQty=ctePOTotal.[TotalQty]
FROM Purchasing.PurchaseOrderHeader poh
    INNER JOIN Purchasing.PurchaseOrderDetail pod
        ON poh.PurchaseOrderId = pod.PurchaseOrderId
    INNER JOIN  ctePOTotal
        ON pod.PurchaseOrderID = ctePOTotal.PurchaseOrderID
WHERE Year(OrderDate)=2004
ORDER BY PO, LineItem

How to list all columns with extended properties?
Execute the following Microsoft SQL Server Transact-SQL (T-SQL) script in Management Studio (SSMS) Query Editor to list all tables column information with extended properties.
USE AdventureWorks2008;

SELECT   [Schema] = s.name,
         [Table] = object_name(major_id),
         [Column] = c.name,
         [Type] = t.name,
         [Extended] = p.VALUE
FROM     sys.extended_properties p
         JOIN sys.columns c
           ON c.column_id = p.minor_id
              AND c.object_id = p.major_id
         JOIN sys.objects o
           ON o.object_id = p.major_id
              AND o.object_id = c.object_id
         JOIN sys.schemas s
           ON s.schema_id = o.schema_id
         JOIN sys.types t
           ON c.system_type_id = t.user_type_id
WHERE    o.TYPE = 'U'
         AND class_desc = 'OBJECT_OR_COLUMN'
ORDER BY [Schema],
         [Table],
         c.column_id

How to calculate running total fast?
Execute the following Microsoft SQL Server Transact-SQL (T-SQL) script in Management Studio (SSMS) Query Editor to calculate running total without using a loop. In the update statement double assignment is applied.
USE tempdb;

SELECT * INTO POH from AdventureWorks2008.Purchasing.PurchaseOrderHeader
ORDER by PurchaseOrderID

-- select * from POH

ALTER TABLE POH ADD RunningTotal money
GO

SET NOCOUNT ON
GO

DECLARE @RunningTotal MONEY

SET @RunningTotal=0

UPDATE POH

SET @RunningTotal = RunningTotal = @RunningTotal+ISNULL(TotalDue, 0)
GO

SELECT * FROM POH
GO