Labels

admin (1) aix (1) alert (1) always-on (2) Architecture (1) aws (3) Azure (1) backup (3) BI-DWH (10) Binary (3) Boolean (1) C# (1) cache (1) casting (3) cdc (1) certificate (1) checks (1) cloud (3) cluster (1) cmd (7) collation (1) columns (1) compilation (1) configurations (7) Connection-String (2) connections (6) constraint (6) copypaste (2) cpu (2) csv (3) CTE (1) data-types (1) datetime (23) db (547) DB2 (1) deadlock (2) Denali (7) device (6) dotNet (5) dynamicSQL (11) email (5) encoding (1) encryption (4) errors (124) excel (1) ExecutionPlan (10) extended events (1) files (7) FIPS (1) foreign key (1) fragmentation (1) functions (1) GCP (2) gMSA (2) google (2) HADR (1) hashing (3) in-memory (1) index (3) indexedViews (2) insert (3) install (10) IO (1) isql (6) javascript (1) jobs (11) join (2) LDAP (2) LinkedServers (8) Linux (15) log (6) login (1) maintenance (3) mariadb (1) memory (4) merge (3) monitoring (4) MSA (2) mssql (444) mssql2005 (5) mssql2008R2 (20) mssql2012 (2) mysql (36) MySQL Shell (5) network (1) NoSQL (1) null (2) numeric (9) object-oriented (1) offline (1) openssl (1) Operating System (4) oracle (7) ORDBMS (1) ordering (2) Outer Apply (1) Outlook (1) page (1) parameters (2) partition (1) password (1) Performance (103) permissions (10) pivot (3) PLE (1) port (4) PostgreSQL (14) profiler (1) RDS (3) read (1) Replication (12) restore (4) root (1) RPO (1) RTO (1) SAP ASE (48) SAP RS (20) SCC (4) scema (1) script (8) security (10) segment (1) server (1) service broker (2) services (4) settings (75) SQL (74) SSAS (1) SSIS (19) SSL (8) SSMS (4) SSRS (6) storage (1) String (35) sybase (57) telnet (2) tempdb (1) Theory (2) tips (120) tools (3) training (1) transaction (6) trigger (2) Tuple (2) TVP (1) unix (8) users (3) vb.net (4) versioning (1) windows (14) xml (10) XSD (1) zip (1)

sp_executesql ERROR: Procedure expects parameter '@parameters' of type 'ntext/nchar/nvarchar'

Error:
EXEC sp_executesql N'SELECT @x', '@x int', @x = 2
--or:
EXEC sp_executesql 'SELECT @x', N'@x int', @x = 2

This error message will be displayed:
Msg 214, Level 16, State 3, Procedure sp_executesql, Line 1
Procedure expects parameter '@parameters' of type 'ntext/nchar/nvarchar'.

Explanation:
The first and the second parameters of sp_executesql are Unicode - nvarchar/ntext (depend on the MSSQL version).
varchar is not valid!

Solutions:
--1.
EXEC sp_executesql N'SELECT @x', N'@x int', @x = 2

-- 2.
DECLARE @stmt nvarchar(max), @params nvarchar(max)
SET @stmt = 'SELECT @x' -- @stmt was declared as nvarchar, so the N is not required
SET @params = '@x int' -- @params was declared as nvarchar, so the N is not required
EXEC sp_executesql @stmt, @params, 2

QUOTENAME

QUOTENAME returns a Unicode string with the delimiters added to make the input string a valid SQL Server delimited identifier.

SELECT QUOTENAME('abcdef') --result: [abcdef]
SELECT QUOTENAME('abc-def') --result: [abc-def]
SELECT QUOTENAME('abc[]def') --result: [abc[]]def]

Slow in Application, Fast in SSMS

There is not unusual situation that query or stored procedure run very slow from the application, but run fast from the SSMS (SQL Server Management Studio).
There are some optional reasons for this situation, I'll describe in this post.

Parameter Sniffing

