Ошибка при создании таблицы: синтаксическая ошибка в или около "@" - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь преобразовать хранимую функцию SQL Server в хранимую функцию PostgreSQL. Я получаю одну синтаксическую ошибку в declare @table1 table

CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID   numeric=0)
RETURNS Boolean
AS $$
    declare @table1 table 
    (
    nbuilding numeric(18, 0) NOT NULL,
    sbuild_name varchar(50) NULL,
    sclient_build_id varchar(50) NULL,
    nbuilding_inst_id numeric(18, 0) NOT NULL,
    ntemp_building_id numeric(18,0) NULL,
    nno_of_floors numeric(18,0) NULL

    )

    declare v_strDeptIds text;
            v_strSubDeptIds text;

BEGIN

        v_strsql := 'SELECT     building.*
FROM         building
        WHERE     (building.nbuilding_inst_id = '|| cast(p_nInstID as varchar(1)) ||')

         ';

         print v_strsql 
         v_strsql1 text;
         v_strsql1 := v_strsql

        Insert into @table1; execute sp_executesql;  v_strsql1 
        select * from @table1;

Return true;
END;

$$ LANGUAGE plpgsql;

Ошибка

ERROR:  syntax error at or near "@"
LINE 4:  declare @table1 table 

Может кто-нибудь сказать, пожалуйста, что я делаю не так?

1 Ответ

1 голос
/ 18 апреля 2019

Кажется, ваша функция на самом деле возвращает результат запроса SELECT, а не логическое значение, поэтому returns boolean неверно для начала.

Чтобы вернуть результат, вам нужно объявить функцию как returns table(). Но так как вы, кажется, просто возвращаете строки из таблицы building, вы можете определить ее как returns setof building.

Затем удалите бесполезный динамический SQL, который кажется совершенно ненужным.

В PL / pgSQL нет табличных переменных, и копирование результата запроса в один перед возвратом результата из этой таблицы представляется ненужным шагом, который только замедляет работу. В Postgres вы просто возвращаете результат запроса, нет необходимости хранить его локально.

Дополнительно: вместо того, чтобы приводить параметр к другому типу внутри функции, лучше объявить этот параметр с ожидаемым вами типом.

Таким образом, упрощенная версия этой функции в PostgreSQL будет выглядеть так:

CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID  text)
  RETURNS setof building
AS $$
    select building.*
    from building
    WHERE  building.nbuilding_inst_id = p_nInstID
$$ LANGUAGE sql;

Вы можете использовать это так:

select *
from ETL_GetBuildingDetailsByUserID ('42');

Не имеет отношения, но: использование numeric(18,0) для столбцов, в которых хранятся значения без десятичных знаков, является излишним. Вы должны определить эти столбцы как bigint. Гораздо быстрее и занимает меньше места, чем числовой.

...