以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  避免重复内容的问题  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=78672)

--  作者:黑苹果
--  发布时间:2015/12/14 20:19:00
--  避免重复内容的问题
某列避免重复输入重复列官方的解决方案是


在DataColChanging事件


If e.DataCol.Name = "订单号" Then
    Dim dr As DataRow 
    dr = e.DataTable.Find("订单号 = \'" & e.NewValue & "\'")
    If dr IsNot Nothing Then
        MessageBox.Show("此订单号已经存在!")
        e.Cancel = True
    End If
End If

这样的判断有个前提条件是该表数据必须全部加载
如果有部份数据没有加载
则代码必须改成SQLFIND

而总感觉频繁的调用SQLFIND 总会影响效率

为啥不就不能使用SQL数据库的 非空唯一列特性来控制列的唯一性呢

--  作者:大红袍
--  发布时间:2015/12/14 20:22:00
--  

 呃,你可以用唯一约束的嘛,但是那种提醒不友好。

 

 你可以先find,找不到,再sqlFind,一行数据,查是没什么问题的。


--  作者:黑苹果
--  发布时间:2015/12/14 20:35:00
--  
用主键唯一约束的确是不好,因为主键唯一约束必须先有值才能加下一行,所以一次只能插入多行,所有狐表默认用自动增量列作主键了
但真正使用过程中,人们可能更多地需要 非空列唯一,空值可以有多个的

SQL数据库已考虑这个了,但是狐表就没有考虑这个需求

我用通用的方法 将SQL的列设置成 UNIQUE 非常唯一列

ALTER TABLE 工装刀检编号表 add UNIQUE (编号)

但遗憾的是,一到狐表中,狐表就将其干成 PRIMARY KEY 约束了

实际测试如果使用SQL的功能更新数万条数据,可以零点几秒完成,那个效率是FT方式的好多倍
同理在全局非空唯一列的问题上,如果能使用SQL UNIQUE 的控制方式肯定也效率高很多.

你可以先find,找不到,再sqlFind,一行数据,查是没什么问题的。如果小型应用 ,数据库中的数据都没有多少条,一次增加的数据都没多少条,则时间是无所味的
但是一次增加的数据有好多条呢

--  作者:大红袍
--  发布时间:2015/12/14 20:39:00
--  
你可以插入多行啊,只要赋值为一个随机的字符,比如可以是唯一的uuid,你想添加多少行都没问题。
--  作者:黑苹果
--  发布时间:2015/12/14 20:53:00
--  
If e.DataCol.Name = "第七列" Then
    Dim drs As DataRow
    drs = e.DataTable.SQLFind("第七列 = \'" & e.NewValue & "\'")
    Dim dr As DataRow
    dr = e.DataTable.Find("第七列 = \'" & e.NewValue & "\'")
    If dr IsNot Nothing Or drs IsNot Nothing Then
        MessageBox.Show("此内容已经存在!")
        e.Cancel = True
    End If
End If

代码如果改成这样的话
先判断一下已加载的数据包括还没有保存的数据
再判断一下没有加载的数据中有没有

看似没问题,但实际上会带来严重的后果,客户会无所适从

比如原来第二行有数据,789是保存了的. 在后台还是记载的789
我现在删除了第二行的789或第二行的修改成其它数据456,再在其它的行输入了789.则这时系统不让输入789了,用户就有些发疯了

解决问题的方法有:
一,全部加载数据,用FIND 一个方法 .但数据多了全部加载是不现实的

二,使用SQL本身的UNIQUE 非空约束,数据随便你怎么改以最后结果为准. 与方法一本质上是相同的.但可惜的是狐表不支持.


目前的方法 :
数据又不能全部加载,只能部份加载
又要保证数据列内容不重复
客户的操作习惯又是不可控的
想要做个不重复的控制,还真有点难

难道必须 控制重复的单元格一发生值变体就保存一下本行? 然后全部编辑完了再来个全表保存?
还真 是费脑子的事情.


--  作者:黑苹果
--  发布时间:2015/12/14 20:57:00
--  
你可以插入多行啊,只要赋值为一个随机的字符,比如可以是唯一的uuid,你想添加多少行都没问题。
这个还不是问题的关键,单列非空不重复. 这个可以转换成主键解决
还有多列组合不重复. 这个也要转换成主键解决.? 一个表中只能有一个主键了

--  作者:大红袍
--  发布时间:2015/12/14 21:25:00
--  

完全没有你说的问题find,sqlfind就可以控制

 

If e.DataCol.Name = "第七列" Then
    Dim dr As DataRow
    dr = e.DataTable.Find("第七列 = \'" & e.NewValue & "\' and _Identify <> " & e.DataRow("_Identify"))
    If dr IsNot Nothing  Then
        MessageBox.Show("此内容已经存在!")
        e.Cancel = True
    Else
       
        dr = e.DataTable.SQLFind("第七列 = \'" & e.NewValue & "\' and _Identify <> " & e.DataRow("_Identify"))
        If dr IsNot Nothing Then
            msgbox("后台数据库此数据已经存在")
            e.cancel = True
        End If
    End If
End If


--  作者:黑苹果
--  发布时间:2015/12/14 21:52:00
--  
你这代码测试结果如下
第一行,第七列有内容 456

我现在移除第一行(相当于第一行数据未加载)
然后再在其它行第七列 输入456

再次打开 项目,第七列就有两个 456了

唯一性不重复就没有判断了.

[此贴子已经被作者于2015/12/14 21:52:20编辑过]

--  作者:黑苹果
--  发布时间:2015/12/14 21:59:00
--  
你这代码有问题,

完全没有你说的问题find,sqlfind就可以控制

 

If e.DataCol.Name = "第七列" Then
    Dim dr As DataRow
    dr = e.DataTable.Find("第七列 = \'" & e.NewValue & "\' and [_Identify] <> " & e.DataRow("_Identify"))
    If dr IsNot Nothing  Then
        MessageBox.Show("此内容已经存在!")
        e.Cancel = True
    Else
        
        dr = e.DataTable.SQLFind("第七列 = \'" & e.NewValue & "\' and [_Identify] <> " & e.DataRow("_Identify"))
        If dr IsNot Nothing Then
            msgbox("后台数据库此数据已经存在")
            e.cancel = True
        End If
    End If
End If


必须这样才能正常执行,难怪我想不通逻辑

但这样后,我所说的问题就存在

删除某行的内容再在其它行输入就是不行


--  作者:大红袍
--  发布时间:2015/12/14 22:01:00
--  
你删除行,肯定要实时保存啊。代码没问题。