2017年2月23日木曜日

SQL ループ文でインクリメント

ループして複数行を挿入する SQL 文を書いてみました。

テーブルはこんな構成です。







register 列は DateTime 型のデータです。ループの中では変数の @index を利用して
分(MINUTE)の部分をインクリメントして追加しています。

DECLARE @index int;
SET @index = 1;
WHILE @index < 10
BEGIN
DECLARE @toDate DATETIME = DATEADD(DAY, -1, GETDATE())
INSERT [Test1].[dbo].[TestTable] (id, name, register)
VALUES(
@index,
'user' + LTRIM(STR(@index)),
(SELECT DATEADD(MINUTE, @index, @toDate))
);
SET @index = @index + 1
END

実行すると行が複数挿入されており、分の部分が1ずつ増加しています。



2017年2月12日日曜日

ASP.NET MVC ビューにクラスインスタンスを渡す際のエラー(InvalidOperationException)

2つのモデルを結合したモデルを表示しようとしたところ、こんなエラーが出ました。

--------エラーここから--------

'/' アプリケーションでサーバー エラーが発生しました。

ディクショナリに型 'System.Collections.Generic.List`1[WordLearner.Models.WordDetail]' のモデル項目が渡されましたが、このディクショナリには型 'WordLearner.Models.WordDetail' のモデル項目が必要です。

説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

例外の詳細: System.InvalidOperationException: ディクショナリに型 'System.Collections.Generic.List`1[WordLearner.Models.WordDetail]' のモデル項目が渡されましたが、このディクショナリには型 'WordLearner.Models.WordDetail' のモデル項目が必要です。

--------エラーここまで--------

調べてみると同じエラーで困っている人がいました。
Unable to cast object of type 'System.Data.Entity.Infrastructure.DbQuery`1[]' using linq lambda expression
http://stackoverflow.com/a/22918838

そして回答も掲載されていました。今回検索結果のオブジェクトをビューに返すところを、クエリの状態でビューに渡しているのが原因でした💨
変数 query に FirstOrDefault() メソッドでオブジェクトを取得することで解決しました。

public ActionResult Test(int? id)
{
  if (id == null)
  {
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }
  Word word = db.Word.Find(id);
  if (word == null)
  {
      return HttpNotFound();
  }

  int _id = id.Value;
  var meaning = db.Meanings;
  var query = from x in db.Word
            join y in meaning on x.ID equals y.WordID
            where x.ID.Equals(_id)
            select new WordDetail
            {
                ID = x.ID,
                Spelling = x.Spelling,
                Meaning = y.Meaning
            };

  return View("Details", query.FirstOrDefault());
}

2017年2月11日土曜日

C# Linq によるオブジェクトの結合

C# Linq を使って、2つのオブジェクトを結合した結果を取得します。

データベースのテーブルはこうなっています。










private WordLearnerDataContext db = new WordLearnerDataContext();

public ActionResult Index()
{
    var words = db.Words;
    var meanings = db.Meanings;

    var query = from x in words
                join y in meanings on x.ID equals y.WordID
                select new { ID = x.ID, Word = x.Word, Meaning = y.Meaning };

    foreach (var item in query)
    {
        Debug.WriteLine("{0}: {1} = {2}", item.ID, item.Word, item.Meaning);
    }

    return View(query.AsQueryable());
}


実行結果

901: deposit = (お金を)預ける
902: evolve         = 進化する

2017年2月5日日曜日

SQL CASE 式の使い方

CASE 式を使って条件に応じた値を出力してみます。

select 
社員コード, 氏名, 在籍支社,/* テーブルに既存の列 */
case 在籍支社
 when '東京本社' then '関東'
 when '大阪支社' then '関西'
 else 'その他'
end as '在籍地域' /*CASE 式で取得した列の名前*/
 from 社員


実行結果

SQL Server 2014 に Northwind データベース(日本語版)をインストール

日本語版の Northwind データベースをインストールする方法をメモします。

SQLQuality さんという会社がデータベースのスクリプトファイルを公開して下さっているので、ありがたく利用させて頂きました。


1.SQL スクリプトの取得

SQL Server 2014 自習書シリーズ (HTML 版) 「No.5 Microsoft Azure SQL Database 入門」
http://www.sqlquality.com/Self2014/Self2014_AzureSQLDB/Text/Step04-02.html

→「サンプル スクリプト」というリンクに「NorthwindJ.sql」が含まれていますので、テキストエディタで開きます。NorthwindJ.sql に含まれる SQL 文を全部コピーします。

※ Northwind(英語版)のスクリプトはこちらで公開されています。


2.SQL Server Management Studio で SQL 文を実行

「新しいクエリ」をクリックし、クエリエディターを開きます。
1でコピーした SQL 文をクエリエディターに貼り付け、「実行」をクリックします。(もしくは NorthwindJ.sql を Management Studio で直接開いて実行しても OK です。)

→クエリを実行し、完了となれば終わりです。