Different Plans for Different Settings
Different Settings between SSMS and the application create different plans.
Different Default Setting between SSMS and the application is for ARITHABORT – in Applications using ADO .Net, ODBC or OLE DB is OFF, and in SSMS is ON. This can cause different plans. In many the ARITHABORT settings is the reason for performance problems in the application.

Check settings of sessions using:

SELECT * FROM sys.dm_exec_sessions 
WHERE session_id in (68,61) --SSMS session VS APP session.

http://copypastenet.blogspot.com/2011/10/get-set-options-for-current-session.html

Blocking
Blocking between statements and/or transactions from/in the applications.

Permissions on the remote database
Permissions on the remote database can be different than the permissions of the user in SSMS, and this can cause to different statistics, query plans, etc.
For simulate the application execution, try to execute in SSMS with: 
EXECUTE AS USER = 'AppUser'

Bad SQL Code
Bad SQL Code is always bad.....

Plans for Dynamic SQL
Unparameterised SQL is bad for the performance:
Not good:
SELECT @sql = 'SELECT mycol FROM tbl WHERE keycol = ' + convert(varchar, @value)
EXEC(@sql)
Or in C#:
cmd.CommandText = "SELECT mycol FROM tbl WHERE keycol = " + value.ToString();
Good:
EXEC sp_executesql N'SELECT mycol FROM dbo.tbl WHERE keycol = @value',
                   N'@value int', @value = @value
Or in C#:
cmd.CommandText = "SELECT mycol FROM dbo.tbl WHERE keycol = @value";
cmd.Parameters.Add("@value", SqlDbType.Int);
cmd.Parameters["@value"].Value = value;

Application cache
Similar to Parameter Sniffing.



Note: Beside of my experience, in this post I also based on one of the best articles that I ever read:

NULLIF

NULLIF returns a null value if the two specified expressions are equal.

SELECT NULLIF (colA, 0)
NULLIF is good to prevent 'divide by zero' issues, by converts the column that can be zero to NULL, and than the result will be NULL and not ERROR (divide by NULL = NULL).

SQL Server Denali (2011) main features and innovations


WINDOW Functions
Window Functions are functions on subsets of rows that meet a pre-defined, user defined criteria. Any subset of user-defined records or rows is called a “window”.
SQL Server Denali takes the Window Functions to the next step by adding functionality.
Window Functions are, as examples, ROW_NUMBER(), RANK(), DENSE_RANK(), and NTILE(), OVER(), LEAD and LAG.

LEAD and LAG
Return the previous (LAG) and the next (LEAD) value

LAG (scalar_expression [,offset] [,default]) OVER ( [ partition_by_clause ] order_by_clause )
SELECT LAG(SalesQuota, 1,0) OVER (ORDER BY YEAR(QuotaDate)) AS 'LAG' FROM .....

LEAD ( scalar_expression [ ,offset ] , [ default ] ) OVER ( [ partition_by_clause ] )
SELECT LEAD(SalesQuota, 1,0) OVER (ORDER BY YEAR(QuotaDate)) AS 'LEAD' FROM .....

FIRST_VALUE and LAST_VALUE
Return the first or the last value in the "window".

