создать таблицу в postgresql функция не работает - PullRequest
0 голосов
/ 27 сентября 2019

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

Я использую pgadmin для созданияи проверьте мою функцию.

мой код:


create or replace function f_produceMultiroleWorkload(sourceTable text, targetTable text) returns integer as $$ 
declare                                                                                                                                                                                                                                                   
        mysql text; 
        record_cnt integer; 
begin 
        record_cnt=0; 

        create temp table t_staff_job_division( staff_num varchar(30), cate_division varchar(30)); 

        mysql:='insert into t_staff_job_division select  staff_num, cate_division from (select staff_num, cate_division from bpc."' || $1 || '" group by 1,2) t1 where staff_num in (select distinct staff_num from bpc."' || $1 || '" where cate_division<>staff_division) and staff_num not in (select distinct staff_num from  (select staff_num, count(distinct cate_division) as division_cnt from bpc."'|| $1 ||'" group by 1) t2 where division_cnt=1)' ;                     
        execute mysql; 

        EXECUTE format( 
      ' 
        CREATE TABLE IF NOT EXISTS %I.%I ( 
                staff_num varchar(30) PRIMARY KEY, 
                cate_division varchar(30), 
                score numeric(18,7) 
        ); 
      ', 
      'bpc', $2 
    ); 
        mysql:='insert into bpc.' || $2 ||' select t1.staff_num, t1.cate_division, sum(normalized_individual_gross_score) from bpc."' || $1 || '" t1 inner join t_staff_job_division t2 on t1.staff_num=t2.staff_num and t1.cate_division=t2.cate_division group by 1,2';                                                       
        execute mysql;                 
        if exists(select count(*) from bpc."' || $2 || '")        then                                                                                                                                                                                                                                           
                mysql:='select count(*) from bpc."' || $2 || '"'; 
                execute mysql into record_cnt; 
        else 
                record_cnt=0;                                                                                                                                                                                                                                                   
        end if;                         
        return record_cnt; 
end; 
$$ language plpgsql; 

Ошибка возникает при выполнении функции

mysql:='insert into bpc.' || $2 ||' select t1.staff_num, t1.cate_division, sum(normalized_individual_gross_score) from bpc."' || $1 || '" t1 inner join t_staff_job_division t2 on t1.staff_num=t2.staff_num and t1.cate_division=t2.cate_division group by 1,2';    

Синус подсказка на китайскомНет смысла публиковать это здесь.Но, вообще говоря, в нем говорится, что таблица с именем bpc.$2 не существует.

Буду признателен за любую помощь, чтобы помочь мне решить эту проблему.

заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

Похоже, вам нужно убедиться, что ваши прописные / строчные имена совпадают.Здесь вы можете столкнуться с проблемой в верхнем / нижнем регистре, потому что $2 непоследовательно заключен в двойные кавычки (").

Примечание:

        EXECUTE format( 
      ' 
        CREATE TABLE IF NOT EXISTS %I.%I ( 
                staff_num varchar(30) PRIMARY KEY, 
                cate_division varchar(30), 
                score numeric(18,7) 
        ); 
      ', 
      'bpc', $2 
    ); 

Если $2«myTable», тогда таблица будет создана как bpc.mytable, потому что когда имена таблиц / столбцов не заключены в двойные кавычки, PostgreSQL автоматически преобразуется в нижний регистр.Однако для этого:

mysql:='select count(*) from bpc."' || $2 || '"';

Имя таблицы будет интерпретировано как bpc."myTable", и поскольку оно в двойных кавычках, верхний регистр T будет сохранен.В Postgres mytable != "myTable" вы получите сообщение о том, что bpc."myTable" не существует.

Пожалуйста, рассмотрите возможность использования этого формата (обратите внимание на двойные кавычки):

        EXECUTE format( 
      ' 
        CREATE TABLE IF NOT EXISTS %I."%I" ( 
                staff_num varchar(30) PRIMARY KEY, 
                cate_division varchar(30), 
                score numeric(18,7) 
        ); 
      ', 
      'bpc', $2 
    );
0 голосов
/ 27 сентября 2019

Вы жертва (случайного) внедрения SQL.

Второй аргумент функции (targettable), вероятно, выглядит следующим образом: CamelCase.

Теперь оператор CREATE TABLE, который правильно построен с использованием format, выглядит следующим образом:

CREATE TABLE bpc."CamelCase" ...

, а неправильно построенный оператор INSERT выглядит как

INSERT INTO bpc.CamelCase ...

Теперь идентификаторы SQL свернуты в нижний регистрв PostgreSQL, если они не заключены в двойные кавычки, поэтому второй оператор попытается вставить в bpc.camelcase.Но имена таблиц чувствительны к регистру, поэтому они не работают.

Рекомендации:

  • Всегда используйте format, чтобы избежать внедрения SQL.

  • Избегайте использования в идентификаторах букв ASCII, строчных букв и цифр _.

Не связано, но IF EXISTS в вашей функции также будетпровал.Там вам тоже нужен динамический SQL.

...