使用 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.
- 第二个查询在
union
ed 链中首先设置,因为它是 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 表达式)的文档
如何通过 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. - 第二个查询在
union
ed 链中首先设置,因为它是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 表达式)的文档