postgresql GET STACKED DIAGNOSTICS不能使用数组类型?

时间:2013-12-16 09:09:08

标签: postgresql plpgsql

当我在PL / pgSQL中实现以下代码时,会发生一些错误。

ERROR:  syntax error at or near "["
LINE 10: GET STACKED DIAGNOSTICS text_val[1] = RETURNED_SQLSTATE,

或者我不对的地方? 任何回复将不胜感激。

CREATE or replace FUNCTION merge_db5(key INT, data TEXT) RETURNS text AS
$$
    declare 
    text_val text[];
    text_result text;
    -- Declare an array to store the result.
BEGIN
    text_result := '';
    BEGIN
    INSERT INTO db(a,b) VALUES (key, data);
    EXCEPTION WHEN unique_violation THEN  
    GET STACKED DIAGNOSTICS text_val[1] = RETURNED_SQLSTATE, 
    text_val[2] = COLUMN_NAME,
    text_val[3] = CONSTRAINT_NAME,
    text_val[4] = PG_DATATYPE_NAME,
    text_val[5] = MESSAGE_TEXT,
    text_val[6] = TABLE_NAME,
    text_val[7] = SCHEMA_NAME,
    text_val[8] = PG_EXCEPTION_DETAIL,
    text_val[9] = PG_EXCEPTION_HINT,
    text_val[10] = PG_EXCEPTION_CONTEXT;
    text_result = array_to_string(text_val,',','*');
    /*
    To save all the error messages to this array.
    */
  END;
    return text_result;
 END;
$$
LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:1)

这不是你的错误。目标变量应该是标量。那里不支持数组。

这个限制的原因是plpgsql解析器和执行器的设计非常简单。类似的行为有一个FOR IN LOOP语句。另一方面,这个限制具有实际意义(虽然它没有设计) - 数组更新并不快 - 数组是不可变结构,因此通过创建修改后的副本来模拟任何更新 - 更少的数组更新通常意味着更快的执行。

CREATE or replace FUNCTION merge_db5(key INT, data TEXT)
RETURNS text AS $$
  DECLARE 
     f1 text; f2 text; f3 text; f4 text; f5 text;
     f6 text; f7 text; f8 text; f9 text; f10 text;
  BEGIN
    INSERT INTO db(a,b) VALUES (key, data);
    RETURN '';
  EXCEPTION WHEN unique_violation THEN  
    GET STACKED DIAGNOSTICS f1 = RETURNED_SQLSTATE, 
                            f2 = COLUMN_NAME, f3 = CONSTRAINT_NAME,
                            f4 = PG_DATATYPE_NAME, f5 = MESSAGE_TEXT,
                            f6 = TABLE_NAME, f7 = SCHEMA_NAME,
                            f8 = PG_EXCEPTION_DETAIL, f9 = PG_EXCEPTION_HINT,
                            f10 = PG_EXCEPTION_CONTEXT;
    RETURN array_to_string(ARRAY[f1, f2, f3, f4, f5, f6, f7, f8, f9, f10], '*');
  END;
  $$ LANGUAGE plpgsql;