В программе pro*C, почему курсор ЗАКРЫТИЯ не выполняется в дочернем процессе?

#c #oracle #fork #oracle-pro-c

Вопрос:

Вкратце…

 int main() {     pid_t childPid;    EXEC SQL CONNECT :username IDENTIFIED BY :password;   for (;;)  {  childPid = fork();    if(childPid gt; 0)  { // parent process  ...  ...  ...   }  else if(childPid == 0)  { // chiled process  EXEC SQL DECLARE c1 CURSOR FOR  SELECT empno, ename, sal FROM emp;    for (;;)  {  EXEC SQL OPEN c1;  EXEC SQL FETCH c1 INTO :emp_rec;    if(sqlca.sqlcode == 1403)  {  EXEC SQL CLOSE c1;  EXEC SQL COMMIT WORK RELEASE;  break;  }  ...  ...  //A function that sends results to the Client program.  SendPacketTOClient(fd,size);  }  EXEC SQL COMMIT WORK;  exit(0);  }  else { // fork Fail  perror("fork Fail! n");  return -1;  }    sleep(60);   }  retun 0; }  

Как и выше, ПОДКЛЮЧЕНИЕ к БД выполняется в родительском процессе, и вилки выполняются каждую минуту, а дочерний процесс завершается выходом (0) после запроса (ОБЪЯВИТЬ-gt;ОТКРЫТЬ-gt;gt;ВЫБОРКА-gt;gt;gt;ЗАКРЫТЬ). Не было никаких проблем, потому что он был обработан до ПОЛУЧЕНИЯ. Но если ЗАКРЫТЬ не работает должным образом, позже произошла ошибка ORA-01000: максимальный открытый ответ. Когда я на самом деле проверил, дочерний процесс был создан, и он не закрылся, когда был завершен после завершения работы.

После Serch я обнаружил, что это была проблема, потому что процесс Servie был одним, поэтому я решил ее, разветвив родительский процесс и подключение к БД дочернего процесса.

Я решил эту проблему, но я хочу знать принцип, поэтому я оставляю вопрос. Могу я узнать, почему выполняются ОБЪЯВЛЕНИЯ, ОТКРЫТИЯ и ВЫБОРКИ, но COLSE не выполняется?

Спасибо.

Комментарии:

1. Из опубликованного вами кода (в котором есть ошибка, как будто(sqlca.sqlcode==1403 не закрыт), вы извлекаете только одну строку из курсора, а затем проверяете, дошли ли вы до конца, чтобы закрыть ее, затем открываете ее снова и извлекаете. Таким образом, если ваш курсор возвращает строки, вы не закрываете его до следующего открытия, и в итоге у вас будет много открытых курсоров. И поскольку все ваши разветвленные процессы используют одно и то же соединение, поэтому все открываемые ими курсоры вносят вклад в один и тот же максимум, вы доберетесь туда очень быстро.

2. @gsalen Спасибо вам за ваш ответ. Как вы сказали, ошибка была исправлена. И я еще не решил эту проблему. Для выживания дочернего процесса требуется менее 10 секунд. Время сна родительского процесса составляет 1 минуту. Таким образом, перед ОТКРЫТИЕМ КУРСОРА следующего дочернего процесса выполняется ВЫБОРКА и дочерний процесс завершается. В этом случае значение sqlcode после ЗАКРЫТИЯ КУРСОРА равно 0 (нормально), тем не менее, мне интересно, почему курсор не закрывается.

3. Попробуйте распечатать sqlcode после выборки и посмотрите, что вы получите. Вероятно, бот 1403.