Вызов функции с табличными параметрами в Postgres

Я столкнулся с проблемой с утра и провел много часов, но не смог вызвать указанную ниже функцию.

Определение функции:

CREATE OR REPLACE FUNCTION public.proc_mc2cdnpf_insertupdatev3(
    tblnotesv3 typupdate_notesv3,
    tbldoclinks typupdate_guidparameter,
    iuserid integer,
    shtmltext character varying,
    OUT snoteid character varying,
    OUT inoteid integer,
    OUT inoteactivityid integer)
    RETURNS record
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
AS $BODY$    
#variable_conflict use_variable
    declare         sNote VARCHAR;
    declare sLoggedInUser VARCHAR(20);
    declare     dtCurrDateTime timestamp;
    declare     iCurrDate int;
    declare     iCurrTime INT;
    declare iNewNoteID INT;
BEGIN

/*
    proc_MC2CDNPF_InsertUpdateV3
    2018-04-23      Dennis Sebenick

    2018-04-23      
        - Initial creation of new proc for storing additional HTML text value.  
        - This proc is going to help bridge the old note system to a new note storage method

    2018-04-25
    - Added iNoteID / iNoteActivityID for output

    2018-06-01
    - Update to typUpdate_NotesV3 - removed additional CDN rows for long text

    2091-05-08
        Rupali Shah
        web 1753-added RTRIM(isnull(NOTE_HDQTRS,''))  while creating sNoteID

*/
/******************************
** File:  proc_MC2CDNPF_InsertUpdateV3
** Desc:  Insert/Update account notes
** Auth:  Rupali Shah
** Date:  2019-05-08
**************************
** Change History
**************************
** Date                                Dev                        JIRA                                       Description 
**2019-05-08                Rupali Shah                 Web 1753                        -added RTRIM(isnull(NOTE_HDQTRS,'')) while creating sNoteID
*******************************/
    SELECT dtCurrDateTime = fnGetDate();
    SELECT iCurrDate = fnMC2DateToMC2(dtCurrDateTime);
    SELECT iCurrTime = fnMC2DateTimeToMC2(dtCurrDateTime);

    /*==========================================
        Retrieve Update fields from parameter
    ============================================*/
    select  
          NoteID,
          NOTE_NOTES,
          NOTE_LOGGEDINUSER,
          coalesce(NOTE_ID, 0)
        INTO SNoteID,sNote,sLoggedInUser,iNewNoteID
    from 
        tblNotesV3
    LIMIT 1;

    /************************************************
        2018-04-18      DKS
        Added in to update new note table
    *************************************************/
    IF (iNewNoteID > 0)
    THEN
    BEGIN
        IF (LENGTH(sNote) > 0)
        THEN
        BEGIN
            UPDATE 
                NoteDetails
            SET
                sNote = sNote,
                sNoteHTML = sHTMLText,
                iNoteEditedBy = iUserID,
                dtNoteEdited = dtCurrDateTime
            WHERE
                iNoteID = iNewNoteID;

            IF (ROWCOUNT = 0)
            THEN
            BEGIN
                INSERT INTO 
                    NoteDetails
                    (
                        iNoteType,
                        sNote,
                        sNoteHTML,
                        iNoteEnteredBy,
                        dtNoteEntered
                    )
                    VALUES
                    (   9,         -- iNoteType - int
                        sNote,       -- sNote - VARCHAR(max)
                        sHTMLText,       -- sNoteHTML - VARCHAR(max)
                        iUserID,         -- iNoteEnteredBy - int
                        dtCurrDateTime
                ) RETURNING iNewNoteID;

            END;
            END IF;
        END;
        END IF;
    END;
    ELSE
    BEGIN
        -- Inserting a New Activity
        -- 2018-04-18       DKS
        -- - Insert to new note table.
        IF (LENGTH(sNote) > 0)
        THEN
        BEGIN
            INSERT INTO 
                NoteDetails
                (
                    iNoteType,
                    sNote,
                    sNoteHTML,
                    iNoteEnteredBy,
                    dtNoteEntered
                )
                VALUES
                (   9,         -- iNoteType - int
                    sNote,       -- sNote - VARCHAR(max)
                    sHTMLText,       -- sNoteHTML - VARCHAR(max)
                    iUserID,         -- iNoteEnteredBy - int
                    dtCurrDateTime
            ) RETURNING iNewNoteID;
        END;
        END IF;
    END;
    END IF;

    /************************************************
        End new note table insert / update
    *************************************************/

    IF EXISTS(SELECT * FROM MC2CDNPF WHERE MC2CDNPF.iNoteID = iNoteID)
    THEN
    BEGIN
        UPDATE 
            MC2CDNPF
        SET
            CDNNOTES = '',
            CDNFDATE = fnMC2DateToMC2(TblNotesUpdate.NOTE_DDATE),
            CDNREASN = TblNotesUpdate.NOTE_REASN,
            CDNPRIOR = TblNotesUpdate.NOTE_PRIOR,
            CDNTAGGED = TblNotesUpdate.NOTE_TAGGED,
            iNoteID =  iNewNoteID
        FROM
            MC2CDNPF
        JOIN
            tblNotesV3 TblNotesUpdate
        ON
            MC2CDNPF.iNoteID = TblNotesUpdate.NOTE_ID
        WHERE
            MC2CDNPF.CDNDSEQN = 1;

    END;
    ELSE
    BEGIN
        SELECT 

                TRIM(coalesce(NOTE_CMPANY,'')) || 
                TRIM(coalesce(NOTE_BUSNSS,'')) || 
                TRIM(coalesce(NOTE_CUSNBR,'')) ||
                TRIM(coalesce(NOTE_ENTITY,'')) ||
                TRIM(coalesce(NOTE_HDQTRS,'')) ||
                CAST( iCurrDate AS VARCHAR(8)) || 
                CAST( iCurrTime AS VARCHAR(10))
                INTO sNoteID
        FROM
            tblNotesV3
        LIMIT 1;

        INSERT INTO
            MC2CDNPF
            (
                CDNDSEQN, 
                CDNNOTES, 
                CDNCMPANY, 
                CDNCUSNBR, 
                CDNBUSNSS, 
                CDNENTITY, 
                CDNHDQTRS, 
                CDNRPTCON,
                CDNFULNME, 
                CDNAGNIDN, 
                CDNDDATE, 
                CDNDTIME, 
                CDNREASN,
                CDNTUSER, 
                CDNADATE, 
                CDNTAGGED, 
                CDNFDATE, 
                CDNPRIOR,  
                CDNDTASRC, 
                CDNODATE, 
                CDNOTIME,
                iNoteID
            )
        SELECT
            1, 
            '',                             -- 6/1/2018 DKS - no longer storing note in MC2CDNPF
            coalesce(NOTE_CMPANY,''), 
            coalesce(NOTE_CUSNBR,''), 
            coalesce(NOTE_BUSNSS,''), 
            coalesce(NOTE_ENTITY,''), 
            coalesce(NOTE_HDQTRS,''), 
            coalesce(NOTE_RPTCON,''),
            NOTE_FULNME, 
            coalesce(NOTE_AGNIDN,''), 
            iCurrDate, 
            iCurrTime, 
            NOTE_REASN, 
            NOTE_TUSER, 
            iCurrDate, 
            coalesce(NOTE_TAGGED,''), 
            iCurrDate, 
            NOTE_PRIOR, 
            coalesce(NOTE_DTASRC,''),
            iCurrDate, 
            iCurrTime,
            iNewNoteID
        FROM
            tblNotesV3 TblSource;

    END;
    END IF;

    -- There are attachments to link
    IF EXISTS(SELECT * FROM tblDocLinks)
    THEN
    BEGIN
        CALL public.proc_Documents_AddLinkMultiple_LinkID (tblDocLinks, 9, 0, sNoteID, iUserID);
    END;
    END IF;
     iNoteID := iNewNoteID;
     iNoteActivityID := 0;  

