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 です。)

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