Почему выборка курсора всегда возвращает верхнюю строку, когда есть несколько строк? - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь получить уникальные имена файлов, хранящиеся в таблице, в которой хранится самая старая дата изменения.

 EXEC SQL AT  DECLARE CtrlIndexTLOGNames_cursor CURSOR FOR 
    SELECT cDataSrcFileName
    FROM SC_CTRL_XMLBUFFER
    GROUP BY cDataSrcFileName
    ORDER BY MAX(modifieddatetime) asc;

EXEC SQL FETCH CtrlIndexTLOGNames_cursor INTO :s_cDataSrcFileName;

Pro * C Код:

BOOLEAN CXYZ::GetSCCtrlTLOGFileName()
{
    EXEC SQL BEGIN DECLARE SECTION;

        char cDataSrcFileName[SZ_FILENAME+30];
        char cSetSortorder[5];
        char s_cAtTable[80];

    EXEC SQL END DECLARE SECTION;

    BOOLEAN bOpenFail=false;
    BOOLEAN bRet=false;

    //char  s_append[500];
    sqlca.sqlcode = null;

    // Always start with a clean error structure
    ClearLastError();

    // Make sure that we close the cursor if it is opened
    CloseCursor();

    ClearLastError();

    // Make sure it is OK to proceed
    if (m_bDBConn)
    {
        // Next check to see that DB is available
        memset(s_cAtTable, 0, sizeof(s_cAtTable));
        if (m_pSup->DBActive(m_lDBType))
            m_pSup->DBAtString(m_lDBType, s_cAtTable, sizeof(s_cAtTable));
        else
            m_lDBType=DAI_PRIMARY;

        // Here we access the appropriate table
        if (m_lDBType == DAI_PRIMARY)
        {
            // Get the row count from the table

             EXEC SQL DECLARE CtrlIndexTLOGNames_cursor CURSOR FOR 
                SELECT cDataSrcFileName
                FROM SC_CTRL_XMLBUFFER
                GROUP BY cDataSrcFileName
                ORDER BY MAX(modifieddatetime) asc;

            // Check to see if the cursor declare succeeded
            if (sqlca.sqlcode == 0)
            {
                EXEC SQL OPEN CtrlIndexTLOGNames_cursor;
                m_lCursorCode=SCCURCTRLXMLBUFFER;
                m_bCursorOpen=true;
                bRet = true;
            }
            else
                bOpenFail=true;
        }
        else
        {
            EXEC SQL AT :s_cAtTable DECLARE CtrlIndexTLOGNames_cursor_B CURSOR FOR 
                SELECT cDataSrcFileName
                FROM SC_CTRL_XMLBUFFER
                GROUP BY cDataSrcFileName
                ORDER BY MAX(modifieddatetime) asc;

                // Check to see if the cursor declare succeeded
            if (sqlca.sqlcode == 0)
            {
                EXEC SQL OPEN CtrlIndexTLOGNames_cursor_B;
                m_lCursorCode=SCCURCTRLXMLBUFFER_B;
                m_bCursorOpen=true;
                bRet = true;
            }
            else
                bOpenFail=true;
        }

        // Check to make sure the open succeeded
        if(!bOpenFail)
        {
            if (sqlca.sqlcode == 0)
                bRet=true;
            else
            {
                // Report the failure information
                sprintf(m_cLastError, (char *)"RTPSC  CtrlIndexTLOGNames CURSOR open failed[%d]:", sqlca.sqlcode);

                // Here we append the RDBMS string
                strncat(m_cLastError, sqlca.sqlerrm.sqlerrmc, sizeof(m_cLastError)-(strlen(m_cLastError)+2));

                // Here we set the appropriate control information
                m_lLastError = sqlca.sqlcode;
                m_bDBConn=false;
                m_pSup->Show(VBL_MINIMAL,m_cLastError);
            }
        }
        else
        {
            // Report the failure information
            sprintf(m_cLastError, (char *)"RTP5003E:CtrlIndexTLOGNames CURSOR declaration failed[%d]:", sqlca.sqlcode);

            // Here we append the RDBMS string
            strncat(m_cLastError, sqlca.sqlerrm.sqlerrmc, sizeof(m_cLastError)-(strlen(m_cLastError)+2));

            // Here we set the appropriate control information
            m_lLastError = sqlca.sqlcode;
            m_bDBConn=false;
            m_pSup->Show(VBL_MINIMAL,m_cLastError);
        }
    }
    else
    {
        strcpy(m_cLastError, (char *)"RTP9101E:Transaction class was not properly initialized.");
        m_lLastError=EFAULT;
    }

    // Close out an ERROR'd cursor
    if (!bRet) CloseCursor();

    // Return the results of this action
    return(bRet);
}


