2017-02-08 17 views
1

Я пытался подготовить Fetch заявление в db2, как показано нижеподготовить принести заявление в db2

Stmt = %trim('FETCH EXSQCRS INTO ?'); 
EXEC SQL PREPARE SQLSTMT2 FROM :STMT ; 

EXSQCRS находится курсор.

Но это ошибка при ошибке -104. Любая подсказка о том, как написать это?

ответ

2

FETCH не является заявлением, которое может быть подготовлено. Это просто исполняемый оператор. См Actions allowed on SQL statements

Вы должны прочитать на Embedded SQL programming

Простой пример с динамическим SQL

D EMPNUM   S    6A 
D NAME   S    15A 
D STMT   S   500A INZ('SELECT LASTNAME   - 
D          FROM CORPDATA.EMPLOYEE WHERE - 
D          EMPNO = ?') 

    //************************************************************ 
    // Prepare STMT as initialized in declare section   * 
    //************************************************************ 
    /FREE 
    EXEC SQL 
    PREPARE S1 FROM :STMT; 
    // 
    //************************************ 
    // Declare Cursor for STMT   * 
    //************************************ 
    EXEC SQL 
    DECLARE C1 CURSOR FOR S1; 
    // 
    //**************************************************** 
    // Assign employee number to use in select statement * 
    //**************************************************** 
    EMPNUM = '000110'; 

    //********************* 
    // Open Cursor  * 
    //********************* 
    EXEC SQL 
    OPEN C1 USING :EMPNUM; 
    // 
    //********************************************** 
    // Fetch record and put value of    * 
    // LASTNAME into NAME       * 
    //********************************************** 
    EXEC SQL 
    FETCH C1 INTO :NAME; 
1

Вы не можете подготовить выборку. Вы можете подготовить инструкцию SQL, которая используется для определения курсора. Таким образом, это будет выглядеть так:

dcl-s stmt  Varchar(256) Inz(''); 

exec sql declare S1 statement; 
exec sql declare C1 cursor for S1; 

stmt = 'select * from customer where cusno = ?'; 
exec sql prepare S1 from :stmt; 
exec sql open C1 using :customerNumber; 

exec sql fetch C1 into :customerDS; 
dow %subst(sqlstate:1:2) = '00' 
    or %subst(sqlstate:1:2) = '01'; 

    ... process it here ... 

    exec sql fetch C1 into :customerDS; 
enddo; 
exec sql close C1; 

Обратите внимание, что здесь нет ошибок. Вы действительно хотите сделать это во всех исполняемых операциях sql. Также обратите внимание, что операторы exec sql declare ... не исполняются. Даже не declare C1 cursor. Обычно я ставил свой sql в свои собственные процедуры. Подготовка и открытие будут проходить в одной процедуре, в другой - в другом, а в другом - в другом.

Некоторые замечания об использовании процедур и локальных переменных со встроенным sql. При использовании статических курсоров вам нужно поместить объявление в ту же процедуру, что и open, потому что переменные хоста находятся в инструкции declare, и они должны быть теми же переменными в области, когда вы открываете. Это потому, что объявление полностью закомментировано и не генерирует никакого кода. Он не является исполняемым. В этом случае переменные хоста отображаются в коде, сгенерированном для open.

С помощью подготовленных курсоров вам не нужно указывать объявление в той же процедуре, что и открытые, как и для статических курсоров. Это связано с тем, что переменные хоста, привязанные к маркерам параметров в подготовленном заявлении, появляются в открытом заявлении. Объявление может быть во главе программы с глобальными объявлениями. Это глобальная декларация в любом случае независимо от того, где объявлено физически. Мне нравится явно объявлять мои подготовленные заявления, даже если вам это не нужно. Я помещаю их в объявления курсора.

У меня обычно будет процедура выборки, возвращающая логическое значение (индикатор) или количество записей, чтобы я не мог повторить вызов в коде. Вывод действительно повторяется здесь только потому, что я не использовал процедуры.

И, наконец, единственное исключение, которое я испытываю с ошибками тестирования, заключается в том, что я не тестирую ошибку после закрытия, потому что единственная ошибка, которая будет бросать, заключается в том, что курсор не открыт, что не является ошибкой в ​​моем сознании , это то, что я хочу, чтобы состояние курсора было, когда я закончил с ним.