3/16(木) 三木会 で 列ストアインデックスのお話しします

3/16(木) Insight Technology 様が主催している 三木会 で SQL Server の列ストアインデックス のお話しをさせていただきます。
[2017/03/16(木): 三木会] SQL Server の 列ストアインデックス 入門 | Insight Technology, Inc.
内容は 列ストアって何?ってところから順に掘り下げていく予定です。
梅田のグランフロントで開催しますのでお近くの方は是非ご参加を~。

Application Insights JavaScript browserTimings の メモ

networkDuration / sendDuration / receivedDuration / prosessiongDuration とかって何の時間かっての調べた時のメモ。
ApplicationInsights-JS/PageViewPerformance.ts at 4620cfdc47975f2e32e82f63c693f9b88fa50568 · Microsoft/ApplicationInsights-JS · GitHub

ソースのコメント見たかんじ、本家はここなんかな?
Navigation Timing

Japanese_XJIS_140 って _SC 指定出来ないけど、どないなん?

SQL Server 2012 で追加された照合順序で何ができるようになった? at SE の雑記

の検証クエリを拝借しました。

CREATE TABLE dbo.TblTest
(
Col1 nvarchar(50) COLLATE Japanese_XJIS_100_CI_AS NULL,
Col2 nvarchar(50) COLLATE Japanese_XJIS_100_CI_AS_SC NULL,
Col3 nvarchar(50) COLLATE Japanese_XJIS_140_CI_AS NULL
)
GO

INSERT INTO TblTest VALUES(N'森鷗外𠮟る', N'森鷗外𠮟る', N'森鷗外𠮟る')
INSERT INTO TblTest VALUES(N'森鴎外叱る', N'森鴎外叱る', N'森鴎外叱る')

SELECT LEFT(Col1, 4), LEFT(Col2, 4), LEFT(Col3, 4),* FROM TblTest
SELECT * FROM TblTest WHERE Col1 LIKE N'森鷗外_る'
SELECT * FROM TblTest WHERE Col2 LIKE N'森鷗外_る'
SELECT * FROM TblTest WHERE Col3 LIKE N'森鷗外_る'

_SC ありの時と同じ動作のように見えますね。

照合順序に KI、WI はないですよー

照合順序について調べてて、KI、WI について書いてるページがあったので。
正しくは、省略して何も指定しないです。

例:列の照合順序を変える

-- 全部区別する場合
alter table t alter column col char(10) collate JAPANESE_XJIS_140_CS_AS_KS_WS
-- 全部区別しない場合
alter table t alter column col char(10) collate JAPANESE_XJIS_140_CI_AI

SQL Server の照合順序 - マイクロソフト系技術情報 Wiki
このサイトが参考にしているサイトが
照合順序 – 文字の比較と並び順 (その 1) – Microsoft SQL Server Japan Support Team Blog
でした。
Team Blog じゃないですかーということで、コメントで連絡してみました。
そのうち直るはず。

公式はこちらで。
照合順序と Unicode のサポート

vNext と SQL DB(v12) で、Japanese_XJIS_140 が使えるようになってるけど、_SC 指定できない。
どっちの動作になってるのかな?後で試す。

OUTPUT 句で FK 付テーブルに INTO する時のメモ

OUTPUT 句 (Transact-SQL)
今日気付いたのですが、INTO 先のテーブルには FOREIGN KEY 付いてるとダメという制約がありました。

幾つかの回避方法があると思いますが、ここでは テーブル変数 に退避してからという方法のメモです。
※FK を一旦無効にしてから OUTPUT で INTO したあと再度 FK 有効にするってやり方もあります。

対処方法のメモ

create table [ユーザー] (
    [ID] int not null primary key, 
    [名前] nvarchar(10) not null 
)
create table [通知] (
    [ID] int not null primary key, 
    [種類] nvarchar(10) not null, 
    [内容] nvarchar(100)
)
create table [ユーザーへの通常通知] (
    [ユーザーID] int not null references [ユーザー]([ID]), 
    [通知ID] int not null references [通知]([ID]), 
    [日時] datetime2(0) not null, 
    primary key([ユーザーID], [通知ID])
)

insert into [ユーザー] ([ID], [名前])
values (1, N'一郎'), (2, N'二郎'), (3, N'三郎')

insert into [通知] ([ID], [種類], [内容])
values (1, N'定期', N'一郎さん。お元気ですか?')
, (2, N'定期', N'二郎さん。お元気ですか?')
, (3, N'定期', N'三郎さん。お元気ですか?')
, (4, N'アラート', N'三郎さん。不明な端末でログイン試行されました。')
, (5, N'セキュリティ', N'三郎さん。パスワードリセット要求。')
, (6, N'アラート', N'一郎さん。アカウントロックされました。')

insert into [ユーザーへの通常通知] ([ユーザーID], [通知ID], [日時])
values (1, 1, '2017-02-01 12:34:56')
, (2, 2, '2017-02-02 20:02:01')
, (3, 3, '2017-02-03 02:11:48')
, (3, 4, '2017-02-07 19:02:32')
, (3, 5, '2017-02-07 19:09:51')
, (1, 6, '2017-02-08 12:45:20')

select * from [ユーザー]
select * from [通知]
select * from [ユーザーへの通常通知]


ってのがあったときに、アラート通知の紐づけは別テーブルにしよう!と変更したとします。
テーブルを作って、

create table [ユーザーへのアラート通知] (
    [ユーザーID] int not null references [ユーザー]([ID]), 
    [通知ID] int not null references [通知]([ID]), 
    [日時] datetime2(0) not null, 
    primary key([ユーザーID], [通知ID])
)

データを移行します。

