2016-11-12 49 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