使用 If else 或 case 方法合并多个相关的 firebird select 过程

Merging multiple related firebird select procedure using If else or case method

如何通过 if else、case 或其他方法使用此 REFERENCE 变量合并这两个 firebird select 过程。如果 REFERENCE = 1 则程序 1 将显示,如果 REFERENCE = 2 则程序 2 将显示。我正在尝试使用 1 个 select 带条件的程序而不是 2 个程序。

CREATE PROCEDURE PRINT_NON_REF1(
      M VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      Y VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      REFERENCE VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1)
    RETURNS(
      AP_PSTIONLVL_NON VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      AP_POSTION_NON VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      RANKING_MONTH VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      RANKING_YEAR VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1)
    AS
    BEGIN
      FOR
        SELECT
          '',
          '',
          RANKING_MONTH,
          RANKING_YEAR

        FROM APPLICANT
        WHERE RANKING_MONTH = :M AND RANKING_YEAR = :Y

        GROUP BY
        RANKING_MONTH,
        RANKING_YEAR

        INTO
          :AP_PSTIONLVL_NON,
          :AP_POSTION_NON,
          :RANKING_MONTH,
          :RANKING_YEAR
      DO
        BEGIN
          SUSPEND;
        END

    END;

CREATE PROCEDURE PRINT_NON_REF2(
      M VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      Y VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      REFERENCE VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1)
    RETURNS(
      AP_PSTIONLVL_NON VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      AP_POSTION_NON VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      RANKING_MONTH VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1,
      RANKING_YEAR VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1)
    AS
    BEGIN
      FOR
        SELECT
          AP_PSTIONLVL_NON,
          AP_POSTION_NON,
          RANKING_MONTH,
          RANKING_YEAR

        FROM APPLICANT
        WHERE RANKING_MONTH = :M AND RANKING_YEAR = :Y

        GROUP BY
        AP_PSTIONLVL_NON,
        AP_POSTION_NON,
        RANKING_MONTH,
        RANKING_YEAR

        INTO
          :AP_PSTIONLVL_NON,
          :AP_POSTION_NON,
          :RANKING_MONTH,
          :RANKING_YEAR
      DO
        BEGIN
          SUSPEND;
        END

    END;

您可以尝试这样的结构:

WITH
  Q_2 as (
      SELECT
        AP_PSTIONLVL_NON,
        AP_POSTION_NON,
        RANKING_MONTH,
        RANKING_YEAR
      FROM APPLICANT
      WHERE RANKING_MONTH = :M
        AND RANKING_YEAR = :Y
      GROUP BY
        AP_PSTIONLVL_NON,
        AP_POSTION_NON,
        RANKING_MONTH,
        RANKING_YEAR
  ), 
  Q_1 as (
     SELECT
       '',
       '',
       RANKING_MONTH,
       RANKING_YEAR
     FROM APPLICANT
     WHERE RANKING_MONTH = :M 
       AND RANKING_YEAR = :Y
     GROUP BY
       RANKING_MONTH,
       RANKING_YEAR
 )

SELECT * FROM Q_2 WHERE :REFERENCE=2
   UNION ALL
SELECT * FROM Q_1 WHERE :REFERENCE=1

注意事项:

  • 创建一个只包含一个 SELECT 的存储过程在 Firebird/Interbase 中是个坏主意。它将在加入时禁用 SQL 优化器作业,并且不会增加任何价值。 Firebird 不是 MS SQL.
  • 第二个查询在 unioned 链中首先设置,因为它是 UNION 从中获取列名和数据类型的第一个查询。 Q_1 会先走吗 - 两个匿名列会有问题。
  • 一些数据库访问库可能会遇到查询中具有相同名称的多个参数的问题。您可能需要将 :M 重命名为 :M_1:M_2 等。或者可能不需要,测试您的库。
  • 您的特定编程 language/library 可以具有与上面使用的 :name 不同的 SQL 参数语法。特别是 SQL 级别的 Firebird 本身仅支持未命名参数。检查你的图书馆文件。您还可以在 https://bobby-tables.com/
  • 阅读代码示例以获得见解
  • https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-select.html
  • 阅读有关 UNION 和 CTE(通用 Table 表达式)的文档