T-SQLでOUTPUT句を使う
OUTPUT句って結構便利だと思っているんですが、そうそう使わないこともあってなかなか覚えられないorz
そんなわけでサンプルを書いてみました。
まずは書き方
何はともあれ、MSDN参照しましょう。
SQLServer2005から使えるようです。
insert into [table] output inserted.* values ( 'hoge' ) update [table] set [colName] = 'po' output deleted.*, inserted.* where [colName] = 'aiueo' delete from [table] output deleted.* where [colName] = '123456789'
ついでにやりたいことの実験
複数のプロセスから重複なく指定件数だけ更新したい。
かつ更新したレコードが欲しい。
テスト用のテーブルを用意。
create table test(id Integer, kind Integer, memo nvarchar(max), assignedName nvarchar(max)); --delete test; declare @idx int; set @idx = 0; while @idx < 10000 begin insert test values(@idx, @idx % 3, 'hoge', Null); set @idx = @idx + 1; end;
サンプルコードを用意。
理解が怪しいところがあるので、大丈夫だろうか。(; ̄ー ̄A
//using Dapper; static void Main(string[] args) { var list = new SynchronizedCollection<Test>(); ThreadPool.SetMinThreads(200, 200); Parallel.ForEach( Enumerable.Range(0, 300), new ParallelOptions { MaxDegreeOfParallelism = 200 }, num => { Console.WriteLine(string.Format("BEGIN:{0}", num)); var data = GetData(0, num.ToString()).Result; foreach (var item in data) { list.Add(item); Console.WriteLine(string.Format("Num:{0}, Id:{1}", num, item.Id)); } Console.WriteLine(string.Format("END:{0}", num)); }); Console.ReadLine(); } public async static Task<IEnumerable<Test>> GetData(int kind, string name) { var str = @"接続文字列"; using (var con = new SqlConnection(str)) { con.Open(); using (var tran = con.BeginTransaction()) { var result = await con.QueryAsync<Test>("Update Top (10) test set assignedName = @Name output inserted.id, inserted.Kind where (kind = @Kind) and (assignedName IS NULL)", new { Kind = kind, Name = name }, tran); tran.Commit(); return result; } } } public class Test { public int Id { get; set; } public int Kind { get; set; } public string Memo { get; set; } public string AssignedName { get; set; } }
実行結果
今のところ大体思った通り動いてる。