What is New for T-SQL in SQL Server 2012 & SQL Azure Tobias Ternström Senior Program Manager Lead, SQL Engine
Our organization SQL Server RDBMS Team Applications and Components External Apps Excel Project Server Content Management Server MOM MS CRM Outlook Visual Studio Dynamics LCS Commerce Server Oslo Exchange Biztalk Server Sharepoint DPM SQL Replication SQL Management Tools SQL Reporting Services SQL Analysis Services SQL Integration Services SQL Server RDBMS Team Connectivity MDAC ODBC, OLE-DB SNAC ODBC, OLE-DB EDM Ado.Net SQL Client JDBC App Platform T-SQL Language, Data-Tier Application Model, Types, Libraries SQL Engine Query Processor Query Opimization & Execution Storage & Admin Storage Engine, DR etc. High Availability Mirroring, Clustering, etc.
Overview New Query & Schema Constructs Improved Error Handling Additional Scalar Functions Robust Metadata Discovery Improvements to Dynamic SQL
Simplified Paging & UTF-16 Support for Simplified Paging SELECT . . . ORDER BY ... OFFSET <expr> ROWS FETCH NEXT <expr> ROWS ONLY Support for UTF-16, introducing _SC collations Common Unicode characters occupy 16-bits each (NCHAR / NVARCHAR) Rarer Unicode characters occupy 2 x 16-bits each “Supplementary Characters”, “Surrogate Pairs” Ancient scripts; Music Notation; Math Symbols etc. Available in SQL Azure Now!
Sequence Generators New Database Object, similar to the IDENTITY property Separates number-generation from column and table ANSI standard compliant implementation CREATE SEQUENCE MySchema.IdSequence AS INT START WITH 10000 INCREMENT BY 1; GO INSERT INTO Employees (EmployeeId, Name) VALUES (NEXT VALUE FOR MySchema.IdSequence, 'Jane'); INSERT INTO Contractors (ContractorId, Name) VALUES (NEXT VALUE FOR MySchema.IdSequence, 'John');
Sequence Generators CREATE SEQUENCE [ schema_name . ] sequence_name [ AS { <built_in_integer_type> | <user-defined_integer_type> } ] [ START WITH <constant> ] [ INCREMENT BY <constant> ] [ MINVALUE <constant> | NO MINVALUE ] [ MAXVALUE <constant> | NO MAXVALUE ] [ CYCLE | NO CYCLE ] [ CACHE [<constant> ] | NO CACHE ]
Sequence Generators Generates a Predictable number of values SELECT NEXT VALUE FOR MySequence ,…. FROM MyTable; Generates a Predictable number of values Achieved by restricting where NEXT VALUE FOR can be used Supported in DEFAULT-constraints Semantically correct support for generating values based on an order (extension to ANSI) SELECT NEXT VALUE FOR MySeq OVER (ORDER BY OrderDate ASC) AS OrderId ,OrderDate ,CustomerId FROM Orders; Generate a range using sp_sequence_get_range
Extended support for Window Functions SQL:2008 Compliant Functionality Windowed Aggregates OVER (<partition_clause> <order_clause> <frame_clause> ) New Ranking Functions CUME_DIST, PERCENT_RANK Inverse Distribution Functions PERCENTILE_CONT, PERCENTILE_DISC LAG / LEAD Functions FIRST_VALUE / LAST_VALUE Functions
Extended support for Window Functions <partition_clause> <order_clause> Full support for ordering <frame_clause> Full support for ROWS RANGE supports well-known bounds only Supported Aggregates COUNT , COUNT_BIG, SUM, AVG, MIN, MAX STDEV, STDEVP, VAR, VARP, CHECKSUM_AGG
Extended support for Window Functions RANGE/ROWS units ROWS | RANGE BETWEEN <B1> AND <B2> ROWS | RANGE <B1> B1 and B2 can be any of UNBOUNDED PRECEDING UNBOUNDED FOLLOWING CURRENT ROW For ROWS only <scalar expression> PRECEDING <scalar expression> FOLLOWING For short form FOLLOWING cannot be used Notes B1 must be less or equal to B2, otherwise NULL is returned (except for COUNT) New conditional keywords: UNBOUNDED, PRECEDING, FOLLOWING, ROWS, RANGE, CURRENT ROW Short form with left border only (right border is current row) Full form with left and right border ROWS BETWEEN 10 PRECEDING AND 5 PRECEDING is OK
<frame_clause> Supported framing options ROWS UNBOUNDED PRECEDING ROWS <unsigned integer literal> PRECEDING ROWS CURRENT ROW ROWS BETWEEN UNBOUNDED PRECEDING AND <unsigned integer literal> PRECEDING ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ROWS BETWEEN UNBOUNDED PRECEDING AND <unsigned integer literal> FOLLOWING ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ROWS BETWEEN <unsigned integer literal> PRECEDING AND <unsigned integer literal> PRECEDING ROWS BETWEEN <unsigned integer literal> PRECEDING AND CURRENT ROW ROWS BETWEEN <unsigned integer literal> PRECEDING AND <unsigned integer literal> FOLLOWING ROWS BETWEEN <unsigned integer literal> PRECEDING AND UNBOUNDED FOLLOWING ROWS BETWEEN CURRENT ROW AND CURRENT ROW ROWS BETWEEN CURRENT ROW AND <unsigned integer> FOLLOWING ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ROWS BETWEEN <unsigned integer literal> FOLLOWING AND <unsigned integer> FOLLOWING ROWS BETWEEN <unsigned integer literal> FOLLOWING AND UNBOUNDED FOLLOWING RANGE UNBOUNDED PRECEDING RANGE CURRENT ROW RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING RANGE BETWEEN CURRENT ROW AND CURRENT ROW
SQL Server Code-named Denali New Query & Schema Constructs Improved Error Handling Additional Scalar Functions Robust Metadata Discovery Improvements to Dynamic SQL
The Error Handling Quiz What is returned to the client? a) Error b) Error & Hello RAISERROR(‘Error‘, 10, 1); PRINT ‘Hello‘; RAISERROR(‘Error‘, 16, 1); PRINT ‘Hello‘; RAISERROR(‘Error‘, 20, 1); PRINT ‘Hello‘; RAISERROR(‘Error‘, 20, 1) WITH LOG; PRINT ‘Hello‘; CREATE PROC sp1 AS RAISERROR(‘Error‘, 11, 1); PRINT ‘Hello‘; CREATE PROC sp2 AS RAISERROR(‘Error‘, 10, 1); PRINT ‘Hello‘; EXEC sp1; EXEC sp2; BEGIN TRY EXEC sp1; END TRY BEGIN CATCH END CATCH BEGIN TRY EXEC sp2; END TRY BEGIN CATCH END CATCH
Available in SQL Azure Now! What is in Denali? Introducing THROW which… always THROWs is even spelled correctly! Syntax THROW <number>, <message>, <state>; Batch aborts if not in SET XACT_ABORT ON where it Transaction-aborts Does not automatically use sys.messages re-THROW BEGIN CATCH …; THROW; END CATCH Available in SQL Azure Now!
SQL Server Code-named Denali New Query & Schema Constructs Improved Error Handling Additional Scalar Functions Robust Metadata Discovery Improvements to Dynamic SQL
Additional Scalar Functions Available in SQL Azure’s Next SR New conversion functions for all types: TRY_CONVERT(data_type[(length)], [,style]) TRY_CAST(expression AS data_type[(length)]) New conversion functions to and from strings: FORMAT(value, format [,culture]) PARSE(string_value AS data_type [USING culture]) TRY_PARSE(string_value AS data_type [,USING culture]) Other functions: IIF(boolean expr, true_value, false_value) CHOOSE(index,val1,val2 [,valN]) CONCAT(val1, val2…[,valn])
Additional Scalar Functions Available in SQL Azure’s Next SR New date & time related functions: EOMONTH(date [, months_to_add]) DATEFROMPARTS(year, month, day) TIMEFROMPARTS(hour, minutes, seconds, fractions, scale) DATETIME2FROMPARTS(year, month, day ,hour, minutes, seconds, fractions, scale) DATETIMEFROMPARTS(year, month, day, hour, minutes, seconds, milliseconds) SMALLDATETIMEFROMPARTS(year, month, day, hour, minutes)
SQL Server Code-named Denali New Query & Schema Constructs Improved Error Handling Additional Scalar Functions Robust Metadata Discovery Improvements to Dynamic SQL
Robust Result set Metadata Discovery or Finally replacing SET FMTONLY ON SET FMTONLY ON; IF(…) SELECT a FROM t1; ELSE SELECT b FROM t2; SET FMTONLY OFF; EXEC sp_describe_first_result_set @tsql = N' IF(…) SELECT a FROM t1; ELSE SELECT b FROM t2; '; What is the big difference?
Robust Result set Metadata Discovery Pre-Denali option is to use SET FMTONLY ON which is sadly broken... What will this batch return using FMTONLY? IF (...) SELECT a, b FROM t1; ELSE SELECT c, d, e FROM t2;
Robust Result set Metadata Discovery SET FMTONLY is replaced by ... Result set metadata discovery sp_describe_first_result_set dm_exec_describe_first_result_set dm_exec_describe_first_result_set_for_object Parameter metadata discovery sp_describe_undeclared_parameters Jedi mind trick! Available in SQL Azure Now!
Robust Metadata Discovery for Result sets – The Guranatee The semantics of sp_describe_first_result_set provide a guarantee that if the procedure returns the first result-set metadata for some batch B, and that batch is subsequently executed with no relevant schema changes on the server, other than creating a temporary table or table variable in the batch B, between the time sp_describe_first_result_set is called and the time the result set is returned during execution (including schema changes made by the batch B), then either the batch raises an optimization-time or run-time error, the batch returns no result-set or the first result-set returned by the batch will have the same metadata that sp_describe_first_result_set described (the name, nullability and data type can differ as described under section “d” above). In case sp_describe_first_result_set returnes an empty result-set, the guarantee is that the execution of the batch will return no result-sets.
… simplified sp_describe_first_result_set analyzes batch B and returns result set metadata M. When batch B is executed, a result set with metadata M is returned, no result set is returned, or an error is returned.
Examples a{int}, b{int} a{int}, b{int} a{int} a{nvarchar(50)} Batch FMTONLY Metadata Discovery IF(…) SELECT a{int}, b{int}FROM t1; ELSE SELECT d{int} AS a, e{int} AS b FROM t2; SELECT a{nvarchar(max)} FROM t3; a{int}, b{int} a{int}, b{int} IF(…) SELECT a{int} FROM t1; ELSE SELECT d{int} + g{smallint} FROM t2; a{int} <none>{int} IF(…) SELECT a{nvarchar(50)} FROM t1; ELSE SELECT a{nvarchar(120)} FROM t2; a{nvarchar(50)} a{nvarchar (120)} IF(…) SELECT a{int}, b{int} FROM t1; ELSE SELECT a{varchar(50)}, b{int} FROM t2; ERROR: Type mismatch
SQL Server Code-named Denali New Query & Schema Constructs Improved Error Handling Additional Scalar Functions Robust Result set Metadata Discovery Improvements to Dynamic SQL
Improvements to Dynamic SQL Support for defining a contract for returned result set(s) EXECUTE <proc|clr proc|remote proc|function> [WITH <execute_option>[,...n ]] { RESULT SETS {UNDEFINED|NONE |(<result_sets_definition>)} } <result_sets_definition> ::= { <result_set_definition> |AS OBJECT [<object_location>.]{table_name| view_name | tvf} |AS TYPE [schema_name.]table_type_name |AS FOR XML | (…) [,...n ]} Available in SQL Azure Now! EXEC(@SQL) WITH RESULT SETS ( (ObjectID BIGINT, Name NVARCHAR(100)) ); EXEC(@SQL) WITH RESULT SETS (AS OBJECT Sales.OrdersView); EXEC(@SQL) WITH RESULT SETS NONE;
Enforcing the contract Batch Metadata Discovery Runtime EXEC('SELECT a{int} FROM t1') WITH RESULT SETS ((b INT)); b{int} EXEC('SELECT a{tinyint} FROM t1') WITH RESULT SETS ((b INT)); EXEC('SELECT a{datetime2} FROM t1') WITH RESULT SETS ((b INT)); ERROR: Msg 206, Operand type clash… EXEC('SELECT a{int}, b{int} FROM t1') WITH RESULT SETS ((b INT)); ERROR: Number of columns mismatch
For attending this session and PASS SQLRally Nordic 2011, Stockholm THANK YOU! For attending this session and PASS SQLRally Nordic 2011, Stockholm