【问题标题】:Convert PL SQL function to T-SQL with cursor loop and fetch使用游标循环将 PL SQL 函数转换为 T-SQL 并获取
【发布时间】:2021-01-26 03:51:57
【问题描述】:

函数代码如下:

CREATE OR REPLACE FUNCTION FTTH_GETBUSZONECODEMULTI(
    p_house_nbr        IN VARCHAR2,
    p_as_of_date       IN DATE DEFAULT SYSDATE)
RETURN VARCHAR2
AS
    CURSOR l_get_cur
    IS
         SELECT
            LTRIM(RTRIM(BZO.B2FEDC)) BusinessZoneCode
           FROM
           [not wasting your time with business logic]
    l_return VARCHAR2(32767);
BEGIN
    --
    FOR l_get_rec IN l_get_cur LOOP
       l_return := l_return || '|' || l_get_rec.BusinessZoneCode;
    END LOOP;
    --
    CASE
              WHEN l_return IS NULL THEN RETURN NULL;
              ELSE RETURN l_return || '|';
    END CASE;
    --
END FTTH_GETBUSZONECODEMULTI;

我的翻译尝试如下:

CREATE FUNCTION ftth_GETBUSZONECODEMULTI(
    @p_house_nbr        VARCHAR(4000),
    @p_as_of_date       DATETIME)
RETURNS VARCHAR(4000)
AS
BEGIN
   SET @p_as_of_date = GETDATE()
    DECLARE l_get_cur CURSOR LOCAL
    FOR
         SELECT
            LTRIM(RTRIM(BZO.B2FEDC)) BusinessZoneCode
           FROM
            [not wasting your time with business logic]
    DECLARE @l_return VARCHAR(MAX);
 
    --
    SET @l_return = isnull(@l_return, '') + '|' + ISNULL((FETCH BusinessZoneCode from l_get_cur), '');

    --
    if @l_return IS NULL begin RETURN NULL END
    if @l_return is not null BEGIN RETURN isnull(@l_return, '') + '|' END;
END

我认为,问题在于我如何尝试获取该值 - 即使我在其中放置了“NEXT”,它也无法正常工作。我已经尝试了 6 种不同的方式来安排 FETCH,但它们都不起作用。

【问题讨论】:

  • 真的想要一个多行标量函数中的CURSOR 吗?那会表现得很糟糕。您需要一个内联表值函数。
  • 这只是简单的字符串连接/聚合吗?并始终确定您正在使用的 sql server 的版本和版本。 TSQL 有一个TRIM 函数已经有一段时间了。
  • 这个函数的实际目标是什么?
  • 它的用途让我大吃一惊,我只是一个迁移猴子,一个接一个地执行一个函数,但我知道我不能使用表值函数,因为它被调用选择语句。它根本不会有性能,但客户设定了一个非常紧迫的截止日期,速度不是交易的一部分哈哈
  • “我不知道它的用途是什么,” 然后找出或弄清楚它的作用;如果您要迁移它需要了解它。

标签: sql sql-server tsql plsql


【解决方案1】:

这里是光标使用的一些变化,你的光标循环结束的地方我可能错了,所以你可能需要调整它:

CREATE FUNCTION ftth_GETBUSZONECODEMULTI(
    @p_house_nbr        VARCHAR(4000),
    @p_as_of_date       DATETIME)
RETURNS VARCHAR(4000)
AS
BEGIN
    declare @BusinessZoneCode varchar(500)
   SET @p_as_of_date = GETDATE()
    DECLARE l_get_cur CURSOR LOCAL
    FOR
         SELECT
            LTRIM(RTRIM(BZO.B2FEDC)) BusinessZoneCode
           FROM
            [not wasting your time with business logic]

    OPEN l_get_cur
    fetch next from l_get_cur
    into @BusinessZoneCode

    WHILE @@FETCH_STATUS = 0  
    begin 
        DECLARE @l_return VARCHAR(MAX);
 
        --
        SET @l_return = isnull(@l_return, '') + '|' + ISNULL((@BusinessZoneCode), '');

        --
        if @l_return IS NULL begin RETURN NULL END
        if @l_return is not null BEGIN RETURN isnull(@l_return, '') + '|' END

        fetch next from l_get_cur
        into @BusinessZoneCode
    end
    close l_get_cur
    deallocate l_get_cur
END

【讨论】:

  • 啊我现在明白该怎么做了!提取需要去其他地方,然后只使用一个变量。谢谢!
  • 虽然这可能回答了这个问题,@CapnShanty,但我强烈建议它不是 真正的 解决方案。在这里使用内联表值函数是真正的解决方案,#
  • Afaik,表值函数不能用作 select 语句的一部分,对吧?所以不幸的是,我被一个标量困住了
  • @CapnShanty 当然内联表值函数可以用作选择的一部分。这就是为什么 Larnu 想知道这个函数的目的是什么——所以他/我们可以协助创建一个。
猜你喜欢
  • 2013-11-08
  • 2012-03-27
  • 2012-04-28
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 2020-12-25
相关资源
最近更新 更多