【问题标题】:TRANSACT SQL to PL/pgSQL将 SQL 转换为 PL/pgSQL
【发布时间】:2014-07-16 11:56:12
【问题描述】:

我有很多函数和存储过程要从 MS SQL 服务器导出到 PostgreSQL

你能帮我实现这个功能并给我 PL/pgSQL for PostgreSQL 中的等效功能吗?

USE [METRICS]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[fnPSR_CtrlNouveauProjet]
(
    @InstanceID int,
    @Month_Param nvarchar(15)
)
RETURNS nvarchar(2)
AS
BEGIN
    DECLARE @ReturnValue NVARCHAR(2), @Max_ID_Token int
    DECLARE @Month_Param_Prev nvarchar(15)
    SELECT @Month_Param_Prev = CASE WHEN @Month_Param like '%-08' THEN  SUBSTRING(CONVERT(VARCHAR(10), DATEADD(MONTH, DATEDIFF(MONTH, 0, '01-'+@Month_Param) - 2, 0), 105),4,10) 
         ELSE  SUBSTRING(CONVERT(VARCHAR(10), DATEADD(MONTH, DATEDIFF(MONTH, 0, '01-'+@Month_Param) - 1, 0), 105),4,10) end 
    DECLARE @KIS_FileName NVARCHAR(100)
    SELECT 
        @KIS_FileName = KI.KIS_FileName 
    FROM 
        PSR_KIS_INSTANCE KI (NOLOCK)
    WHERE
        KI.ID_Instance = @InstanceID

    SELECT @Max_ID_Token = MAX(KI.ID_Token) FROM DBO.PSR_KIS_INSTANCE KI (NOLOCK) WHERE KI.KIS_FileName = @KIS_FileName and KI.Reporting_Month = @Month_Param_Prev

    IF (EXISTS(SELECT 
        KI.ID_Instance 
    FROM 
        PSR_KIS_INSTANCE KI (NOLOCK) 
    WHERE 
        KI.KIS_FileName  = @KIS_FileName
        and KI.Reporting_Month = @Month_Param_Prev 
        and KI.ID_Token = @Max_ID_Token))

    BEGIN
        SET @ReturnValue = ' '
    END
    ELSE
    BEGIN
        SET @ReturnValue = 'N'
    END

    RETURN @ReturnValue

END

【问题讨论】:

  • 你能帮我实现这个功能,并给我在 PL/pgSQL for PostgreSQL 中的等效功能吗?你能先给我钱吗?
  • 您至少可以发布一个适当的问题,其中包含表格定义和一些解释以及您尝试过的内容以及软件的确切版本号。

标签: sql-server postgresql tsql plpgsql


【解决方案1】:

我的 T-SQL 确实生锈了,但是这样的事情应该可以帮助您入门:

这是未经测试的,不会编译

create or replace function fnPSR_CtrlNouveauProjet(p_instance_id integer, p_month_param varchar)
  return varchar
as
$body$
declare
   l_return_value VARCHAR(2);
   l_max_id_token integer;
   l_mont_param_prev varchar(15);
   l_kis_filename varchar(100);

   -- I have NO idea what the following is doing.
   SELECT @Month_Param_Prev = 
       CASE WHEN @Month_Param like '%-08' 
         THEN  SUBSTRING(CONVERT(VARCHAR(10), DATEADD(MONTH, DATEDIFF(MONTH, 0, '01-'+@Month_Param) - 2, 0), 105),4,10) 
         ELSE  SUBSTRING(CONVERT(VARCHAR(10), DATEADD(MONTH, DATEDIFF(MONTH, 0, '01-'+@Month_Param) - 1, 0), 105),4,10) 
       end 

    SELECT ki.kis_filename 
      INTO l_kis_filename
    FROM psr_kis_instance ki
    WHERE ki.id_instance = p_instance_id;

    SELECT MAX(ki.id_token) 
      INTO l_max_id_token
    FROM psr_kis_instance ki 
    WHERE ki.kis_filename = l_kis_filename
      AND reporting_month = l_month_param_prev;

    SELECT count(*)
       INTO l_count 
    FROM psr_kis_instance ki
    WHERE ki.kis_filename = l_kis_filename
      and ki.reporting_month = l_month_param_prev
      and ki.id_token = l_max_id_token;

    if l_count = 1 then 
      l_return_value = ' '
    else
      l_return_value = 'N';
    end if;

    RETURN l_return_value;
END;
$body$
language plpgsql;

一些注意事项:

  • Postgres 中不需要(NOLOCK)。读取器从不阻止写入器,写入器从不阻止读取器。
  • 没有NVARCHAR 数据类型。 VARCHAR 和你用 UTF-8 创建数据库一样好
  • 在 Postgres 中也不需要 dbo 前缀。但是,您可以根据需要创建具有该名称的模式,以使迁移更容易。
  • 习惯于不带引号的名称被折叠成小写的事实。因此,不要使用CamelCaseIdentifier,而是养成使用下划线分隔单词的习惯。使用类似fn_psr_ctrl_nouveau_projet 的东西。不带引号的标识符不区分大小写,因此您也可以使用fn_PSR_Ctrl_Nouveau_Projet
  • 我感觉这三个 SQL 语句可以合并为一个语句(这样效率更高),但是由于您没有费心解释您在做什么,这很难说。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-18
    • 2013-11-08
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 2011-08-08
    • 2014-03-31
    • 2015-09-16
    相关资源
    最近更新 更多