delete from [ユーザーへの通常通知]
output deleted.* into [ユーザーへのアラート通知] -- 列名は同じ順序なので省略
where exists (
    select * from [通知]
    where [通知].[ID] = [ユーザーへの通常通知].[通知ID]
      and [通知].[種類] = N'アラート'
)

これがエラーになります。

メッセージ 332、レベル 16、状態 1、行 99
OUTPUT INTO 句の対象のテーブル 'ユーザーへのアラート通知' を、(主キー、外部キー) リレーションシップのどちらにも配置できません。参照制約 'FK__ユーザーへのアラー__ユーザーI__6477ECF3' が見つかりました。

FK があるとダメーと言われました。
というわけで、一旦テーブル変数に INTO してから移行します。

declare @t table (
    [ユーザーID] int not null, 
    [通知ID] int not null, 
    [日時] datetime2(0) not null
)
delete from [ユーザーへの通常通知]
output deleted.* into @t -- 列名は同じ順序なので省略
where exists (
    select * from [通知]
    where [通知].[ID] = [ユーザーへの通常通知].[通知ID]
      and [通知].[種類] = N'アラート'
)
insert into [ユーザーへのアラート通知]
select * from @t

select * from [ユーザーへの通常通知]
select * from [ユーザーへのアラート通知]

出来上がり!

クエリ全文

create table [ユーザー] (
    [ID] int not null primary key, 
    [名前] nvarchar(10) not null 
)
create table [通知] (
    [ID] int not null primary key, 
    [種類] nvarchar(10) not null, 
    [内容] nvarchar(100)
)
create table [ユーザーへの通常通知] (
    [ユーザーID] int not null references [ユーザー]([ID]), 
    [通知ID] int not null references [通知]([ID]), 
    [日時] datetime2(0) not null, 
    primary key([ユーザーID], [通知ID])
)

insert into [ユーザー] ([ID], [名前])
values (1, N'一郎'), (2, N'二郎'), (3, N'三郎')

insert into [通知] ([ID], [種類], [内容])
values (1, N'定期', N'一郎さん。お元気ですか?')
, (2, N'定期', N'二郎さん。お元気ですか?')
, (3, N'定期', N'三郎さん。お元気ですか?')
, (4, N'アラート', N'三郎さん。不明な端末でログイン試行されました。')
, (5, N'セキュリティ', N'三郎さん。パスワードリセット要求。')
, (6, N'アラート', N'一郎さん。アカウントロックされました。')

insert into [ユーザーへの通常通知] ([ユーザーID], [通知ID], [日時])
values (1, 1, '2017-02-01 12:34:56')
, (2, 2, '2017-02-02 20:02:01')
, (3, 3, '2017-02-03 02:11:48')
, (3, 4, '2017-02-07 19:02:32')
, (3, 5, '2017-02-07 19:09:51')
, (1, 6, '2017-02-08 12:45:20')

select * from [ユーザー]
select * from [通知]
select * from [ユーザーへの通常通知]
go

create table [ユーザーへのアラート通知] (
    [ユーザーID] int not null references [ユーザー]([ID]), 
    [通知ID] int not null references [通知]([ID]), 
    [日時] datetime2(0) not null, 
    primary key([ユーザーID], [通知ID])
)
go

-- エラーになる!
delete from [ユーザーへの通常通知]
output deleted.* into [ユーザーへのアラート通知] -- 列名は同じ順序なので省略
where exists (
    select * from [通知]
    where [通知].[ID] = [ユーザーへの通常通知].[通知ID]
      and [通知].[種類] = N'アラート'
)
go

declare @t table (
    [ユーザーID] int not null, 
    [通知ID] int not null, 
    [日時] datetime2(0) not null
)
delete from [ユーザーへの通常通知]
output deleted.* into @t -- 列名は同じ順序なので省略
where exists (
    select * from [通知]
    where [通知].[ID] = [ユーザーへの通常通知].[通知ID]
      and [通知].[種類] = N'アラート'
)
insert into [ユーザーへのアラート通知]
select * from @t

select * from [ユーザーへの通常通知]
select * from [ユーザーへのアラート通知]
go

-- 後片付け
drop table [ユーザーへのアラート通知]
drop table [ユーザーへの通常通知]
drop table [通知]
drop table [ユーザー]

2/18(土) 第19回 中国地方DB勉強会 in 米子 で SQL Server / T-SQL のお話しします

第19回 中国地方DB勉強会 in 米子 - connpass

中国地方DB勉強会初参加ー!楽しみです。
鳥取行くの初めてじゃないかな?

初めて参加する勉強会なので、お話しする内容をちょっと悩んでます。 タイトル通りの T-SQL のお話しで良いのか、SQL Server 寄りの方が良いのか…。

是非ご参加を~。

1/24(火) SQLWorld★大阪#40 開催します

2週間前の告知! SqlWorld :: SQLWorld★大阪#40 開催します。22回目の平日夜開催で、前回同様 ハンズオン 形式行う予定です。

【日時】
2017年1月24日(火曜日) 19:00~21:00
 

【イベント概要】
SQLWorld 22回目の平日夜開催~。今回も、みんなで SQL を書いてみようというハンズオン企画です!ブラウザがあれば参加出来るようにしていますので、iPad 等のタブレットでも大丈夫です。
 

【会場】
フェンリル株式会社さま大阪本社 http://www.fenrir-inc.com/
〒530-0011 大阪府大阪市北区大深町 3番1号 グランフロント大阪タワーB(オフィス)
 

【参加費】
無料
 

【持ち物】
パソコン/タブレット (DB のインストールは不要です。)
 

【参加可能人数】
13 人
 

お題に沿って、SQL を書いてみようという勉強会です。是非ご参加を~。

開催回数は増えていっていますが、続き物というわけでは無いので初めて参加される方でもお気軽にどぞー。