END;
$BODY$;

Я пытаюсь вызвать свою функцию двумя способами:

Метод 1:

SELECT public.proc_MC2CDNPF_InsertUpdateV3
(
    (SELECT w::typupdate_notesv3 FROM (TABLE tblnotesv31) w ) ,
    (SELECT w1::typupdate_guidparameter FROM (TABLE tbldoclinks1) w1 ) ,
    1,
    'test text'
)  

Но это не удается со следующей ошибкой:

ОШИБКА: запрос не имеет места назначения для данных результатов СОВЕТ: Если вы хотите отказаться от результатов SELECT, вместо этого используйте PERFORM. КОНТЕКСТ: функция PL/pgSQL proc_mc2cdnpf_insertupdatev3(typupdate_notesv3,typupdate_guidparameter,integer,character Variable), строка 41 в операторе SQL Состояние SQL: 42601

Метод 2:

SELECT * 
from proc_MC2CDNPF_InsertUpdateV3
(
    (SELECT w::typupdate_notesv3 FROM (TABLE tblnotesv31) w ) ,
    (SELECT w1::typupdate_guidparameter FROM (TABLE tbldoclinks1) w1 ) ,
    1,
    'test text'
)  

Опять не удалось сказать:

ОШИБКА: запрос не имеет места назначения для данных результатов СОВЕТ: Если вы хотите отказаться от результатов SELECT, вместо этого используйте PERFORM. КОНТЕКСТ: функция PL/pgSQL proc_mc2cdnpf_insertupdatev3(typupdate_notesv3,typupdate_guidparameter,integer,character Variable), строка 41 в операторе SQL Состояние SQL: 42601

