我创建了下面的Postgres函数,该函数在PGADMIN IV中编译时没有任何错误,但是当我尝试运行它时,它抛出了以下错误,
错误:无法在PL / pgSQL中开始/结束事务
提示:改为使用带有EXCEPTION子句的BEGIN块。
上下文:PL / pgSQL函数shift_release_dates()第35行位于SQL语句SQL状态:0A000
有人可以让我知道代码中是否缺少任何内容吗?
我的功能如下,
CREATE OR REPLACE FUNCTION ssp2_pcat.shift_release_dates_V5(
)
RETURNS void
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
C1 CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME IN (SELECT TABLE_NAME FROM RESET_DATES) ORDER BY 1;
C2 CURSOR (iTable_Name VARCHAR) FOR
SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = iTable_Name
AND UPPER(DATA_TYPE) = 'DATE'
AND (COLUMN_NAME LIKE '%START%' OR COLUMN_NAME LIKE '%END%')
AND (COLUMN_NAME NOT LIKE '%TEST%' AND COLUMN_NAME NOT LIKE '%PCAT%' AND
COLUMN_NAME NOT LIKE '%ORDER%' AND COLUMN_NAME NOT LIKE '%SEASON%' AND
COLUMN_NAME NOT LIKE '%_AT') ORDER BY 1, 2;
Wed DATE;
Thurs DATE;
SQL_Text VARCHAR(4000);
Start_Date_Row INTEGER;
End_Date_Row INTEGER;
Start_Date_Update_Rows INTEGER;
End_Date_Update_Rows INTEGER;
l_start TIMESTAMP;
l_end TIMESTAMP;
Time_Taken VARCHAR(20);
BEGIN
l_start := clock_timestamp();
SELECT 'TOMORROW'::date + ( 4 + 7 - extract ( dow FROM
'TOMORROW'::date))::int%7 INTO Thurs ;
SELECT 'TOMORROW'::date + ( 3 + 7 - extract ( dow FROM
'TOMORROW'::date))::int%7 INTO Wed ;
UPDATE RESET_DATES SET START_DATE_ROWS = NULL, END_DATE_ROWS = NULL,
START_DATE_UPDATED = NULL, END_DATE_UPDATED = NULL, LAST_UPDATED = NULL;
RAISE NOTICE '% ', ('Wednesday: ' || Wed) ;
RAISE NOTICE '% ', ('Thursday: ' || Thurs) ;
FOR i IN C1 LOOP
BEGIN
FOR j IN C2 (i.Table_Name)LOOP
BEGIN
IF j.COLUMN_NAME LIKE '%START%' THEN -- Start Date
SQL_Text := 'SELECT COUNT(*) FROM ' || i.TABLE_NAME || ' WHERE
' || j.COLUMN_NAME || ' = ''' || TO_CHAR(Thurs, 'DD-MON-YYYY') || '''';
RAISE NOTICE '% ', (SQL_Text);
Execute SQL_Text INTO Start_Date_Row;
RAISE NOTICE '% ', ('Start_Date_Row: ' || Start_Date_Row);
SQL_Text := 'UPDATE ' || i.TABLE_NAME || ' SET ' || j.COLUMN_NAME || ' = ''' || current_timestamp::date+1 || ''' WHERE ' || j.COLUMN_NAME || ' = ''' || TO_CHAR(Thurs, 'DD-MON-YYYY') || '''';
RAISE NOTICE '% ', (SQL_Text);
Execute SQL_Text;
Start_Date_Update_Rows := SQL%ROWCOUNT;
RAISE NOTICE '% ', ('Start_Date_Update_Rows: ' || Start_Date_Update_Rows);
UPDATE RESET_DATES set start_date_rows = Start_Date_Row, start_date_updated = Start_Date_Update_Rows, last_updated = current_timestamp::timestamp(0)
WHERE table_name = i.TABLE_NAME;
ELSE -- END_DATE
SQL_Text := 'SELECT COUNT(*) FROM ' || i.TABLE_NAME || ' WHERE ' || j.COLUMN_NAME || ' = ''' || TO_CHAR(Wed, 'DD-MON-YYYY') || '''';
RAISE NOTICE '% ', (SQL_Text);
Execute SQL_Text INTO End_Date_Row;
RAISE NOTICE '% ', ('End_Date_Row: ' || End_Date_Row);
SQL_Text := 'UPDATE ' || i.TABLE_NAME || ' SET ' || j.COLUMN_NAME || ' = ''' || current_timestamp::date || ''' WHERE ' || j.COLUMN_NAME || ' = ''' || TO_CHAR(Wed, 'DD-MON-YYYY') || '''';
RAISE NOTICE '% ', (SQL_Text);
Execute SQL_Text;
End_Date_Update_Rows := SQL%ROWCOUNT;
RAISE NOTICE '% ', ('End_Date_Update_Rows: ' || End_Date_Update_Rows);
UPDATE RESET_DATES set end_date_rows = End_Date_Row, end_date_updated = End_Date_Update_Rows, last_updated = current_timestamp::timestamp(0)
WHERE table_name = i.TABLE_NAME;
END IF;
BEGIN
EXCEPTION
WHEN OTHERS THEN
BEGIN
RAISE NOTICE '% ', (sqlerrm);
ROLLBACK;
END;
END;
END;
END LOOP;
END;
END LOOP;
l_end := clock_timestamp();
Time_Taken := (l_end-l_start);
RAISE NOTICE '% ',('SHIFT_RELEASE_DATES Took: ' || Time_Taken );
END;
$BODY$;
感谢您的时间! 在此处输入代码
答案 0 :(得分:1)
对于此类问题,请记住提及postgres服务器版本。
无论如何,documentation says:
您不能使用事务控制命令,例如提交,保存点, 和一些实用程序命令,例如VACUUM,在SQL函数中。
不幸的是,我找不到与plpgsql相同的句子,但是根据我的经验,所有功能都禁止内部事务操作。
不过,version 11 brings procedures可以满足您的需求:
添加SQL级过程,这些过程可以启动和提交自己的事务(Peter Eisentraut)
它们是使用新的CREATE创建的 PROCEDURE命令并通过CALL调用。