【问题标题】:PL/SQL: re-write SELECT statement using IN parameter in stored procedurePL/SQL:在存储过程中使用 IN 参数重写 SELECT 语句
【发布时间】:2012-04-01 05:36:02
【问题描述】:

假设我有一个包含下表的 Oracle 11.2 数据库:

TABLE: SURVEY

PARAMETER    MALE   FEMALE 
--------------------------
SAMPLE_SIZE  102       95
AVG_WEIGHT   170      120
AVG_HEIGHT   5.9      5.4

这是一个最小的 PL/SQL 存储过程示例,它选择男性的平均体重并将其(例如 170)放入变量 v_stat

PROCEDURE get_stat (gender IN VARCHAR2) 
AS
    v_stat number;
BEGIN
    SELECT male INTO v_stat FROM survey WHERE parameter = 'avg_weight';
END get_stat;

注意 IN 参数 gender 在这里没有做任何事情。我想要的是传入变量gender,它可能等于“男性”或“女性”,并在SELECT语句中以某种方式使用gender(而不是“男性”)。目标是将gender 作为一个变量传入,该变量可用于返回例如gender 定义的男性或女性的平均体重。

我知道我可能可以将 IF/THEN/ELSE 语句与两个单独的 SELECT 语句一起使用,但我想知道是否有一种优雅的方法可以通过将上述 SELECT 语句中的“男性”更改为其他内容来仅使用一个 SELECT 语句?

请注意,这是我之前的问题的重做

How to programmatically set table name in PL/SQL?

这被(正确地)批评为不是一个现实的问题。

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您需要使用其他问题中建议的相同动态 SQL 方法

    PROCEDURE get_stat (gender IN VARCHAR2) 
    AS
        v_sql   varchar2(1000);
        v_param varchar2(100) := 'AVG_WEIGHT';
        v_stat  number;
    BEGIN
        v_sql := 'SELECT ' || gender || ' FROM survey WHERE parameter = :1';
        EXECUTE IMMEDIATE v_sql
                     INTO v_stat
                    USING v_param;
    END get_stat;
    

    但是您会遇到与您之前的问题中提出的相同的一般性反对意见 - 数据模型存在根本缺陷。为MALEFEMALE 调查结果设置单独的行比为malefemale 结果设置单独的列会更好。

    【讨论】:

    • 谢谢贾斯汀,为什么单独的行比列更好?这是一条有时不适用的一般经验法则,还是可以肯定地说,如果可以消除列,增加行总是更好?男性和女性的数据将始终存在。
    • @ggkmath - 至少从正确规范化的数据模型开始基本上总是最好的。正确规范化的数据模型将有一个表,其中包含 parameter、'gender, and result` 等列,而不是 parametermalefemale。一般来说,如果您发现自己需要在运行时选择不同的表或不同的列,则说明您的数据模型没有正确规范化。
    【解决方案2】:

    您需要将 SELECT 语句编写为字符串,然后在其上使用 EXECUTE IMMEDIATELY

    【讨论】:

      【解决方案3】:

      我必须看看如何转换您的示例,但我知道在 SQL Server 中您可以执行动态 SQL。还有,it appears that you can do this in Oracle

      它会变成这样(我只是通过examples here 去,因为 Oracle 不是我的正常语言)

      avg_weight_str := avg_weight;
      stmt_str := 'SELECT :gender INTO v_stat FROM survey WHERE parameter = :avg_weight_str';
      EXECUTE IMMEDIATE stmt_str;
      

      动态 SQL 的问题在于它的性能不高。虽然不优雅,但如果你只有两种方式 if,那么我会使用 if 块,这样代码的性能会更高。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-16
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        相关资源
        最近更新 更多