Not able to run block in PostgreSQL 8.2

前端 未结 1 1586
挽巷
挽巷 2021-01-22 00:39

I can\'t run this block in PostgreSQL 8.2.

DECLARE
        curtime char;
BEGIN
        curtime := \'now\';
        INSERT INTO logtable VALUES (logtxt, curtime)         


        
相关标签:
1条回答
  • 2021-01-22 01:02

    It sounds like you're trying to run a PL/PgSQL code block stand-alone, without wrapping it up in a function using CREATE OR REPLACE FUNCTION. That won't work, you need to include it in a function or (from PostgreSQL 9.0) a DO block. PL/PgSQL and plain SQL are different languages so you can't just run PL/PgSQL code directly.

    It'd help if you explained why you're trying to write the code you pasted. I suspect you're trying to solve a problem that's better handled with a trigger function like an audit trigger.

    Some important notes:

    You need to update PostgreSQL: PostgreSQL 8.2 is dangerously out of date and unsupported. security and bug fixes are no longer being released. Upgrade urgently to a supported version, but make sure to read the release notes for each major ".0" version like "8.3.0", "8.4.0", etc for migration and compatibility advice.

    Avoid 'now': Also, instead of using 'now' you should usually use the current date/time functions, particularly current_timestamp.

    current_timestamp is stable: The hoop-jumping you are doing is probably unnecessary because the value of current_timestamp (and 'now'::timestamp) doesn't change for the duration of a transaction. Eg:

    regress=# BEGIN;
    regress=# SELECT current_timestamp;
     2012-08-14 14:52:43.382596+08
    regress=# SELECT pg_sleep(5);
    regress=# SELECT current_timestamp;
     2012-08-14 14:52:43.382596+08
    

    Details

    Your intention appears to be something like the following (incorrect, do not use) code:

    CREATE OR REPLACE FUNCTION some_function(logtxt text) RETURNS timestamptz AS $$
    DECLARE
            curtime char;
    BEGIN
            curtime := 'now';
            INSERT INTO logtable VALUES (logtxt, curtime);
            RETURN curtime;
    END;
    $$ LANGUAGE 'plpgsql';
    

    but you've misused the char datatype, which requires a length parameter. It defaults to 1 if not supplied so you'll get:

    regress=# SELECT some_function();
    ERROR:  value too long for type character(1)
    CONTEXT:  PL/pgSQL function "some_function" line 5 at assignment
    

    NEVER use the char datatype in SQL; use varchar or text. For cross-database portability varchar(n) where n is a maximum length is required; if portability isn't needed use text.

    If you change char to text in the above, your code might run, but it still doesn't make any sense. I strongly suspect that you really want to write:

    CREATE OR REPLACE FUNCTION some_function(logtxt text) RETURNS timestamptz AS $$
    BEGIN
            INSERT INTO logtable VALUES (logtxt, current_timestamp);
            RETURN current_timestamp;
    END;
    $$ LANGUAGE 'plpgsql';
    

    ... but you didn't know about the current date/time functions.

    Even that's too much, really. I think you're trying to solve a problem that's a better fit for a trigger.

    0 讨论(0)
提交回复
热议问题