YUKON в примерах

Начинаю знакомить с YUKON, знакомство с вещами которые понравились

Переменные типа varchar(max). Теперь при работе со строками-переменными ограничения нет
Правда varchar(max) не может быть индексирован а в базе он зранится как TEXT.
Просто многие ограничения при работе с ним сняты

snapshot isolation level - даже лучше чем в Oracle.
То есть читатели не блокируются

Recursive queries, например, можно расрыть все дерево папок одним оператором
(но для Docs у меня пока не получилось)

Использование namespaces

create schema PIKA
create schema CHOU
GO
 
create procedure PIKA.BBB as select 111
create procedure CHOU.BBB as select 222
create procedure BBB as select 333
GO
 
exec CHOU.BBB
exec PIKA.BBB
exec BBB

Блок TRY..CATCH

create table uni (n int primary key)
go
create procedure InsUni @k int
as
  begin try
    insert into uni select @k
    print 'Inserted !!!'
  end try
  begin catch 
    print 'Failed !!!'
  end catch
go
exec InsUni 7
--Inserted !!!
exec InsUni 7
--Failed !!!

Snapshot есть база замороженная во времени
Идеальное средство для бух отчетов
Создаются почти мгновенно

CREATE DATABASE WO1 ON ( NAME = 'MyDb_Data', FILENAME = 'C:DATAWO1.SS') AS SNAPSHOT OF MyDB
GO
select * from WO1..Docs
GO

DDL triggers, можно отслеживать например создания таблиц (для metadata ?)

CREATE TRIGGER safety 
ON DATABASE 
FOR CREATE_TABLE 
AS 
   PRINT 'CREATE TABLE Issued.'
   PRINT CONVERT (nvarchar (1000), EVENTDATA() )
GO

PIVOT таблицы
Хотя на самом деле это просто макрос для многочисленных case

select SPACESTRING,[10],[20],[30],[40],[50] from TABLE_CDC as x 
  PIVOT(count(x.IDCDC) for x.IDSTATUS in ([10],[20],[30],[40],[50])) as X

Хранение XML в 'родном' формате
Вот пример с реальным XML и реальной таблицей

SELECT XMLSIGNATURE,SIGNEDDOCUMENT into SIG_1 FROM SIGNATURE 
SELECT convert(XML,XMLSIGNATURE) as XMLSIGNATURE,convert(XML,SIGNEDDOCUMENT) as SIGNEDDOCUMENT 
  into SIG_2 FROM SIGNATURE 

Сравнение размеров:
SIG_1 = 16.7Mb
SIG_2 = 6.547 Mb

Само хранение нереляционных данных не революционно
Революция в том что можно в них быстро искать
Вот простой способ

-- Увы так не получится. Надо использовать функцию
alter table SIGNATURE add LegalName as convert(XML,XMLSIGNATURE).query('data(//LegalName)')
GO
 
-- Создаем функцию
create function LegalName (@t TEXT) 
  returns varchar(128) -- не varchar(max) 
  with schemabinding  -- !!!
as 
  begin 
  return convert(varchar(max),convert(XML,@t).query('data(//LegalName)')) 
  end
GO
 
-- создаем колонку
alter table SIGNATURE add LegalName as dbo.LegalName(XMLSIGNATURE)
GO
 
-- и индекс
create index IX_LegalName on SIGNATURE (LegalName)
 
-- проверка что работает
select * from SIGNATURE where LegalName='Test Benoit Signature 2'
GO

Но есть и способ куда гибче

create table SIG_3 (n int identity primary key, doc xml)
-- в таблице дожен быть PK
 
-- заполняю таблицу
insert into SIG_3 (doc) 
  select SIGNEDDOCUMENT from SIG_2 
    where SIGNEDDOCUMENT is not null

Теперь провожу эксперименты с поиском с использованием Xpath/Xquery,
время всегда это время второго выполнения

Без индекса

select count(*) from SIG_3 where 
  doc.exist('//cdcInfo[title="test steph"]')=1
à 2 lignes
CPU time = 1109 ms,  elapsed time = 1105 ms.

Теперь создаем индекс XML

create primary XML index XXX on SIG_3 (doc)
 
select count(*) from SIG_3 where 
  doc.exist('//cdcInfo[title="test steph"]')=1
à 2 lignes
CPU time = 265 ms,  elapsed time = 287 ms.

Лучше. А еще лучше с вспомошательным индексом XML

create XML index ZZZ on SIG_3 (doc) using xml index XXX for path
 
select count(*) from SIG_3 where 
  doc.exist('//cdcInfo[title="test steph"]')=1
à 2 lignes
CPU time = 47 ms,  elapsed time = 29 ms.

Замечания: collation учитывается нормально

select count(*) from SIG_3 where 
  doc.exist('//cdcInfo[title="TEST STEPH"]')=1
à 2 строки

Однако, названия полей всегда case-sensitive

select count(*) from SIG_3 where 
  doc.exist('//cdcInfo[TITLE="TEST STEPH"]')=1
à 0 строк

Надо сказать что параметр exists, valuе НЕ является строкой
Это как бы строка
Она парзится сразу и не может быть переменной
Но переменные туда все таки можно передавать:

declare @val varchar(max)
set @val='test steph'
select count(*) from SIG_3 where   
  doc.exist('//cdcInfo[title=sql:variable("@val")]')=1
à 2 строки

А вот как элегантно можно получить Nную страницу выборки, без временных таблиц.
Не напоминает rownum в Oracle ?

select * from (
  select row_number() over (order by Name desc) RNUM,
    * from Docs
  ) X where X.RNUM>=1000 and X.RNUM<1010
order by Name desc

Есть и более сложные случаи с over (partition by ... order by ...)

Forums: 

Блин, какая анлийская статья ?

Блин, какая анлийская статья ? Я сам писал
ВОт и примеры даже местами из Nexus

Получилось recursive query
Вот кверь которая выдает документы с уровнем иерархии и даже с путем ПапкаПодпапка итд

WITH Rec(Folder, Name, UDN, Lev, Path) AS 
(
    SELECT Folder, Name, UDN, 0 AS Lev, 
        convert(varchar(2000),'') as Path
      FROM Docs WHERE Folder=0
    UNION ALL
    SELECT sub.Folder, sub.Name, sub.UDN, up.Lev+1, 
        convert(varchar(2000),up.Path+'/'+sub.Name)
    FROM Docs sub INNER JOIN Rec up  ON sub.Folder = up.UDN
)
SELECT * FROM Rec
  OPTION (MAXRECURSION 10) -- чтобы если что не зацикливаться
GO

Изображение пользователя ipanshin.

Это хорошо. Еще бы кинул дис

Это хорошо.
Еще бы кинул дистрибутивчик yukon
Мда. Если все так умно, то почему так поздно? :)

Изображение пользователя st.

Блин, какая анлийс

Блин, какая анлийская статья ?

Статья или материалы с описанием юконовских новшеств, по которым ты написал свою статью с примерами из нехуса.
Ведь не телепатическим же способом ты узнал о нововведениях :)