PostgreSQL - Как изменить длину столбцов разных таблиц с помощью курсоров - PullRequest
0 голосов
/ 16 апреля 2019

Я изменяю длину столбцов для всех необходимых таблиц, но я получил некоторые ошибки.

Я использую PostgreSQL 10 и pgAdmin4, но не вижу сообщений об ошибках.

Полагаю, из-за версии pgAdmin. Во-первых, я не мог объявить CURSOR, я не знаю почему? Я преуспел на Oracle.

Можете ли вы помочь мне в этой ситуации? Мой код, как показано ниже;

do $$
DECLARE
    modify_column_cursor CURSOR FOR 
        SELECT 'ALTER TABLE "schema_name"."' || C.TABLE_NAME || '" ALTER COLUMN'|| C.COLUMN_NAME||' varchar(128)'  as alter_sql, TABLE_NAME t_name, COLUMN_NAME c_name, 128 c_length FROM information_schema.columns c  WHERE column_name LIKE '%PROD_NUM' and TABLE_NAME not like '%STAGING%'  UNION
        SELECT 'ALTER TABLE "schema_name"."' || C.TABLE_NAME || '" ALTER COLUMN'|| C.COLUMN_NAME||' varchar(128)'  as alter_sql, TABLE_NAME t_name, COLUMN_NAME c_name, 128 c_length FROM information_schema.columns c  WHERE column_name LIKE '%PREV_PROD_NUM' and TABLE_NAME not like '%STAGING%';
        --.
        --.
        --.
    sql_stmt    VARCHAR(800);
    c_length    numeric;
    c_length_db numeric;
    flag        numeric := 0;
BEGIN
    --OPEN modify_column_cursor;
    for modify_column in modify_column_cursor LOOP
        raise notice 'asd : %', modify_column.ex_name;

        sql_stmt := 'SELECT character_maximum_length FROM information_schema.columns WHERE column_name = ''' || modify_column.c_name || ''' and table_name = ''' || modify_column.t_name || ''' and table_schema = ''schema_name''';
        EXECUTE sql_stmt INTO c_length_db;
        IF c_length_db > modify_column.c_length THEN
            sql_stmt := 'select max(length(' || modify_column.c_name || ')) from "schema_name".' || modify_column.t_name;
            EXECUTE sql_stmt INTO c_length;

            IF c_length > modify_column.c_length THEN
                flag := 1;
                raise notice '--------------INCONSISTENED FIELD FOUND---------------';
                raise notice '% - % - %   Not Ok!   Default field size in db: %', modify_column.t_name, modify_column.c_name, modify_column.c_length, c_length_db;
                raise notice '% - % - %   Not Ok!   Field has a data with length: %', modify_column.t_name, modify_column.c_name, modify_column.c_length, c_length;
                raise notice '-------------------------------------------------------';
                raise notice ' ';
            ELSE
                NULL;
            END IF;
        ELSE
            NULL;
        END IF;
    END LOOP;


    IF flag = 0 THEN

        FOR modify_column IN modify_column_cursor
        LOOP
            EXECUTE modify_column.alter_sql;
        END LOOP;

        raise notice ' ';
        raise notice '-----FIELDS ARE SUCCESSFULLY MODIFIED-----';
    ELSE
        raise notice ' ';
        raise notice '-----ERROR: SOME FIELDS ARE NOT SUITABLE TO ALTER-----';
    END IF;
end$$; 

1 Ответ

1 голос
/ 16 апреля 2019

Я нахожусь на PostgreSQL 11, но если я хорошо помню, это почти то же самое. Если вы хотите абсолютно использовать цикл для этого, я немного исправил ваш код и ввел таблицу отладки.

У вас пропущено пустое пространство и неверное объявление курсора. Я просто прокатился на нем.

Вы можете прочитать эту превосходную статью о курсоре на postgresql, если хотите: http://www.postgresqltutorial.com/plpgsql-cursor/

do $$
DECLARE
    sql_stmt    VARCHAR(800);
    c_length    numeric;
    c_length_db numeric;
    flag        numeric := 0;
    modify_column record;
begin
    create table if not exists [your_schema_name].test (query varchar);

    for modify_column in 
        SELECT 'ALTER TABLE "'||[your_schema_name]||'"."' || C.TABLE_NAME || '" ALTER COLUMN '|| C.COLUMN_NAME||' varchar(128)'  as alter_sql
                , TABLE_NAME t_name
                , COLUMN_NAME c_name
                , 128 c_length 
        FROM information_schema.columns c  
        where table_schema = ''||[your_schema_name]||''
    LOOP
        --raise notice 'asd : %', modify_column.ex_name;

        sql_stmt := 'SELECT character_maximum_length FROM information_schema.columns WHERE column_name = ''' || modify_column.c_name || ''' and table_name = ''' || modify_column.t_name || ''' and table_schema = '''||[your_schema_name]||'''';
        insert into [your_schema_name].test values (sql_stmt);

       EXECUTE sql_stmt INTO c_length_db;
        IF c_length_db > modify_column.c_length THEN
            sql_stmt := 'select max(length(' || modify_column.c_name || ')) from "'||[your_schema_name]||'".' || modify_column.t_name;
            --EXECUTE sql_stmt INTO c_length;
            insert into [your_schema_name].test values (sql_stmt);

            IF c_length > modify_column.c_length THEN
                flag := 1;
                raise notice '--------------INCONSISTENED FIELD FOUND---------------';
                raise notice '% - % - %   Not Ok!   Default field size in db: %', modify_column.t_name, modify_column.c_name, modify_column.c_length, c_length_db;
                raise notice '% - % - %   Not Ok!   Field has a data with length: %', modify_column.t_name, modify_column.c_name, modify_column.c_length, c_length;
                raise notice '-------------------------------------------------------';
                raise notice ' ';
            ELSE
                NULL;
            END IF;
        ELSE
            NULL;
        END IF;
    END LOOP;


    IF flag = 0 THEN

        --FOR modify_column IN modify_column_cursor
       -- LOOP
       --     EXECUTE modify_column.alter_sql;
        --END LOOP;

        raise notice ' ';
        raise notice '-----FIELDS ARE SUCCESSFULLY MODIFIED-----';
    ELSE
        raise notice ' ';
        raise notice '-----ERROR: SOME FIELDS ARE NOT SUITABLE TO ALTER-----';
    END IF;
end;
$$;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...