簡體   English   中英

如何遍歷表並更新pl / sql中的值

[英]How to loop through table and update values in pl/sql

我們有Oracle 12數據庫。

我需要遍歷表並根據上一行更新值。 像下面一樣,我需要從第1行獲取值並將其更新為第2至6行。然后從第7行獲取新值並繼續進行到表末尾。 column1是csv格式的文本,因此我需要從那里提取數字值。

id  column1 column2
1   xxx;yyy;zzz;123456; 
2   aaa 
3   bbb 
4   ccc 
5   ddd 
6   eee 
7   xxx;yyy;zzz;789123; 
8   aaa

更新后的表應如下所示:

id  column1 column2
1   xxx;yyy;zzz;123456; 
2   aaa 123456
3   bbb 123456
4   ccc 123456
5   ddd 123456
6   eee 123456
7   xxx;yyy;zzz;789123; 
8   aaa 789123

Tbh我對pl / sql沒有太多經驗。 我試圖在循環中使用pl / sql,但是沒有用。

如果有人可以將我踢向正確的方向,將不勝感激。

您不需要PL / SQL,可以使用MERGELAG( ... ) IGNORE NULLS ...分析函數和REGEXP_SUBSTR的組合完全通過SQL來完成(提取子字符串):

MERGE INTO table_name dst
USING (
  SELECT id,
         CASE WHEN val IS NULL
              THEN LAG( val ) IGNORE NULLS OVER ( ORDER BY id )
         END AS val
  FROM   (
    SELECT id,
           REGEXP_SUBSTR( column1, ';(\d{6});$', 1, 1, NULL, 1 ) AS val
    FROM   table_name
  )
) src
ON ( dst.id = src.id )
WHEN MATCHED THEN
  UPDATE SET column2 = src.val;

更新后的表格:

id  column1             column2
--  ------------------- -------
1   xxx;yyy;zzz;123456; 
2   aaa                 123456
3   bbb                 123456
4   ccc                 123456
5   ddd                 123456
6   eee                 123456
7   xxx;yyy;zzz;789123; 
8   aaa                 789123

這樣的事情應該做你想要的。 它遍歷該表,每次以“ xxx”開頭時,將第一條記錄的最后一位傳遞給變量,如果沒有則更新第2列。

DECLARE
    L_UpdateVal VARCHAR2(10) := '';
BEGIN
    FOR REC IN (SELECT Column1, column2, ROWNUM From table) LOOP
        IF SUBSTR(REC.column1, 1, 3) = 'xxx' THEN
            L_UpdateVal := SUBSTR(column1, 13, 6);
        ELSE
            UPDATE Table SET Column2 = L_UpdateVal
                WHERE ROWNUM := REC.ROWNUM
        END IF;
    END LOOP;
END;

您不需要PL / SQL,可以在一個MERGE語句中完成。

首先,找出如何獲得所需的結果-您可以使用LAST_VALUE()分析函數來完成此操作,如下所示:

WITH your_table AS (SELECT 1 id, 'xxx;yyy;zzz;123456;' column1, NULL column2 FROM dual UNION ALL
                    SELECT 2 id, 'aaa' column1, NULL column2 FROM dual UNION ALL
                    SELECT 3 id, 'bbb' column1, NULL column2 FROM dual UNION ALL
                    SELECT 4 id, 'ccc' column1, NULL column2 FROM dual UNION ALL
                    SELECT 5 id, 'ddd' column1, NULL column2 FROM dual UNION ALL
                    SELECT 6 id, 'eee' column1, NULL column2 FROM dual UNION ALL
                    SELECT 7 id, 'xxx;yyy;zzz;789123;' column1, NULL column2 FROM dual UNION ALL
                    SELECT 8 id, 'aaa' column1, NULL column2 FROM dual)
select id,
       column1,
       last_value(CASE WHEN substr(column1, -1) = ';' THEN 
                            regexp_substr(column1, ';*([[:digit:]]*)(;$)', 1, 1, NULL, 1)
                  END IGNORE NULLS) OVER (ORDER BY ID) column2
from   your_table;

        ID COLUMN1             COLUMN2
---------- ------------------- -------------------
         1 xxx;yyy;zzz;123456; 123456
         2 aaa                 123456
         3 bbb                 123456
         4 ccc                 123456
         5 ddd                 123456
         6 eee                 123456
         7 xxx;yyy;zzz;789123; 789123
         8 aaa                 789123

然后,您可以在MERGE語句中使用它進行更新,如下所示:

MERGE INTO your_table tgt
  USING (select id,
                column1,
                CASE WHEN substr(column1, -1) = ';' THEN 'Y' ELSE 'N' END driving_column1,
                last_value(CASE WHEN substr(column1, -1) = ';' THEN 
                                     regexp_substr(column1, ';*([[:digit:]]*)(;$)', 1, 1, NULL, 1)
                           END IGNORE NULLS) OVER (ORDER BY ID) column2 -- assuming id drives the correct order to use here
         from   your_table) src
  ON (tgt.id = src.id) -- assuming id is the primary key of your_table
WHEN MATCHED THEN
  UPDATE SET tgt.column2 = src.column2;

如果您不想更新其中的值是csv值的column1行的column2(我假設如果它們是csv值,則會出現分號),那么您可以更新ON子句以包括and driving_column1 = 'N'或者您可以將源子查詢包裝在過濾對Driving_column1的外部查詢中(不幸的是,您不能對同一查詢中的分析函數進行過濾),也可以在where子句中添加where子句合並語句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM