iT邦幫忙

0

Greenplum Create Function Error(PostgreSQL 9.6)

推測應該是碰到符號轉義的問題,在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;

1 個回答

0
一級屠豬士
iT邦大師 1 級 ‧ 2020-10-15 00:36:10

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 可以運作
看更多先前的回應...收起先前的回應...
ty201457 iT邦新手 5 級 ‧ 2020-10-15 09:23:25 檢舉

屠大又見面了 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貌似讓我自己處理!!!所以想說上來發文看看有沒有類似遭遇的人,可以幫忙調一下。

那我們想辦法從別的方向試試看. 你的"目標","目的" 是什麼?
然後"方法",“手段" 再來研究.

ty201457 iT邦新手 5 級 ‧ 2020-10-15 16:21:15 檢舉

目標:建立提問的function在Greenplum環境上
目的:建立可用return query execute的動態SQL功能即可
方法:https://my.oschina.net/u/4341484/blog/4020129 ,希望以這篇來改寫Code
手段:目前沒測試環境,還要想辦法生出。

我推測你是有一些table 區分成 part_n , 但是你的函數,那個 m-1, 其實是造成了許多麻煩,而且你兩次轉換型別,一來成本高,二來
又讓你語法產生許多限制.若沒有絕對的必要,也許改換成在外部轉換.
你說的目的,其實還是方法.真正的目的目標,不是產生這個函數.

ty201457 iT邦新手 5 級 ‧ 2020-10-15 18:46:47 檢舉

不減也是可以的,只是我想測試多一點的動作,在這個動態函數裡面,但感覺這段比較屬於優化的部分。
目標跟目的還是一致的,在Greenplum上建立動態的函數。

那現在是出現怎樣的錯誤?

ty201457 iT邦新手 5 級 ‧ 2020-10-16 09:37:18 檢舉

不好意思,錯誤訊息在公司信箱,所以現在才回。
由於有一些資訊不能露出因此隱碼起來,大概是下面這樣。

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

https://ithelp.ithome.com.tw/upload/images/20201016/20112811K91A60D17J.png

看來是語法解析時的問題,這個會讓你有點麻煩.
可以先建立 view, 將你的數個 table,先 union 起來.
另外建議你使用quote_literal()將你的code一些地方,改用
它來包含.

我要發表回答

立即登入回答