标题:VFP中子表与父表存储过程中参照完整性问题,求助
只看楼主
Amilier
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2018-5-29
结帖率:0
已结贴  问题点数:20 回复次数:5 
VFP中子表与父表存储过程中参照完整性问题,求助
以下是本人正在做的一个关于试卷系统的参照完整性代码,出现问题是方案内容部分触发器无法触发,查相关资料表示是参照完整性问题,然而我不知道具体是哪个部分出现问题,求助希望有大神可以帮忙解决

  procedure __RI_UPDATE_方案内容     &&方案内容更新时是试卷方案子表,设置了级联,标记为方案编号
** "Referential integrity update trigger for" 方案内容
LOCAL llRetVal
llRetVal = .t.
PRIVATE pcParentDBF,pnParentRec,pcChildDBF,pnChildRec,pcParentID,pcChildID
PRIVATE pcParentExpr,pcChildExpr
STORE "" TO pcParentDBF,pcChildDBF,pcParentID,pcChildID,pcParentExpr,pcChildExpr
STORE 0 TO pnParentRec,pnChildRec
IF _triggerlevel=1
  BEGIN TRANSACTION
  PRIVATE pcRIcursors,pcRIwkareas,pcRIolderror,pnerror,;
  pcOldDele,pcOldExact,pcOldTalk,pcOldCompat,PcOldDBC
  pcOldTalk=SET("TALK")
  SET TALK OFF
  pcOldDele=SET("DELETED")
  pcOldExact=SET("EXACT")
  pcOldCompat=SET("COMPATIBLE")
  SET COMPATIBLE OFF
  SET DELETED ON
  SET EXACT OFF
  pcRIcursors=""
  pcRIwkareas=""
  pcRIolderror=ON("error")
  pnerror=0
  ON ERROR pnerror=rierror(ERROR(),message(),message(1),program())
  IF TYPE('gaErrors(1)')<>"U"
    release gaErrors
  ENDIF
  PUBLIC gaErrors(1,12)
  pcOldDBC=DBC()
  SET DATA TO ("试卷生成系统")
ENDIF first trigger
LOCAL lcParentID && parent's value to be sought in child
LOCAL lcOldParentID && previous parent id value
LOCAL lcChildWkArea && child work area handle returned by riopen
LOCAL lcChildID && child's value to be sought in parent
LOCAL lcOldChildID && old child id value
LOCAL lcParentWkArea && parentwork area handle returned by riopen
LOCAL lcStartArea
lcStartArea=select()
llRetVal=.t.
lcChildWkArea=select()
IF _triggerlevel=1 or type("pccascadeparent")#"C" or (NOT pccascadeparent=="试卷方案")
  SELECT (lcChildWkArea)
  lcChildID=方案编号
  lcOldChildID=oldval("方案编号")
  pcChildDBF=dbf(lcChildWkArea)
  pnChildRec=recno(lcChildWkArea)
  pcChildID=lcOldChildID
  pcChildExpr="方案编号"
  if isnull(lcChildID) or isnull(lcOldChildID) or lcChildID <> lcOldChildID
    lcParentWkArea=riopen("试卷方案","方案编号")
    IF lcParentWkArea<=0
      IF _triggerlevel=1
        DO riend WITH .F.
      ENDIF at the end of the highest trigger level
      SELECT (lcStartArea)
      RETURN .F.
    ENDIF not able to open the child work area
    pcParentDBF=dbf(lcParentWkArea)
    llRetVal=SEEK(lcChildID,lcParentWkArea)
    pnParentRec=recno(lcParentWkArea)
    if llRetVal and not (isrlocked(pnParentRec, lcParentWkArea) or ;
      isflocked(lcParentWkArea))
      if rlock(lcParentWkArea)
        unlock record pnParentRec in lcParentWkArea
      else
        =rireuse("tparen",lcParentWkArea)
        pnError = rierror(-1,"Insert restrict rule violated.","","")
        IF _triggerlevel=1
          DO riend WITH llRetVal
        ENDIF at the end of the highest trigger level
        SELECT (lcStartArea)
        RETURN llRetVal
      endif
    endif
    =rireuse("试卷方案",lcParentWkArea)
    IF NOT llRetVal
      pnError = rierror(-1,"Insert restrict rule violated.","","")
      IF _triggerlevel=1
        DO riend WITH llRetVal
      ENDIF at the end of the highest trigger level
      SELECT (lcStartArea)
      RETURN llRetVal
    ENDIF no parent
  ENDIF this value was changed
