英文:
How to use a value in a column as repetition count
问题
我有一个需要根据另一个表中的值运行多次的更新语句。以下是这些表的样子:
表1
| ROW_ID | CLOB_TEXT | 
|---|---|
| 1 | 文本 | 
| 2 | 文本 | 
表2
| HOW_MANY_TIMES | ROW_ID | 
|---|---|
| 1 | 1 | 
| 4 | 2 | 
基本上,更新语句应该在第一行上运行,但它将运行多少次取决于第二个表的第一列。我在两个表上都有ROW_ID列来将它们关联起来,以防止重复。
我应该将我的第二个表转换为下面的格式并为每一行运行更新吗?或者可能还有其他方法吗?
| COL1 | ROW_ID | 
|---|---|
| 1 | 1 | 
| 1 | 2 | 
| 2 | 2 | 
| 3 | 2 | 
| 4 | 2 | 
我可以为每一行执行单个更新,但似乎无法根据另一个表中的计数器在循环中执行更新。
英文:
I have an update statement that needs to be run as many times as a value in another table. Here are what the tables look like
TABLE 1
| ROW_ID | CLOB_TEXT | 
|---|---|
| 1 | text | 
| 2 | text | 
TABLE 2
| HOW_MANY_TIMES | ROW_ID | 
|---|---|
| 1 | 1 | 
| 4 | 2 | 
Basically update statement should run on the first row, but how many times that it will runn will be dependent based on the first col from the second table. And i have ROW_ID col on the both tables to link them to prevent repetitions.
Should i convert my second table to the format below and run updates for each row? Or is there another way to do it maybe?
| COL1 | ROW_ID | 
|---|---|
| 1 | 1 | 
| 1 | 2 | 
| 2 | 2 | 
| 3 | 2 | 
| 4 | 2 | 
I can do single updates for each row but i can't seem to do it in a loop(?) based on a counter from another table it seems.
答案1
得分: 1
你可以在单个MERGE语句中完成它(对于大型数据集,这比在PL/SQL中使用循环要高效得多):
MERGE INTO table_1 dst
USING (
  SELECT t1.ROWID AS rid,
         t2.ROW_ID,
         l.idx
  FROM   table_1 t1
         INNER JOIN table_2 t2
         ON (t1.ROW_ID = t2.ROW_ID)
         CROSS APPLY(
           SELECT LEVEL AS idx
           FROM   DUAL
           WHERE  LEVEL <= t2.how_many_times
           CONNECT BY LEVEL <= t2.how_many_times
         ) l
) src
ON (dst.ROWID = src.rid AND src.idx = 1)
WHEN MATCHED THEN
  UPDATE
  SET clob_text = src.idx
WHEN NOT MATCHED THEN
  INSERT (row_id, clob_text) VALUES (src.row_id, src.idx);
对于示例数据:
CREATE TABLE TABLE_1 (ROW_ID, CLOB_TEXT) AS
SELECT 1, EMPTY_CLOB() || 'text' FROM DUAL UNION ALL
SELECT 2, EMPTY_CLOB() || 'text' FROM DUAL;
CREATE TABLE TABLE_2 (HOW_MANY_TIMES, ROW_ID) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 4, 2 FROM DUAL;
然后,在MERGE之后,table_1 包含以下内容:
| ROW_ID | CLOB_TEXT | 
|---|---|
| 1 | 1 | 
| 2 | 1 | 
| 2 | 2 | 
| 2 | 3 | 
| 2 | 4 | 
英文:
You can do it in a single MERGE statement (which for large data sets is going to be much more efficient than loops in PL/SQL):
MERGE INTO table_1 dst
USING (
  SELECT t1.ROWID AS rid,
         t2.ROW_ID,
         l.idx
  FROM   table_1 t1
         INNER JOIN table_2 t2
         ON (t1.ROW_ID = t2.ROW_ID)
         CROSS APPLY(
           SELECT LEVEL AS idx
           FROM   DUAL
           WHERE  LEVEL <= t2.how_many_times
           CONNECT BY LEVEL <= t2.how_many_times
         ) l
) src
ON (dst.ROWID = src.rid AND src.idx = 1)
WHEN MATCHED THEN
  UPDATE
  SET clob_text = src.idx
WHEN NOT MATCHED THEN
  INSERT (row_id, clob_text) VALUES (src.row_id, src.idx);
Which, for the sample data:
CREATE TABLE TABLE_1 (ROW_ID, CLOB_TEXT) AS
SELECT 1, EMPTY_CLOB() || 'text' FROM DUAL UNION ALL
SELECT 2, EMPTY_CLOB() || 'text' FROM DUAL;
CREATE TABLE TABLE_2 (HOW_MANY_TIMES, ROW_ID) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 4, 2 FROM DUAL;
Then, after the MERGE, table_1 contains:
| ROW_ID | CLOB_TEXT | 
|---|---|
| 1 | 1 | 
| 2 | 1 | 
| 2 | 2 | 
| 2 | 3 | 
| 2 | 4 | 
答案2
得分: 0
这是你所讨论的内容吗?
开始
  对于 cur_2 在 (选择 row_id, how_many_times 从 table2) 循环
    对于 i 在 1 到 cur_2.how_many_times 循环
      更新 table1 设置
        clob_text = 替换(clob_text, 'A', 'B')
        其中 row_id = cur_2.row_id;
    结束循环;
  结束循环;
结束;
/
英文:
Is this what you're talking about?
begin
  for cur_2 in (select row_id, how_many_times from table2) loop
    for i in 1 ..cur_2.how_many_times loop
      update table1 set
        clob_text = replace(clob_text, 'A', 'B')
        where row_id = cur_2.row_id;
    end loop;
  end loop;
end;
/ 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论