PostgreSQL - 如何使用游标更改不同表列的长度
PostgreSQL - How to change Length of Different Tables Columns with Cursors
我正在更改所有必要表格的列长度,但我遇到了一些错误。
我正在使用 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$$;
我使用的是 PostgreSQL 11,但如果我没记错的话,它几乎是一样的。
如果你想完全使用循环来做到这一点,我更正了你的代码并注入了调试 table.
您缺少空格 space 并且游标声明错误。我只是搭上了它。
如果需要,您可以阅读这篇关于 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;
$$;
我正在更改所有必要表格的列长度,但我遇到了一些错误。
我正在使用 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$$;
我使用的是 PostgreSQL 11,但如果我没记错的话,它几乎是一样的。 如果你想完全使用循环来做到这一点,我更正了你的代码并注入了调试 table.
您缺少空格 space 并且游标声明错误。我只是搭上了它。
如果需要,您可以阅读这篇关于 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;
$$;