在下面的代码中调试一些语法错误需要帮助。代码如下所示,在Insert,Select等关键字附近只有几个语法错误
CREATE OR REPLACE FUNCTION audit_temp() RETURNS TRIGGER LANGUAGE plpgsql AS $BODY$
DECLARE
ri RECORD;
oldValue TEXT;
newValue TEXT;
isColumnSignificant BOOLEAN;
isValueModified BOOLEAN;
BEGIN
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
NEW.record_modified_ = clock_timestamp();
FOR ri IN
-- Fetch a ResultSet listing columns defined for this trigger's table.
SELECT ordinal_position, column_name, data_type
FROM information_schema.columns
WHERE table_schema = quote_ident(TG_TABLE_SCHEMA)
AND table_name = quote_ident(TG_TABLE_NAME)
ORDER BY ordinal_position
LOOP
-- For each column in this trigger's table, copy the OLD & NEW values into respective variables.
-- NEW value
EXECUTE 'SELECT ($1).' || ri.column_name || '::text' INTO newValue USING NEW;
-- OLD value
IF TG_OP = 'INSERT' THEN -- If operation is an INSERT, we have no OLD value, so use an empty string.
oldValue := ''::varchar;
ELSE -- Else operation is an UPDATE, so capture the OLD value.
EXECUTE 'SELECT ($1).' || ri.column_name || '::text' INTO oldValue USING OLD;
END IF;
isColumnSignificant := (position( '_x_' in ri.column_name ) < 1) AND
(ri.column_name <> 'pkey_') AND
(ri.column_name <> 'record_modified_');
IF isColumnSignificant THEN
isValueModified := oldValue <> newValue; -- If this nthField in the table was modified, make history.
IF isValueModified THEN
/*RAISE NOTICE E'Inserting history_ row for INSERT or UPDATE.\n';*/
INSERT INTO audit_temp( operation_, table_oid_, table_name_, uuid_, column_name_, ordinal_position_of_column_, old_value_, new_value_ )
VALUES ( TG_OP, TG_RELID, TG_TABLE_NAME, NEW.pkey_, ri.column_name::VARCHAR, ri.ordinal_position, oldValue::VARCHAR, newValue::VARCHAR);
END IF;
END IF;
END LOOP;
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
/*RAISE NOTICE E'Inserting history_ row for DELETE.\n';*/
-- Similar to INSERT above, but refers to OLD instead of NEW, and passes empty values for last 4 fields.
INSERT INTO audit_temp ( operation_, table_oid_, table_name_, uuid_, column_name_, ordinal_position_of_column_, old_value_, new_value_ )
VALUES ( TG_OP, TG_RELID, TG_TABLE_NAME, OLD.pkey_, ''::VARCHAR, 0, ''::VARCHAR, ''::VARCHAR );
RETURN OLD;
END IF;
/* Should never reach this point. Branching in code above should always reach a call to RETURN. */
RAISE EXCEPTION 'Unexpectedly reached the bottom of this function without calling RETURN.';
END; $BODY$;
错误如下&amp;主要围绕选择插入关键字:
>[Error] Script lines: 1-42 -------------------------
ERROR: syntax error at or near "SELECT"
任何建议?????
答案 0 :(得分:0)
违规陈述就是这个(和其他人一样):
EXECUTE 'SELECT ($1).' || ri.column_name || '::text' INTO newValue USING NEW;
根据documentation 参数,符号只能用于数据值 - 如果要使用动态确定的表名或列名,则必须将它们以文本形式插入命令字符串。所以解决方案是:
EXECUTE 'SELECT (' || NEW || ').' || ri.column_name || '::text' INTO newValue;
您可以对触发功能进行一些改进,以使其更快更有效:
isColumnSignficant
和oldValue
之前,您应该先检查newValue
。OLD
值:首次插入或稍后更新数据时,它们已在审计表中。