2016-11-12 47 views
2

我正在学习PostgreSQL,并且我正在尝试创建一个函数来ALTER具有character varying数据类型的列的给定表的数据类型。更改文本为字符变化不按预期执行

要做到这一点,我已经建立了一个光标,基本上查询INFORMATION_SCHEMA.COLUMNS寻找具有与character varying类型列后执行ALTER,并尝试改变列text表,让现场不限由价值的长度。

下面是函数:

CREATE OR REPLACE FUNCTION my_cursor(db_name TEXT, tbl_schema TEXT, tbl_name TEXT, col_type TEXT) RETURNS void AS $func$ 
DECLARE 
    cid record; 
BEGIN 
    FOR cid IN SELECT * FROM information_schema.columns AS ic 
       WHERE ic.table_catalog=db_name 
       AND ic.table_schema=tbl_schema 
       AND ic.table_name=tbl_name 
       AND ic.data_type=col_type 
    LOOP 
     EXECUTE format('ALTER TABLE %I.%I ALTER COLUMN %I TYPE text', cid.table_schema, cid.table_name, cid.column_name); 
    END LOOP; 
    RETURN; 
END; 
$func$ LANGUAGE plpgsql; 

SELECT my_cursor('database10232016', 'public', 'continent', 'character varying'); 

功能编译和创建成功后,运行该功能后,但我注意到圣坛是不是在指定的表名来运行。

你能帮我找出我的光标出了什么问题吗?

回答

1

您的功能本身没有问题本身;它的功能很好。但有几点:

  • text数据类型与character varying相同,没有指定长度。所以基本上,你正在努力改变什么,除非有character varying (n)列。在information_schema表中,这两种类型都列为character varying,因为这是SQL标准; text类型是PostgreSQL扩展。
  • 您没有使用CURSOR,您正在使用循环。这是一件好事,尽可能避免游标,因为通常有更有效的方法来做事情。
  • 在您的format()函数中,您应该使用占位符而不是字符串连接与||。现在你连接一个字符串,你进一步不做格式化。请使用format('ALTER TABLE %I.%I ALTER COLUMN %I TYPE text', cid.table_schema, cid.table_name, cid.column_name)

如果你有字符串类型的character (n)character varying (n),你要删除的长度的限制,那么你应该在同一个表中搜索列,其中character_maximum_length IS NOT NULL

+0

嗨帕特里克, 感谢您采取突出这些要点。然而,独立于数据类型的建议,我仍然在努力看到ALTER TABLE打算做的改变。您可以请针对具有不同类型字符的列的本地表尝试相同的功能。 结果应该是字符变化列应该变成文本类型columna。 – fndg87

+0

我的观点是'text'数据类型永远不会显示一列。这只是一个方便的符号'字符变化'。你想要的是去除长度限制,这应该与你的函数一起工作,但你最好检查'character_maximum_length'而不是列数据类型。 – Patrick

+0

我明白你的观点。现在让我们说我在表格中有smallint类型的列,我想将它们更改为bigint。考虑写入的功能来改变和尝试它,它不会工作。 (例如: 例如: SELECT my_cursor('database10232016','public','continent','smallint'); 而Alter部分应该看起来像这样: format('ALTER TABLE%I.%I ALTER COLUMN%I TYPE bigint',cid.table_schema,cid.table_name,cid。column_name) 这就是我想指出的。由于某些原因,它没有运行alter函数。 – fndg87