ENDIF not part of a cascade from "试卷方案"
IF _triggerlevel=1 or type("pccascadeparent")#"C" or (NOT pccascadeparent=="试题")
  SELECT (lcChildWkArea)
  lcChildID=试题编号
  lcOldChildID=oldval("试题编号")
  pcChildDBF=dbf(lcChildWkArea)
  pnChildRec=recno(lcChildWkArea)
  pcChildID=lcOldChildID
  pcChildExpr="试题编号"
  if isnull(lcChildID) or isnull(lcOldChildID) or lcChildID <> lcOldChildID
    lcParentWkArea=riopen("试题","试题编号")
    IF lcParentWkArea<=0
      IF _triggerlevel=1
        DO riend WITH .F.
      ENDIF at the end of the highest trigger level
      SELECT (lcStartArea)
      RETURN .F.
    ENDIF not able to open the child work area
    pcParentDBF=dbf(lcParentWkArea)
    llRetVal=SEEK(lcChildID,lcParentWkArea)
    pnParentRec=recno(lcParentWkArea)
    if llRetVal and not (isrlocked(pnParentRec, lcParentWkArea) or ;
      isflocked(lcParentWkArea))
      if rlock(lcParentWkArea)
        unlock record pnParentRec in lcParentWkArea
      else
        =rireuse("tparen",lcParentWkArea)
        pnError = rierror(-1,"Insert restrict rule violated.","","")
        IF _triggerlevel=1
          DO riend WITH llRetVal
        ENDIF at the end of the highest trigger level
        SELECT (lcStartArea)
        RETURN llRetVal
      endif
    endif
    =rireuse("试题",lcParentWkArea)
    IF NOT llRetVal
      pnError = rierror(-1,"Insert restrict rule violated.","","")
      IF _triggerlevel=1
        DO riend WITH llRetVal
      ENDIF at the end of the highest trigger level
      SELECT (lcStartArea)
      RETURN llRetVal
    ENDIF no parent
  ENDIF this value was changed
ENDIF not part of a cascade from "试题"
lcParentWkArea=lcChildWkArea
IF _triggerlevel=1
  do riend with llRetVal
ENDIF at the end of the highest trigger level
SELECT (lcStartArea)
RETURN llRetVal
搜索更多相关主题的帖子: 方案 IF select NOT the 
2018-05-29 17:39
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:10 
数据输入时需要先进行审核把关,防止错误数据录入表中,这项工作最好是通过程序来完成,这样可以有针对性地提醒用户如何纠正,如果将这项工作交给系统来完成,系统的提示比较笼统,用户可能很难明白到底错在哪儿。所以我从来不用系统提供的“数据完事性”检查,都是对用户录入的数据进行审核后再保存,审核不通过则给出明确的提示,以便用户更正。

活到老,学到老! http://www. E-mail:hu-jj@
2018-05-30 06:45
Amilier
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2018-5-29
得分:0 
回复 2楼 hu9jj
  首先感谢您的回复。那么我想问下能不能具体给我讲解下上面的问题呢??我现在主要就是希望能够使触发器可以实现触发,而不是一直触发失败
2018-05-30 08:02
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:10 
VFP触发器的格式:
CREATE TRIGGER ON TableName   FOR DELETE | INSERT |
UPDATE AS lExpression

你的格式是:
procedure __RI_UPDATE_
...
...
RETURN llRetVal
你的是过程,能触发才怪.
2018-05-30 08:43
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
这个是帮助上的示范

CLOSE DATABASES

OPEN DATABASE (HOME(2) + 'data\testdata')
USE customer  && 打开 customer 表

* 设置 maxordamt 字段的触发器为:值 <= 50 时失败
CREATE TRIGGER ON customer FOR UPDATE AS maxordamt <= 50

ON ERROR  && 恢复系统错误处理程序

WAIT WINDOW "按任一键,用值 60 测试触发器"+CHR(13);
 +"当收到错误信息时,按忽略(Ignore)."
REPLACE maxordamt WITH 60    && 显示错误信息
? maxordamt

WAIT WINDOW "按任一键,用值 50 测试."
REPLACE maxordamt WITH 50    && 值被接受
? maxordamt
DELETE TRIGGER ON customer FOR UPDATE  && 移除触发器
2018-05-30 08:45
Amilier
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2018-5-29
得分:0 
回复 5楼 mywisdom88
  感谢!!!
2018-05-30 12:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-487395-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.718289 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved