推測應該是碰到符號轉義的問題,在Greenplum執行有誤,想求教大神可以怎麼調整我的自定義Function。
程式碼如下:
CREATE OR REPLACE FUNCTION test.fun_part("m1" int)
RETURNS TABLE(k1 text, k2 int) AS
$$
BEGIN
RETURN QUERY EXECUTE
'
select k1::text, k2::int
from
(
select k1, '||(m1-1)::text||' as k2
from test.part_'||(m1-1)::text||'
where k1 like ''ABC''
) kk
';
END;
$$ LANGUAGE plpgsql;
create table part_1 (
id smallint generated always as identity
, k1 text not null
);
insert into part_1(k1) values
('ABC'),('ABCD'),('XYZ');
commit;
create or replace function fun_part(m1 int)
returns table(k1 text, k2 int) as
$$
begin
return query execute
'select k1, k2::int
from (select k1, '||(m1-1)::text|| 'as k2
from part_'||(m1-1)::text||'
where k1 like ' || quote_literal('ABC')
|| ') kk';
end;
$$ language plpgsql;
commit;
select fun_part(2);
+----------+
| fun_part |
+----------+
| (ABC,1) |
+----------+
(1 row)
select *
from fun_part(2);
+-----+----+
| k1 | k2 |
+-----+----+
| ABC | 1 |
+-----+----+
(1 row)
我用 PG12.4 可以運作
屠大又見面了 XD
這段我在PG上面可以做,換到GP就不行了。
查了許多資料才發現GP雖然跟PG是同一個老爸生的,內在還是有點不同,看Error Code加上參考下面這幾篇,推測應該是處理符號的時候發生問題。
https://gp-docs-cn.github.io/docs/admin_guide/load/topics/g-escaping-in-text-formatted-files.html
http://blog.itpub.net/11022757/viewspace-1242320/
苦惱的是現在只有一個GP環境select的權限,也沒法測試,DBA貌似讓我自己處理!!!所以想說上來發文看看有沒有類似遭遇的人,可以幫忙調一下。
那我們想辦法從別的方向試試看. 你的"目標","目的" 是什麼?
然後"方法",“手段" 再來研究.
目標:建立提問的function在Greenplum環境上
目的:建立可用return query execute的動態SQL功能即可
方法:https://my.oschina.net/u/4341484/blog/4020129 ,希望以這篇來改寫Code
手段:目前沒測試環境,還要想辦法生出。
我推測你是有一些table 區分成 part_n , 但是你的函數,那個 m-1, 其實是造成了許多麻煩,而且你兩次轉換型別,一來成本高,二來
又讓你語法產生許多限制.若沒有絕對的必要,也許改換成在外部轉換.
你說的目的,其實還是方法.真正的目的目標,不是產生這個函數.
不減也是可以的,只是我想測試多一點的動作,在這個動態函數裡面,但感覺這段比較屬於優化的部分。
目標跟目的還是一致的,在Greenplum上建立動態的函數。
那現在是出現怎樣的錯誤?
不好意思,錯誤訊息在公司信箱,所以現在才回。
由於有一些資訊不能露出因此隱碼起來,大概是下面這樣。
ERROR: syntax error at or near "'
LINE 1: EXECUTE '
^
DETAIL:
select ****::text, ****::text, ****::int, ****::int, ****::int
from ( select ****, ****, ****, ****, '"
QUERY: EXECUTE '
select ****::text, ****::text, ****::int, ****::int, mounth_number::int
from (
select ****, ****, ****, ****, '||( $1 -1)::text||' as ****
from ****_'||( $1 -1)::text||'
where **** is not null and strpos(****,''****'') >= 1
union
select ****, ****, ****, ****, '||( $1 -2)::text||' as ****
from ****_'||( $1 -2)::text||'
where **** is not null and strpos(****,''****'') >= 1
union
select ****, ****, ****, ****, '||( $1 -3)::text||' as ****
from ****_'||( $1 -3)::text||'
where **** is not null and strpos(****,''****'') >= 1
) ****
'
CONTEXT: SQL statement in PL/PgSQL function "****" near line 18 SQL state: 42601
看來是語法解析時的問題,這個會讓你有點麻煩.
可以先建立 view, 將你的數個 table,先 union 起來.
另外建議你使用quote_literal()將你的code一些地方,改用
它來包含.