oracle 如何在过程的where子句中放置条件?

xvw2m8pv  于 2022-11-22  发布在  Oracle
关注(0)|答案(2)|浏览(175)

我想根据过程中参数的空条件在where子句中加入一个条件,但是我做的过程有问题,问题出在IF子句中。
如何在过程的where子句中放置条件?

CREATE OR REPLACE PROCEDURE SP_PROCEDURE(START_DATE, END_DATE)
    IS
      START_DATE DATE;
      END_DATE DATE;
    BEGIN
      START_DATE := TO_DATE(START_DATE, 'YYYYMMDD');
      END_DATE := TO_DATE(END_DATE, 'YYYYMMDD');
    
      INSERT INTO USER
        (
          USR_KEY,
          USR_NAME
        )
      SELECT
        USR_KEY,
        USR_NAME
      FROM
        USER
      WHERE
        1 = 1
        IF START_DATE THEN --I think there's problem here..
          AND USR_CRT_DATE >= START_DATE
        END IF;
    
    COMMIT;
    
      EXCEPTION
      
        WHEN OTHERS THEN
            ROLLBACK;
    END;
utugiqy6

utugiqy61#

如果我没阅读你的要求,这应该可以了

CREATE OR REPLACE PROCEDURE SP_PROCEDURE(START_DATE, END_DATE)
    IS
      START_DATE DATE;
      END_DATE DATE;
    BEGIN
      START_DATE := TO_DATE(START_DATE, 'YYYYMMDD');
      END_DATE := TO_DATE(END_DATE, 'YYYYMMDD');
    
      INSERT INTO USER
        (
          USR_KEY,
          USR_NAME
        )
      SELECT
        USR_KEY,
        USR_NAME
      FROM
        USER
      WHERE (USR_CRT_DATE >= START_DATE
             or START_DATE is null );
    
    COMMIT;
    
    END;

您不需要该异常处理程序。默认情况下,如果PL/SQL单元失败,它会将更改回滚到过程的开始点。

idv4meu8

idv4meu82#

  • 过程签名中缺少数据类型。
  • 不要对已经是DATE的值使用TO_DATE(因为它会隐式地将日期转换为字符串,然后再转换回日期,这很可能会在转换中引入错误)。如果要删除日期的时间部分,请使用TRUNC,而不要尝试使用TO_DATE
  • 在一个过程中使用COMMIT是不好的做法,因为它不允许您将多个过程链接在一起,如果一个过程失败,您可以使用ROLLBACK将它们全部链接起来;而是应该在调用该过程的事务中使用COMMIT
  • USER是关键字,不能用作未加引号的标识符;最佳做法是将表命名为不是关键字的名称,但也可以使用带引号的标识符(这不是最佳做法)。
CREATE OR REPLACE PROCEDURE SP_PROCEDURE(
  START_DATE IN DATE,
  END_DATE   IN DATE
)
IS
BEGIN
  INSERT INTO "USER" (
    USR_KEY,
    USR_NAME
  )
  SELECT USR_KEY,
         USR_NAME
  FROM   "USER"
  WHERE  (START_DATE IS NULL OR USR_CRT_DATE >= TRUNC(START_DATE));
END;
/

fiddle

相关问题