2015-04-25 2 views
2
CREATE OR REPLACE PROCEDURE SP_NEW_PROCEDURE1() 
RETURNS REFTABLE(employees) 
LANGUAGE NZPLSQL AS 
BEGIN_PROC 
    DECLARE 

    l_conditions varchar(1000); 
    p_rec   RECORD; 

BEGIN 

    FOR P_REC IN select empid, mgrid, empname, salary from employees where mgrid = 7 
    LOOP 


      l_conditions := 'insert into ' || 
           REFTABLENAME  || 
           ' VALUES ('  || 
           P_REC.EMPID  || 
           ','    || 
           P_REC.MGRID  || 
           ','    || 
           P_REC.EMPNAME || 
           ','    || 
           P_REC.SALARY  || 
           ' ) ; ' ; 

    execute immediate l_conditions; 

     l_conditions := ' '; 

    END LOOP;  
    RETURN REFTABLE; 
END; 
END_PROC; 

Когда я запускаю это:Cursor Работа в Netezza

select SP_NEW_PROCEDURE1() 

Я получаю ошибки:

ERROR [01000] NOTICE: Error occurred while executing PL/pgSQL function SP_NEW_PROCEDURE1 
ERROR [01000] NOTICE: line 24 at execute statement 
ERROR [42S22] ERROR: Attribute 'DAN' not found 

Может кто-то помочь, что случилось ... спасибо

ответ

0

я подозреваю, что вы создаете запрос, который предназначен для вставки литерала «DAN», но который не включает требуемые метки кавычек, следовательно, он ссылается на DAN - op поэтому таймер пытается найти атрибут этого имени.

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

Если вы сомневаетесь, всегда смотрите на данные, поскольку это, вероятно, было бы очевидно для вас, если вы проверили значение l_conditions.

1

Это ничего не делает с самим курсором и все зависит от того, как вы строите свою динамическую строку SQL.

При создании динамического SQL в хранимой процедуре Netezza вы можете использовать вспомогательные функции quote_ident и quote_literal, чтобы система могла знать, передаете ли вы литерал или передаете ли вы его идентификатор. Существует пример в online documentation here. По сути, все, что они делают, - это то, что нужно использовать сэкономленные цитаты.

Так как вы пытаетесь поставить значения, хранящиеся в столбцах вашей P_REC записи в VALUES часть оператора вставки, можно использовать quote_literal так:

CREATE OR REPLACE PROCEDURE SP_NEW_PROCEDURE1() 
RETURNS REFTABLE(employees) 
LANGUAGE NZPLSQL AS 
BEGIN_PROC 
    DECLARE 

l_conditions varchar(1000); 
p_rec   RECORD; 

BEGIN 

FOR P_REC IN select empid, mgrid, empname, salary from employees where mgrid = 7 
LOOP 


     l_conditions := 'insert into ' || 
          REFTABLENAME  || 
          ' VALUES ('  || 
          quote_literal(P_REC.EMPID) || 
          ','    || 
          quote_literal(P_REC.MGRID) || 
          ','    || 
          quote_literal(P_REC.EMPNAME) || 
          ','    || 
          quote_literal(P_REC.SALARY) || 
          ' ) ; ' ; 

execute immediate l_conditions; 

    l_conditions := ' '; 

END LOOP;  
RETURN REFTABLE; 
END; 
END_PROC; 

Это, как говорится, с помощью курсора зацикливать записи, чтобы вставить строку по одному, ужасно неэффективна в базе данных MPP, такой как Netezza. Предполагая, что этот вопрос является продолжением вашего вопроса об альтернативе рекурсивному CTE для изучения иерархий, нет ничего плохого в петле в целом, но старайтесь избегать записи по записи. Вот версия, которая будет использовать характер MPP системы. Для записи, если вы собираетесь вернуть свой набор результатов в REFTABLE, тогда ваш единственный выбор - Dynamic SQL.

CREATE OR REPLACE PROCEDURE SP_NEW_PROCEDURE1() 
RETURNS REFTABLE(employees) 
LANGUAGE NZPLSQL AS 
BEGIN_PROC 
    DECLARE 

    l_conditions varchar(1000); 
    p_rec   RECORD; 

BEGIN 

-- FOR P_REC IN select empid, mgrid, empname, salary from employees where mgrid = 7 
-- LOOP 


      l_conditions := 'insert into ' || 
           REFTABLENAME  || 
           ' select empid, mgrid, empname, salary from employees where mgrid = 7 ; ' ; 

    execute immediate l_conditions; 

     l_conditions := ' '; 

-- END LOOP;  
    RETURN REFTABLE; 
END; 
END_PROC; 
+0

Спасибо за вашу помощь –

+0

Если это решение сработало для вас, отметьте свой вопрос как можно скорее. Благодаря! – ScottMcG