Windows ネットワークをワークグループからドメインに変更したら、SQL Server に外部から接続できなくなった

原因は Windows ファイアウォールでした。

セキュリティが強化された Windows ファイヤウォールの受信の規則から「sqlservr.exe」のプロパティを開き、詳細設定タブのプロファイルにあるドメインにチェックを付けます。

これで無事外部から接続できるようになりました。めでたしめでたし。

Mongoose の Document インスタンスにプロパティを追加しての JSON 化

Node.js + Express + Mongoose で MongoDB から取得した Document インスタンスにいくつかのプロパティを追加して JSON で返す Web API を作っていたんですが、プロパティを追加した Document インスタンスをそのまま res.send で送っても追加したプロパティが JSON に含まれません。書いていたコードはこんな感じ。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var Doc = new Schema({
  title: String,
  body: String
});

mongoose.model('Doc', Doc);

...

app.get('/api/docs', function(req, res) {
  mongoose.model('Doc').find({}, function(err, docs) {
    docs.forEach(function(d) { d.comment = 'hoge'; });
    res.send(docs);
  });
});

調べてみると、(そもそも Document に値を追加するには setValue を使うようだったんですけど、)どうも Document には toJSON が実装されているみたいで、そこでは純粋な MongoDB のドキュメントの部分だけを JSON にするようになっているようです。

で、今回の場合だと色々方法はあるとは思いますが、toObject で取得したドキュメントにプロパティを追加して返すのが良さそうだったので、下記のように書き換えて無事成功。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var Doc = new Schema({
  title: String,
  body: String
});

mongoose.model('Doc', Doc);

...

app.get('/api/docs', function(req, res) {
  mongoose.model('Doc').find({}, function(err, docs) {
    res.send(docs.map(function(d) {
      var obj = d.toObject();
      obj.comment = 'hoge';
      return obj;
    }));
  });
});

SQL Server のテーブル型の使い方を整理してみた

一応仕事で SQL Server は触っていて、テーブル型についても仕事で必要になった範囲でなんとなく使ってたんですけど、ちょっと応用したことをしようとしたらどう書けばいいのかわからなくなったので、自分の中で整理することにしました。

テーブル型変数の宣言

DECLARE @Table TABLE(
  Id int NOT NULL,
  Name varchar(20) NOT NULL
)

テーブル型変数を使った SELECT

SELECT * FROM @Table

テーブル型変数への INSERT

INSERT INTO @Table VALUES(1, 'Hoge')

テーブル型変数の UPDATE

UPDATE @Table SET name = name + '1'

テーブル型変数の DELETE

DELETE FROM @Table

インラインテーブル値関数

RETURNS には TABLE とだけ書いて、ボディには BEGIN-END を書かず、RETURN に戻り値のクエリを書く。

CREATE FUNCTION dbo.InlineTableValued()
RETURNS TABLE
AS
RETURN
  SELECT 1 Id, 'Hoge' Name
  UNION ALL
  SELECT 2 Id, 'Fuga' Name
  UNION ALL
  SELECT 3 Id, 'Homu' Name
GO

SELECT * FROM dbo.InlineTableValued()

@Table

id name
1 Hoge
2 Fuga
3 Homu

複数ステートメントのテーブル値関数

RETURNS に戻り値として返すテーブル型変数を宣言して、ボディの最後には RETURN だけ書く。

CREATE FUNCTION dbo.MultiStatementTableValued()
RETURNS @Table TABLE (
  Id int NOT NULL,
  Name varchar(20) NOT NULL
)
AS
BEGIN

INSERT INTO @Table VALUES(1, 'Hoge')
INSERT INTO @Table VALUES(2, 'Fuga')
INSERT INTO @Table VALUES(3, 'Homu')

RETURN

END
GO

SELECT * FROM dbo.MultiStatementTableValued()

@Table

id name
1 Hoge
2 Fuga
3 Homu

プロシージャ内で発行したクエリの結果をテーブル型変数に INSERT する

CREATE PROCEDURE dbo.PROC1
AS
BEGIN
  SELECT 1 Id, 'Hoge' Name
  UNION ALL
  SELECT 2 Id, 'Fuga' Name
  UNION ALL
  SELECT 3 Id, 'Homu' Name
RETURN 0
END
GO

DECLARE @Table TABLE(
  Id int NOT NULL,
  Name varchar(20) NOT NULL
)

INSERT INTO @Table EXECUTE dbo.PROC1

SELECT * FROM @Table

@Table

id name
1 Hoge
2 Fuga
3 Homu

SQL Serverで動的に生成したSQLを実行する

EXECUTE や sp_executesql で文字列の SQL 文を実行できるので、これらを使えば動的に生成したクエリを実行できます。

-- EXECUTEステートメントでの実行例。
EXECUTE (N'SELECT * FROM sys.objects')

-- 変数を使った実行例。
DECLARE @sql NVARCHAR(200)
SET @sql = N'SELECT * FROM sys.objects'
EXECUTE (@sql)

-- sp_executesql の使用例。
EXECUTE sp_executesql
  N'SELECT * FROM sys.objects WHERE type = @type', 
  N'@type CHAR(2)', @type = 'U'

FormsAuthentication.RedirectToLoginPage を実行してもページの実行が止まらない

ここに書いてありました。

http://lonetechie.com/2009/05/14/formsauthenticationredirecttologinpage-does-not-stop-page-execution/

FormsAuthentication.RedirectToLoginPage の後に、Response.End を呼ばないと止まらないそうです。RedirectToLoginPage の引数に渡していたクエリ文字列も Response.End することでちゃんとセットされるようになりました。MSDNには Response.End なんて書いてなかったのにヽ(`Д´)ノ

DatePicker のインライン表示

jQuery UI の DatePicker がインライン表示できることに全然気づいていなかったのでメモ。
とりあえず2か月分のカレンダーをインラインで表示するサンプルを書いてみました。
カレンダーで選択された日付を hidden 要素にセットしてみました。

<html>
<head>
  <title>DatePicker インライン表示</title>
  <link href="css/ui-lightness/jquery-ui-1.8.10.custom.css" rel="stylesheet" type="text/css"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>&#160;
</head>
<body>
  <div id="datepicker"></div>
  <input type="hidden" id="selectedValue" />
  <button type="button" id="btnShow">選択された日付を表示する</button>

  <script type="text/javascript">
  $(document).ready(function() {
    $("#datepicker").datepicker({
      numberOfMonths: 2,
      onSelect: function(dateText, inst) { $("#selectedValue").val(dateText); }
    });
    $("#btnShow").click(function() { alert($("#selectedValue").val()); });
  });
  </script>
</body>
</html>

上の HTML をブラウザで表示するとこんな感じ。

日付を選択してボタンを押すとこんな感じ。