BOOLEAN CZYZ::GetSCCtrlNextTLOGFileName( char *&pFileName)
{
    EXEC SQL BEGIN DECLARE SECTION; 

        char s_cDataSrcFileName[SZ_FILENAME+35];
        char s_cAtTable[80];

    EXEC SQL END DECLARE SECTION;

    BOOLEAN bRet=false;
    long lDataSize;

    // Clear out the last error before diving in to the process
    ClearLastError();

    // Make sure that the caller's storage starts out clean
    pFileName=(char *)null;

    // Next make sure we have access to the database
    if (m_bDBConn && (m_lCursorCode == SCCURCTRLXMLBUFFER || m_lCursorCode == SCCURCTRLXMLBUFFER_B))
    {
        // Next check to see that DB is available
        memset(s_cAtTable, 0, sizeof(s_cAtTable));
        if (m_pSup->DBActive(m_lDBType))
            m_pSup->DBAtString(m_lDBType, s_cAtTable, sizeof(s_cAtTable));
        else
            m_lDBType=DAI_PRIMARY;

        if (m_lCursorCode == SCCURCTRLXMLBUFFER)
        {
            //printf("Inside m_lCursorCode == SCCURCTRLXMLBUFFER condition\n");
            // Pull the information back from the database
            EXEC SQL FETCH CtrlIndexTLOGNames_cursor INTO :s_cDataSrcFileName;
        }
        else
        {
            //printf("Inside m_lCursorCode == SCCURCTRLXMLBUFFER_B condition\n");
            // Pull the information back from the database
            EXEC SQL FETCH CtrlIndexTLOGNames_cursor_B INTO :s_cDataSrcFileName;
        }
        // Check to see if the cursor declare succeeded
        if (sqlca.sqlcode == 0)
        {
            lDataSize=strlen((char *)s_cDataSrcFileName)+2L;
            // Here we allocate the storage as needed
                if ((pFileName=new char[lDataSize]) != (char *)null)
                {
                    // Here we move the data into this storage
                    memset(pFileName, 0, lDataSize);
                    strncpy(pFileName, s_cDataSrcFileName, lDataSize-1L);
                    bRet=true;
                    CleanWhiteSpace(pFileName);
                }
                else
                {
                    // Here we mark this failure for the caller
                    sprintf(m_cLastError, (char *)"RTP1000E:Memory Allocation Failed requesting %lu bytes (rc=%ld).", lDataSize, errno);
                    m_lLastError=ENOMEM;
                    bRet=false;
                }
        }
        else if (sqlca.sqlcode != DBERR_NOTFOUND && sqlca.sqlcode != DBERR_NODATAFOUND)
        {
            // Report the failure information
            sprintf(m_cLastError, (char *)"RTP8323E:GLOAD CtrlIndexTLOGNames CURSOR fetch failed[%d]:", sqlca.sqlcode);

            // Here we append the RDBMS string
            strncat(m_cLastError, sqlca.sqlerrm.sqlerrmc, sizeof(m_cLastError)-(strlen(m_cLastError)+2));

            // Here we set the appropriate control information
            m_lLastError = sqlca.sqlcode;
            m_bDBConn=false;
            m_pSup->Show(VBL_MINIMAL,m_cLastError);
            bRet=false;
        }
        if (!bRet)
        {
            // Here is the cursor close
            CloseCursor();
        }
    }
    else
    {
        strcpy(m_cLastError, (char *)"RTP9101E:RTPSC class was not properly initialized.");
        m_lLastError=EFAULT;
    }

    // Here we return the results of this action
    return(bRet);   
}

Когда я запускаю этот запрос, я получаю несколько строк с уникальными именами файлов. Но когда я использую функцию в своем C-коде, используя цикл while, это всегда возвращает верхнюю строку, а не другие имена файлов.

Подскажите, пожалуйста, что с этим не так?

В модуле C я вызываю функции Pro * C

// Get list of file names
    if(!CXYZ.GetSCCtrlTLOGFileName())
    {
      printf("\n\nERROR creating cursor in SC_CTRL_XMLBUFFER Database Class: 
      \n%s\n\n", cErrorMsg);
      return iRet=EIO;
    }

    while (CXYZ.GetSCCtrlNextTLOGFileName(pFile))
    {
     printf("UpdateWorkFlowListFromDB pFile - %s\n",pFile);
     .
     .
     .
    }   

Кроме того,

Есть ли ограничение на количество открытых курсоров?

из моего окружения:

               select name,value from v$parameter where name like '%cursor%';

               cursor_space_for_time    FALSE
               session_cached_cursors   50
               cursor_sharing   EXACT
               open_cursors 1000
               cursor_bind_capture_destination  memory+disk

              select count(*) from V$OPEN_CURSOR;

             1430

Может ли это быть причиной проблемы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...