【问题标题】:Procedure with cursor to auto fill a column in Oracle使用光标自动填充 Oracle 中的列的过程
【发布时间】:2018-04-04 12:57:35
【问题描述】:

我有一张名为 holidays 的表格,如下所示

date       |hol_name            |hol_id
-----------------------------------------
 01-01-2011|New Year's Day      |1     
02-01-2011 |Substitute Bank Hol |2           |2 

还有另一个表Date,它的所有日期都是2011年

date_id|Date      |is_holiday
------------------------------
221    |01-01-2011|  
222    |02-02-2011| 
223    |03-01-2011|
224    |04-01-2011|    

我想创建一个程序来使用光标自动填充列 is_holiday,该光标将使用 holidays 作为查找,然后填充 Y 如果日期是假期,则 N 如果不是。我只是有点困惑如何去做。创建一个返回 0 或 1 的函数然后在过程中使用它来自动填充会更好吗?也就是说,如果它返回1,那么光标将插入Y,如果它返回0,它将插入N。请指点我正确的方向

【问题讨论】:

标签: sql oracle plsql


【解决方案1】:

您可以从表中删除列 is_holiday 并创建一个类似的视图

select d.date_id, d.date, nvl2(h.hol_id,'Y','N') as is_holiday 
    from date d left join holidays h on d.date = h.date;

这样它就永远是最新的。

但我会将 table_name 和 column_name 从 DATE 重命名为其他名称以避免任何问题。 date 是保留字。

否则,一个简单的更新就足够了。

update date du set is_holidays = (select nvl2(h.date,'Y','N') from date d left join holidays h on d.date = h.date where d.date = du.date);

【讨论】:

    【解决方案2】:

    我想创建一个程序来自动填充 is_holiday 列

    这可以使用像这样的TRIGGER 来完成。

    CREATE OR REPLACE TRIGGER trg_holiday BEFORE
    UPDATE OR INSERT ON DATES
    FOR EACH ROW
    BEGIN
        SELECT MAX(CASE 
                    WHEN date_t = :NEW.date_t
                        THEN 'Y'
                    ELSE 'N'
                    END)
        INTO :NEW.is_holiday
        FROM holidays;
    END;
    /
    

    请注意,Date 是关键字,不应用于表名和列名。

    如果您希望通过procedure 进行操作,您可以在您的过程中运行MERGE INTO

    MERGE INTO DATES t
    USING (
        SELECT d.date_id
            ,d.date_t
            ,CASE 
                WHEN h.date_t IS NULL
                    THEN 'N'
                ELSE 'Y'
                END AS is_holiday
        FROM dates d
        LEFT JOIN holidays h ON d.date_t = h.date_t
        ) s
        ON (t.date_id = s.date_id)
    WHEN MATCHED
        THEN
            UPDATE
            SET t.is_holiday = s.is_holiday;
    

    或者这两个更新

    UPDATE Dates d
    SET IS_HOLIDAY = 'Y' WHERE EXISTS ( 
                         select 1 FROM holidays  h where h.date_t = d.date_t );
    
    UPDATE Dates d
    SET IS_HOLIDAY = 'N' WHERE NOT EXISTS ( 
                         select 1 FROM holidays  h where h.date_t = d.date_t ); 
    

    Demo

    【讨论】:

    • 谢谢。触发器似乎是一个不错的选择。我会尝试的
    • 您还需要在假期触发器上添加一个触发器,以便在添加新假期时更新日期表。
    • @dwalker :如果有帮助,请告诉我。另外,请阅读:stackoverflow.com/help/someone-answers
    【解决方案3】:

    您不需要使用存储过程,因为您可以根据以下查询创建视图。

    create view dbo.dates_vw (date_id, dte,is_holiday)
    as
      select d.date_id, d.dte,
      case when h.dte is null
        then 'N' else 'Y' end as is_holiday
      from dates d
     left join holidays h
     on d.dte=h.dte; 
    

    【讨论】:

      猜你喜欢
      • 2016-01-27
      • 2010-10-20
      • 2013-05-19
      • 2017-09-25
      • 2012-01-13
      • 2021-11-05
      • 1970-01-01
      • 2020-01-06
      • 1970-01-01
      相关资源
      最近更新 更多