SQL FETCH, курсоры и RPG

Я не уверен, что не так с моим кодом, я пытаюсь сделать цикл while, который будет извлекать следующие символы в поле (код) с помощью курсора, объявленного в SQL. Цель состоит в том, чтобы получить следующие совпадающие символы с помощью цикла. Затем я хочу вернуть результаты в конце цикла. Цель состоит в том, чтобы сделать частичное совпадение с кодом, если нет точного совпадения. Я никогда раньше не использовал курсоры, поэтому я пытаюсь узнать как можно больше об использовании выборки и курсоров.

EXEC SQL
SELECT field FROM file
WHERE  field = :code

UNION

DECLARE UserInput CURSOR FOR
SELECT field FROM file
WHERE  field LIKE '%' || :code || '%'
ORDER BY field ASC

OPEN UserInput
FETCH NEXT FROM UserInput
BEGIN
   DO WHILE <> %EOF 
         FETCH NEXT FROM UserInput
END
CLOSE UserInput
DEALLOCATE UserInput;

person Community    schedule 16.05.2016    source источник


Ответы (1)


Вау... тут много чего не так... На первый взгляд...

  1. вы пытаетесь объявить свой курсор не в том месте.
  2. %EOF() работает с доступом на уровне записей RPG, необходимо проверять SQLCODE или SQLSTATE
  3. FETCH OPEN - это все операторы SQL, они должны быть в EXEC SQL
  4. DEALLOCATE не нужен
  5. Нужно FETCH строку от курсора в переменную RPG

Взгляните на этот код:

EXEC SQL                                            
  DECLARE UserInput CURSOR FOR                      
    SELECT field FROM file                          
    WHERE  field = :code                            
    UNION                                           
    SELECT field FROM file                          
    WHERE  field LIKE '%' || :code || '%'           
    ORDER BY field ASC;                             
EXEC SQL                                            
  OPEN UserInput;                                   
--really should check SQLSTATE here too!            

EXEC SQL                                            
  FETCH NEXT FROM UserInput INTO :MyRpgVar;         

Dow SQLSTATE = '00000';                              
   --note 00000 = no errors or warning              
   --     02000 = no data                           
   <do somthing?>                                   
   EXEC SQL                                         
      FETCH NEXT FROM UserInput INTO :MyRpgVar;     
ENDDO;                                              

EXEC SQL                                            
  CLOSE UserInput; 

Я предлагаю вам прочитать раздел RPGLE в Встроенных Справочник по программированию SQL.

person Charles    schedule 16.05.2016
comment
Большое спасибо, это поможет мне понять это намного лучше! - person ; 17.05.2016
comment
еще одна вещь, предполагая, что CODE и FIELD являются символьными полями фиксированной длины, вам, вероятно, понадобится '%' || trim(:code) || '%'. - person Charles; 17.05.2016
comment
Однако, пожалуйста, откажитесь от вариантов символов, символа bar | и замените || как оператор, с CONCAT как оператор. - person CRPence; 28.05.2016
comment
Маловероятно, что набор результатов должен включать дубликаты для любого значения, удовлетворяющего предикату equal? Плюс UNION здесь довольно глупый. Просто закодируйте ИЛИ между двумя предикатами; в зависимости от подразумеваемого или фактического N оптимизации для N строк и фактического количества строк в таблице, возможно, кодировать только предикат LIKE [if, with trim]? Наконец, в зависимости от данных поля запрошенный порядок может не привести к точному совпадению, если есть точное совпадение и неточное совпадение; кажется, возможно, что от описательного [по сравнению с представлением фактических входных данных и желаемого результата] может потребоваться точное совпадение в первую очередь. - person CRPence; 28.05.2016