将其作为一个事务来处理。
用savepoint,要么全部成功,要么全部失败,肯定不会出现这样的现象,你说呢?

解决方案 »

  1.   

    int mydir_Ins(char *szDirName)
    {
    EXEC SQL BEGIN DECLARE SECTION;
    int     count,max,ret,i;
    char dirname[PATHLEN+1];
    int DirId;       
    int     RightId;

    EXEC SQL END DECLARE SECTION;

    strcpy(dirname,szDirName);

             /** 1.计算表mydir中DirId的现有最大值,加1作为新纪录DirId的值 **/
    EXEC SQL SELECT COUNT(*) INTO :count FROM mydir;
    if (count==0)
    DirId=1;
    else
    {
    EXEC SQL SELECT MAX(DirId) INTO :max FROM mydir;
    DirId=max+1;
    }

             /** 2.向表mydir中插入一条记录 **/
    EXEC SQL INSERT INTO mydirlist VALUES(:DirId,:DirName);
    if (sqlca.sqlcode==0)
    { /* 3.如果插入成功,同时向表myright中插入两条记录 */
                      /* RightId为表myright中现有的最大值加1 */
    EXEC SQL SELECT MAX(RightId) INTO :RightId FROM myright;
    RightId=RightId+1;
    EXEC SQL INSERT INTO myright VALUES(:RightId,:DirId,'0');
    if (sqlca.sqlcode!=0)
    {
    return ERR_DB;
    }
    RightId=RightId+1;
    EXEC SQL INSERT INTO myright VALUES(:RightId,:DirId,'1');
    if (sqlca.sqlcode!=0)
    {
    return ERR_DB;
    }
    }
    return sqlca.sqlcode;
    }
      

  2.   

    这段程序应该没有问题。(假设你调用函数后根据返回值执行commit/rollback)仔细看了你最初的说明,有几个疑问:
    1.myright表中的aid只是一个外键,并不是主键,是可以重复的。(要么你对myright表的(aid,aright)建了唯一索引)
    2.你说的联合外键是如何建立的?(mydir表中没有aright字段)
    3.删除mydir表的时候,因为它是外键的父表,所以要么无法删除,要么自动删除myright表对应记录(要看你外键的建法),不明白“同样,删除表A的一条记录时,同时也要删除表B中该Aid所在的两条记录。”的意思
      

  3.   

    用Exception啊,
     begin 
         处理你的事情
     exception 
    when others then 
        retcode := -1;
        errtext := SQLERRM;
        insert into temp_log(id,……o,errtext) values(……errtext);
        commit; 
            end;
      

  4.   

    1.myright表中的aid只是一个外键,并不是主键,是可以重复的。(要么你对myright表的(aid,aright)建了唯一索引)
    --对,我对Aid、Aright建立了唯一索引,语句是
    ALTER TABLE myright ADD(CONSTRAINT "MYRIGHT_UK" UNIQUE("DIRID","RIGHT"));2.你说的联合外键是如何建立的?(mydir表中没有aright字段)
    --我当时说错了,不叫联合外键,就是上个回答中的唯一索引3.删除mydir表的时候,因为它是外键的父表,所以要么无法删除,要么自动删除myright表对应记录(要看你外键的建法),不明白“同样,删除表A的一条记录时,同时也要删除表B中该Aid所在的两条记录。”的意思
    --以DirId为函数输入,删除mydir表记录时,我会删除mydir中该DirId所在的记录后,再删除myright表中该DirId所在的两条记录,如下:
    int mydir_Del(int DirId)
    {
       EXEC SQL DELETE FROM mydir WHERE DirId=:DirId;
       if (sqlca.sqlcode==0)
       {
             /* 从myright中删除有该DirId的记录 */
     EXEC SQL SELECT COUNT(*) INTO :count FROM myright WHERE DirId=:DirId;
     if (count!=0) 
         EXEC SQL DELETE FROM myright WHERE DirId=:Dirid;
       }
       return sqlca.sqlcode;
    }
      

  5.   

    if (count!=0) 
         EXEC SQL DELETE FROM myright WHERE DirId=:Dirid;-->
    if (count!=0) 
    {
         EXEC SQL DELETE FROM myright WHERE DirId=:Dirid;
    }一条EXEC SQL经过预编译后变成N条c/c++语句(你可以看一下编译后的.c/.cpp文件),需要加大括号。检查系统其它程序是否会删除mydir表。