データベースの変更が通知できるのね

おかわりありませんか? −SqlDependency

今回の作品では、5秒ごとに更新されるデータベースの値に追随する必要がある。
じゃあちょいちょいコマンドを飛ばそうかと思っていたのだが、
有益な情報を得たのでメモメモ。

わんくまBBS


なんでも、SQLServer上で値が更新された事を、
クライアントに通知してくれる機能があるらしい。
(実際には、1プロセスを占有してクライアントが監視し続けるんだそうな)

さっそく試してみよう

msdnのチュートリアルを見つけ、さっそく書いてみることに。

かりかり。


動作させてみた

どれどれ。実行!

無題
NotSupportedException はハンドルされませんでした。
通知機能を使用するにはSQL Server 9.0以降が必要です。
がくり。

そうか・・・開発環境はSQL Server 2000だった。
本番環境は最新だったはずだけど、テストできないと辛いな・・・


使ったソースコード

msdnから拾ったコードを乗せとく。いつかまた見たくなるかも知れないので。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Data.SqlClient;
  10. using System.Security.Permissions;
  11. namespace SqlNotifyingTest
  12. {
  13. public partial class Form1 : Form
  14. {
  15. public Form1()
  16. {
  17. InitializeComponent();
  18. }
  19. // Following are the declarations used in this program.
  20. private string statusMessage;
  21. private DataSet myDataSet = null;
  22. private SqlConnection connection = null;
  23. private SqlCommand command = null;
  24. private string connstr;
  25. private void button1_Click(object sender, EventArgs e)
  26. {
  27. // Remove any existing dependency connection, then create a new one.
  28. connstr = "Data Source=MANHATTAN;Initial Catalog=SolarMonitorMobile;Persist Security Info=True;User ID=sa;Password=81at84;";
  29. string ssql = "select * from THATSUDEN_KIROKU ";
  30. SqlDependency.Stop(connstr);
  31. SqlDependency.Start(connstr);
  32. if (connection == null)
  33. connection = new SqlConnection(connstr);
  34. if (command == null)
  35. command = new SqlCommand(ssql, connection);
  36. if (myDataSet == null)
  37. myDataSet = new DataSet();
  38. GetAdvtData();
  39. }
  40. private void GetAdvtData()
  41. {
  42. myDataSet.Clear();
  43. // Ensure the command object does not have a notification object.
  44. command.Notification = null;
  45. // Create and bind the SqlDependency object to the command object.
  46. SqlDependency dependency = new SqlDependency(command);
  47. dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
  48. using (SqlDataAdapter adapter = new SqlDataAdapter(command))
  49. {
  50. adapter.Fill(myDataSet, "THATSUDEN_KIROKU");
  51. dataGridView1.DataSource = myDataSet;
  52. dataGridView1.DataMember = "THATSUDEN_KIROKU";
  53. }
  54. }
  55. private bool EnoughPermission()
  56. {
  57. SqlClientPermission perm = new SqlClientPermission(PermissionState.Unrestricted);
  58. try
  59. {
  60. perm.Demand();
  61. return true;
  62. }
  63. catch (System.Exception)
  64. {
  65. return false;
  66. }
  67. }
  68. private void Form1_Load(object sender, EventArgs e)
  69. {
  70. // TODO: このコード行はデータを 'solarMonitorMobileDataSet.THATSUDEN_KIROKU' テーブルに読み込みます。必要に応じて移動、または削除をしてください。
  71. this.tHATSUDEN_KIROKUTableAdapter.Fill(this.solarMonitorMobileDataSet.THATSUDEN_KIROKU);
  72. }
  73. delegate void UIDelegate();
  74. private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
  75. {
  76. UIDelegate uidel = new UIDelegate(RefreshData);
  77. this.Invoke(uidel, null);
  78. //Remove the handler as it is used for a single notification.
  79. SqlDependency dependency = (SqlDependency)sender;
  80. dependency.OnChange -= dependency_OnChange;
  81. }
  82. private void RefreshData()
  83. {
  84. // Since the code is executing on the UI thread,it is safe to update the UI.
  85. label1.Text = "Database had some changes and are applied in the Grid";
  86. // Reload the dataset that is bound to the grid.
  87. GetAdvtData();
  88. }
  89. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  90. {
  91. SqlDependency.Stop(connstr);
  92. if (connection != null)
  93. connection.Close();
  94. }
  95. }
  96. }

Author: Balamurali Balaji MVP