Может ли кто-нибудь помочь мне, что на самом деле не так с моим вызовом функции?


person Muhammad Waheed    schedule 15.11.2019    source источник
comment
Опубликуйте полную функцию.   -  person sticky bit    schedule 15.11.2019
comment
@stickybit добавлен   -  person Muhammad Waheed    schedule 15.11.2019


Ответы (1)


Начиная со строки 41 (как сказано в сообщении об ошибке), вы получили:

SELECT dtCurrDateTime = fnGetDate();
SELECT iCurrDate = fnMC2DateToMC2(dtCurrDateTime);
SELECT iCurrTime = fnMC2DateTimeToMC2(dtCurrDateTime);

Я предполагаю, что вы хотите установить переменные там. Но ты делаешь это неправильно. (Похоже, вы пытались использовать синтаксис SQL Server. Является ли это попыткой перенести функцию из SQL Server в Postgres? Существуют также блоки BEGIN ... END для IF и ELSE, которые не нужны (но безвредны) в Postgres, но необходимы в SQL Server. .)

Либо используйте INTO:

SELECT fnGetDate() INTO dtCurrDateTime;
SELECT fnMC2DateToMC2(dtCurrDateTime) INTO iCurrDate;
SELECT fnMC2DateTimeToMC2(dtCurrDateTime) INTO iCurrTime;

Или, поскольку вы на самом деле не запрашиваете таблицу, простые присваивания тоже должны работать:

dtCurrDateTime = fnGetDate();
iCurrDate = fnMC2DateToMC2(dtCurrDateTime);
iCurrTime = fnMC2DateTimeToMC2(dtCurrDateTime);

Там могут быть и другие строки с такой же ошибкой, вы должны проверить весь код.

person sticky bit    schedule 15.11.2019
comment
ОШИБКА: запрос не имеет места назначения для данных результатов КОНТЕКСТ: функция PL/pgSQL proc_mc2cdnpf_insertupdatev3 (typupdate_notesv3, typepupdate_guidparameter, целое число, изменяющийся символ) строка 111 в операторе SQL Состояние SQL: 42601 - person Muhammad Waheed; 15.11.2019
comment
@MuhammadWaheed: В основном то же самое. RETURNING ... следует за INSERT ..., но ему не нужно никуда идти. Удалите RETURNING ..., если вам это значение не нужно, или назначьте его переменной с INTO .... - person sticky bit; 15.11.2019
comment
ОШИБКА: синтаксическая ошибка в конце строки ввода 107: ) ВОЗВРАЩЕНИЕ в iNewNoteID; ^ Состояние SQL: 42601 Символ: 3470 - person Muhammad Waheed; 15.11.2019
comment
Вышеупомянутая ошибка появляется, когда я меняю ее на RETURNING INTO - person Muhammad Waheed; 15.11.2019
comment
Синтаксис ... RETURNING <column_name> INTO <variable_name>. Но вы, кажется, пытаетесь ... RETURNING INTO <column_name>. - person sticky bit; 15.11.2019
comment
ОШИБКА: процедура public.proc_documents_addlinkmultiple_linkid(typupdate_guidparameter, integer, integer, character Variable, integer) не существует. СТРОКА 1: ВЫЗОВ public.proc_Documents_AddLinkMultiple_LinkID (tblDocLin... - person Muhammad Waheed; 15.11.2019