英文:
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;
/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论