2014-12-15 2 views
-3

Я хочу написать функцию в Postgres для хранимой процедуры Microsoft SQL Server, показанной здесь. Пожалуйста, помогите. Я хочу использовать эту хранимую процедуру в postgres как функцию.Сохраненная процедура SQL Server в Postgres

USE [EMS_Demo_Db] 
GO 
/****** Object: StoredProcedure [dbo].[SP_HourWise] Script Date: 16-12-2014 10:48:53 AM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[SP_HourWise] 
@date_param datetime 
AS 
BEGIN 
    SET NOCOUNT ON; 
DECLARE @start_time datetime = dateadd(HOUR, 6, @date_param) 

; WITH Hours AS (
    SELECT dateadd(HOUR, row_number() OVER(ORDER BY From_Time) - 1, @start_time) AS From_Time, 
      dateadd(HOUR, row_number() OVER(ORDER BY From_Time), @start_time) AS To_Time 
    FROM Table_2 
) 
SELECT CONVERT(varchar,@date_param, 103) 
as Date_def, convert(time(0), h.From_Time) AS From_Time, convert(time(0), h.To_Time) AS To_Time, 
     MAX(t1.Param_Val) - MIN(t1.Param_Val) as Cal_ParamValue 
FROM Table_1 t1 
JOIN Hours h ON t1.Timestamp_col BETWEEN h.From_Time AND h.To_Time 
WHERE Timestamp_col BETWEEN @start_time AND dateadd(HOUR, 24, @start_time) 
GROUP BY h.From_Time, h.To_Time 
HAVING COUNT(*) > 1 
ORDER BY h.From_Time 
END 

Старинное SP, но он дает ошибку как

Unexpected End of function definition at end of input Line 17 : END$BODY$

CREATE FUNCTION sp_hourwise(OUT from_time time without time zone, OUT to_time time without time zone, OUT param_value bigint, INOUT timestamp_col timestamp without time zone) RETURNS record AS 
$BODY$DECLARE v_start_time timestamp(3) = interval '6 HOUR' + @date_param; 
BEGIN 
With Hours As (
SELECT v_start_time + (row_number() OVER(ORDER BY from_time) - 1) * INTERVAL '1 day' AS from_time, 
v_start_time + (row_number() OVER(ORDER BY from_time)) * INTERVAL '1 day' AS to_time 
    FROM table_2 
) 
SELECT CAST(time(0) h.from_time), CAST(time(0) h.to_time), 
     MAX(t1.param_value) - MIN(t1.param_value) 
FROM Table_1 t1 
JOIN Hours h ON t1.timestamp_col BETWEEN h.from_time AND h.to_time 
WHERE timestamp_col BETWEEN v_start_time AND interval '24 HOUR' + v_start_time 
GROUP BY h.from_time, h.to_time 
HAVING COUNT(*) > 1 
ORDER BY h.from_time 
END$BODY$ 
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF; 
+0

'convert' переводит на' cast() '. '' 'Идет в ** конце ** инструкции не в начале. Примеры функций, возвращающих результаты, см. В руководстве: http://www.postgresql.org/docs/current/static/xfunc-sql.html –

+0

Что относительно dateadd, с AS ... Можете ли вы разместить преобразованный SP – Parth

+2

Это не бесплатная служба написания кода, которую вы должны продемонстрировать своими силами. Общие выражения таблицы одинаковы: http://www.postgresql.org/docs/current/static/queries-with.html Дата арифметики также объясняется в руководстве: http://www.postgresql.org/docs/current /static/functions-datetime.html –

ответ

0

я изменил и, наконец, решены вопросы, получили требуемое result.Below является правильным и тестируемый хранимая процедура. Спасибо всем за помощь.

CREATE OR REPLACE FUNCTION tested_sp(INOUT date_param date, OUT from_time time without time zone, OUT to_time time without time zone, OUT cal bigint) 
    RETURNS SETOF record AS 
$BODY$ 
    DECLARE 
    start_time Timestamp = interval '6 HOUR' + date_param; 
    BEGIN 
return query 
     With Hours As (
     SELECT INTERVAL '1 hour' * (row_number() OVER(ORDER BY table_2.from_time) - 1) + start_time AS from_time, 
     INTERVAL '1 hour' * (row_number() OVER(ORDER BY table_2.from_time)) + start_time AS to_time 
     FROM table_2 
    ) 
     SELECT date_param::date as Date_Def,CAST(h.from_time as time) as from_time, 
      CAST(h.to_time as time) as to_time, 
      CAST(SUM(t1.param_value) AS bigint) as Cal 
     FROM table_1 t1 
     JOIN Hours h ON t1.timestamp_col BETWEEN h.from_time AND h.to_time 
     WHERE timestamp_col BETWEEN start_time AND interval '24 HOUR' + start_time 
     GROUP BY h.from_time, h.to_time 
     HAVING COUNT(*) > 1 
     ORDER BY h.from_time; 
    END; 

$BODY$ 
    LANGUAGE plpgsql VOLATILE 
+0

Направляйте меня туда, где я ошибаюсь. – Parth

+0

Не добавляйте дополнительную информацию (и вопросы) в качестве ответов. ** Изменить ** ваш вопрос –

2

Есть несколько ошибок в вашем скрипте:

  1. вам нужно отделить «доллар цитаты» из фактических ключевых слов. Наиболее распространенный способ сделать это, чтобы написать «долларовую цитату» на линии его собственный:

    $BODY$ 
    DECLARE 
        ... 
    END 
    $BODY$ 
    
  2. Заявление должно быть прекращено с ;

    order by h.from_time; --<< the ; makes a difference 
    
  3. А блок должны завершаться ;, а также:

    END; --<< the ; makes a difference 
    $BODY$ 
    
  4. Ваш оператор выбора не имеет цели, но, как вы хотите простофиля LY возвращает результат, который вы можете использовать return query

  5. Параметры не начинаются с префикса @, как ясно описано в руководстве:
    http://www.postgresql.org/docs/current/static/plpgsql-declarations.html

  6. Там нет параметра date_parm, что вы используете для объявления v_start_time

  7. оператор присваивания := не =

  8. Вы никогда не присваиваете значение ваших OUT параметров, так что вы можете просто объявить их как IN (или выйти из спецификатора полностью)

  9. В cast() функции нуждается в as ключевом слове и параметры обратные as documented in the manual:

    CAST(h.from_time AS time(0)) 
    

    вы также можете использовать Postgres' короче :: обозначения: h.from_time::time

  10. для ясности вы, вероятно, хотите DEF в качестве функции returns table (...) и указать имена столбцов в объявлении функции. Когда вы используете returns record, вам нужно указывать имена столбцов каждый раз, когда вы используете .

Чтобы вернуть один из входных параметров в результате, добавить определение столбца в returns table (...) части и включить параметр как часть оператора выбора:

Принимая все вышеперечисленное что-то вроде следующего должны это сделать:

CREATE FUNCTION sp_hourwise(from_time time without time zone, to_time time without time zone, date_param date) 
RETURNS table (some_date_column date, from_time time, to_time time, diff integer) 
AS 
$BODY$ 

    DECLARE 
    v_start_time timestamp(3) := interval '6 HOUR' + date_param; --- I don't know which parameter you want to use here. 

    BEGIN 

    return query 
     With Hours As (
     SELECT v_start_time + (row_number() OVER(ORDER BY from_time) - 1) * INTERVAL '1 day' AS from_time, 
       v_start_time + (row_number() OVER(ORDER BY from_time)) * INTERVAL '1 day' AS to_time 
     FROM table_2 
    ) 
     SELECT date_param, 
      CAST(h.from_time as time), 
      CAST(h.to_time as time), 
      MAX(t1.param_value) - MIN(t1.param_value) as diff 
     FROM Table_1 t1 
     JOIN Hours h ON t1.timestamp_col BETWEEN h.from_time AND h.to_time 
     WHERE timestamp_col BETWEEN v_start_time AND interval '24 HOUR' + v_start_time 
     GROUP BY h.from_time, h.to_time 
     HAVING COUNT(*) > 1 
     ORDER BY h.from_time; 

    END; 

$BODY$ 
LANGUAGE plpgsql 
VOLATILE NOT LEAKPROOF; 

Состояние WHERE timestamp_col BETWEEN v_start_time AND interval '24 HOUR' + v_start_time выглядит запутанным. Вы назвали параметр «_col», но используете его, как если бы он был столбцом в таблицах. Это колонка? Тогда вам не нужно объявлять об этом. Если нет, я бы рекомендовал использовать другое имя для параметра (но, возможно, это результат того, что вы пытаетесь запутать код).

+0

результат ошибки после выполнения функцииERROR: ссылка столбца «from_time» неоднозначна LINE 2: ... SELECT v_start_time + (row_number() OVER (ORDER BY from_time) ... ^ ДЕТАЛИ: Он может ссылаться либо на переменную PL/pgSQL, либо на столбец таблицы. QUERY: With Hours As ( SELECT v_start_time + (row_number() OVER (ORDER BY from_time) - 1) * INTERVAL '1 день' AS from_time, v_start_time + (row_number() OVER (ORDER BY from_time)) * INTERVAL '1 день' AS to_time FROM table_2 – Parth

+0

@Parth: Затем префикс имени столбца с псевдонимом таблицы (и вам также следует избегать использования имени параметра, которое идентично имя столбца). –

+0

Да timestamp_col - столбец n В моем случае есть две таблицы table_1 со столбцом [timestamp_col, param_value] и table_2 с столбцами [from_time, to_time]. Да, вы пишите, я скорректировал и добавил параметр date_param в качестве параметра и удалил другие параметры, которые фактически были именем столбца. – Parth

Смежные вопросы