FIRST_VALUE ( [scalar_expression ) OVER ( [ partition_by_clause ] order_by_clause [rows_range_clause ] )

LAST_VALUE ( [scalar_expression ) OVER ( [ partition_by_clause ] order_by_clause rows_range_clause ) 


More T-SQL stuff

TRY_CONVERT(), PARSE() and TRY_PARSE()
TRY_CONVERT() - Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
TRY_CONVERT ( data_type [ ( length ) ], expression [, style ] )

SELECT TRY_CONVERT(float,'test') -- result: NULL
SELECT TRY_CONVERT(datetime2, '12/31/2010') -- result: 2010-12-31 00:00:00.0000000

PARSE() - Returns a value cast to the specified data type if the cast succeeds; otherwise, raise an error.
SELECT PARSE('10' AS TIME) -- result: ERROR!
SELECT PARSE('10' AS Float(10,2)) -- result: 10.00 

TRY_PARSE() - Returns a value cast to the specified data type if the cast succeeds; otherwise, return null.
SELECT TRY_PARSE('10' AS TIME) -- result: NULL
SELECT TRY_PARSE('10' AS Float(10,2)) -- result: 10.00 

FORMAT()
Returns a value formatted with the specified format and optional culture.
Mainly useful for Dynamic SQL.
FORMAT ( value, format [, culture ] )

SELECT FORMAT(@d, N'yyyy-MM')
SELECT FORMAT(@d, N'yyyy-MM-dd'),
SELECT FORMAT(@d, N'dddd, MMMM dd, yyyy', N'fr-fr')
SELECT Format(0.5,'000.0')
SELECT Format(1234,'#,###')

IIf()
IIf(Condition, value_if_true, value_if_false)

SELECT IIF(GETDATE() > '20110101', '2011', 'earlier)'

Choose
Choose(index, val_1, val_2 [, val_n ])

SELECT Choose(3, 'A', 'B', 'C', 'D') -- result: 'C'
SELECT Choose(ColInt, 'one', 'two', 'three', 'four', ...) FROM TABLENAME


Concat ()
Concat is similar to the operator +, with those differences: 
  • convertion of numbers and dates without 'Cast'.
  • Null = '' and not make all the result to be null.
Select Concat(@S,',',object_id) From sys.objects 
-- result: all the IDs from sys.objects, separated by ','.

Datetime Functions creation
DateTimeFromParts
DateTime2FromParts
DateTimeOffsetFromParts
SmallDateTimeFromParts
Functions that create datetime from divided parts.

WITH RESULT SETS
Change the names and/or data types of the returning result set of a stored procedure.

SQL built-in Paging

Returns only metadata
SET FMTONLY returns only metadata to the client.


SEQUENCE
SEQUENCE allows you to define a central place where SQL Server will maintain a counter of values for you.

Using a sequence number in multiple tables is one of the adventages of SEQUENCE.
http://msdn.microsoft.com/en-us/library/ff878058(v=sql.110).aspx


--CREATE SEQUENCE:
CREATE SEQUENCE dbo.Seq1
    AS INT -- could be any type of int
    MINVALUE 1 -- default: min value of the defined type
    MAXVALUE 100 -- default: max value of the defined type
    START WITH 1
    INCREMENT BY 1 -- or any other number
    CYCLE
GO
-- note: CYCLE is not must parameter - if it chosen, when arrive to the max. vakue, the SEQUENCE will start again from the min. value.

-- get new number from SEQUENCE:
SELECT NextID = NEXT VALUE FOR dbo.dbo.Seq1
http://msdn.microsoft.com/en-us/library/ff878370(v=sql.110).aspx

-- ALTER SEQUENCE:
ALTER SEQUENCE dbo.Seq1 RESTART WITH 15


Notes:

1. SEQUENCE will not provide you a transactionally consistent and gap-free stream of values.  Like IDENTITY, if your transaction rolls back, the next value is still taken.

2. One of the nice adventage of SEQUENCE relatively to IDENTITY is that you can get the next ID before the insert statement:
DECLARE @NextID int ;
SET @NextID = NEXT VALUE FOR dbo.Seq1
.........
INSERT TABLENEME (ID, Name) VALUES (@NextID, 'Itai')



Column based database - Apollo Project

Column Store Index
Column Store Index is new type of index which stored columns in separate set of data pages instead of rows stored in data pages.
Column Store Index, that can improve performance, mostly for queries which are used aggregation , warehouse processing and BI application.
Column Store Index is read only.

CREATE NONCLUSTERED COLUMNSTORE INDEX MyIndex ON MyTable(col1, col2, …)


SQL Server Developer Tools, Codename "Juneau"
"Juneau" is the new SSMS for developers in Denali.
"Juneau" (SSDT) is a tool for on and off-premise database development within Visual Studio. 
The Server Explorer in VS gives you an SSMS-like view of your live database objects. 
SSDT also provides database developers with code navigation, IntelliSense, language support that parallels what is available for C# and VB, platform specific validation, debugging and declarative editing in the TSQL Editor, as well as a visual Table Designer for both database projects and online database instances.


Reporting Services - Project Crescent
"Crescent" is the new Reporting Services in Denali.
Project “Crescent” is a new interactive data exploration and visual presentation experience. It will offer a fun, visual, and powerful drag-and-drop ad hoc reporting experience. It is an web-based end-user BI tool based on Silverlight.

Demo for SQL Server Project "Crescent":


HADR - AlwaysOn
HADR, (or AlwaysOn, or Availability Groups)
The Always On Availability Groups feature is a high-availability and disaster-recovery solution that provides an enterprise-level alternative to database mirroring. 
AlwaysOn Availability Groups maximizes the availability of a set of user databases for an enterprise. 
Deploying AlwaysOn Availability Groups involves creating and configuring one or more availability groups. 



More Useful links:
MSDN: What's New (SQL Server "Denali")

Download the SQL Server Denali Community Technical Preview 3 (CTP3) Product Guide:

SQL Server code name Denali Links:

Script of DB backup Job creation

-- 1. replace all 'DataBaseName' to your DB Name.
-- 2. replace DomainName\master to your user name.
-- 3. execute on master DB.

BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'DataBaseNameBackup', 
@enabled=1, 
@notify_level_eventlog=0, 
@notify_level_email=0, 
@notify_level_netsend=0, 
@notify_level_page=0, 
@delete_level=0, 
@description=N'DataBaseName Backup', 
@category_name=N'[Uncategorized (Local)]', 
@owner_login_name=N'DomainName\master', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'DataBaseNameBackup', 
@step_id=1, 
@cmdexec_success_code=0, 
@on_success_action=1, 
@on_success_step_id=0, 
@on_fail_action=2, 
@on_fail_step_id=0, 
@retry_attempts=0, 
@retry_interval=0, 
@os_run_priority=0, @subsystem=N'TSQL', 
@command=N'BACKUP DATABASE [DataBaseName] TO  DISK = N''D:\Backup\DataBaseName.Bak'' WITH  INIT ,  NOUNLOAD ,  NAME = N''DataBaseName Backup'',  SKIP ,  STATS = 10,  NOFORMAT', 
@database_name=N'master', 
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'DataBaseNameBackup', 
@enabled=1, 
@freq_type=4, 
@freq_interval=1, 
@freq_subday_type=1, 
@freq_subday_interval=0, 
@freq_relative_interval=0, 
@freq_recurrence_factor=0, 
@active_start_date=20110201, 
@active_end_date=99991231, 
@active_start_time=30000, 
@active_end_time=235959, 
@schedule_uid=N'47e12b03-58e7-4103-b196-f6f812f34a79'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:

GO

WITH CHECK OPTION

'WITH CHECK OPTION' Forces all data modification statements executed against the view to follow the criteria set within select_statement. 
When a row is modified through a view, the WITH CHECK OPTION makes sure the data remains visible through the view after the modification is committed.

Example:
CREATE VIEW CheckOptionTest
AS
SELECT [StamTableId], [StamTableStr], [colIntA]
FROM StamTable
WHERE [colIntA] > 5
GO

-- select #1:
select * from CheckOptionTest
GO

-- update #1:
update CheckOptionTest set [colIntA] = [colIntA] - 2
GO

-- select #2:
select * from CheckOptionTest
-- less rows than select #1 (because of the update)
GO

ALTER VIEW CheckOptionTest
AS
SELECT [StamTableId], [StamTableStr], [colIntA]
FROM StamTable
WHERE [colIntA] > 5
WITH CHECK OPTION
GO

-- update #2:
update CheckOptionTest set [colIntA] = [colIntA] - 2
GO
-- in case of rows that colIntA is not bigger from 5 in more than 2:
-- update will be failed: can't update rows from the view with values that don't follow the criteria set within the select statement.