我试图使用基于查询的通知,但由于某种原因似乎切换到基于对象的通知。我的环境是Oracle 11.2(我相信你需要11.1或以上的查询基于工作),我有一个选择语句,它检索的列是类型为NUMBER。(在这里我的理解是只有varchar2和数字列工作)。我似乎得到了表上的每个更改通知,而不仅仅是我的过滤数据集
作为一个例子,我创建了一个名为test_db_notification的样例表,其中有一列类型为NUMBER。
添加了如下两个条目:
SELECT rowid,column1 FROM test_db_notification;
ROWID COLUMN1
AAAERnAAKAAEurNAAI 54
AAAERnAAKAAEurPAAA 63
下面是我注册通知的代码:
OracleCommand _cmdObj = _connObj.CreateCommand();
_cmdObj.CommandText = " SELECT column1 FROM test_db_notification where column1 = 63";
_dep = new OracleDependency(_cmdObj);
_dep.QueryBasedNotification = true;
_dep.OnChange += new OnChangeEventHandler(_dep_OnChange);
_cmdObj.Notification.IsNotifiedOnce = false;
_cmdObj.AddRowid = true;
_cmdObj.ExecuteNonQuery();
当我注册并更改当前值为54的column1的值时,我收到一个通知,说54的ROWID已更新。我预计不会收到任何通知,因为我的原始查询只看column1 = 63
。
我错过了什么吗?
谢谢
在StackOverflow上发布答案永远不会太晚,因为人们(包括我自己)一直在搜索从问题被问到的几年后的事情。这可能不是你想要的答案,但把它看作是一个可能引导你走向正确方向的观察结果。我没有足够的分数来发表"评论",所以我把这个作为一个答案。
为了重现这个问题,我创建了一个表CREATE TABLE TEST_DB_NOTIFICATION
(
COLUMN1 VARCHAR2(1 BYTE),
COLUMN2 VARCHAR2(1 BYTE)
)
我使用了下面的。net代码(对你的代码做了一些小改动)
private void button1_Click(object sender, RoutedEventArgs e)
{
OracleConnection _connObj = new OracleConnection("Data Source=mydb;User Id=myid;Password=mypassword;");
_connObj.Open();
OracleCommand _cmdObj = _connObj.CreateCommand();
_cmdObj.CommandText = " SELECT column1 FROM ods.test_db_notification where column1 = 'a' ";
OracleDependency _dep = new OracleDependency(_cmdObj);
_dep.QueryBasedNotification = true;
_dep.OnChange += new OnChangeEventHandler(_dep_OnChange);
_cmdObj.Notification.IsNotifiedOnce = false;
_cmdObj.AddRowid = true;
_cmdObj.ExecuteNonQuery();
}
void _dep_OnChange(object sender, OracleNotificationEventArgs eventArgs)
{
MessageBox.Show("changed" + eventArgs.Details.Rows.Count);
}
基本上,我正在做和你一样的事情,但是我正在观察Column1='a'。
我注意到的是:
** INSERT行为**
1)当我插入到表中时,当新行具有Column1 value = 'a'时,我得到通知。2)当列1值不是'a'时,我不会得到通知。
** UPDATE行为**
1)当我更新表导致Column1中的现有值从非'a'值更改为'a'时,我得到通知。2)我得到通知为什么我改变列的值已经是'a'再次成为'a'。3)如果我将列1上的值从'a'更改为'z',我会收到通知。
** DELETE行为**
1)当我删除Column1值= 'a'的行时,我会得到通知2)当Column1值不是'a'时,我不会得到通知
这使我得出一个明显的结论:如果对符合您正在监视的语句的结果的行有任何更改(包括将现有值覆盖到其本身的更改),则会收到通知。这与INSERT、UPDATE和DELETE的行为一致。
插入不会被基于查询的通知捕获。如果您想捕获这些,请设置_dep。QueryBasedNotification为false(这是默认值)。