給定一個表T(x, y, z, t, u, v, ...)
是否有可能在Oracle中編寫該查詢而不列出所有列(在SELECT中還是在INSERT部分中)?如何複製只更改一列的值而不列出其他列的一組行?
INSERT INTO T (x, y, z, t, u, v, ...)
SELECT 'new', y, z, t, u, v, ...
FROM T
WHERE x = 'old'
的影響是,它x
有老值的所有行都是相同的,只是現在x
有新值。
給定一個表T(x, y, z, t, u, v, ...)
是否有可能在Oracle中編寫該查詢而不列出所有列(在SELECT中還是在INSERT部分中)?如何複製只更改一列的值而不列出其他列的一組行?
INSERT INTO T (x, y, z, t, u, v, ...)
SELECT 'new', y, z, t, u, v, ...
FROM T
WHERE x = 'old'
的影響是,它x
有老值的所有行都是相同的,只是現在x
有新值。
「是否有可能在甲骨文寫這個查詢沒有列出所有 列(不管是在SELECT還是在INSERT部分)「
否。避免輸入顯式投影的唯一方法是使用所有表格的列。你不這樣做,因爲你想使用文字而不是列X
。這意味着您必須在SELECT投影中列出所有其他列。
當然,您不必在INSERT子句中指定列。
在開發人員偶爾希望對年「除了」語法,是這樣的:
select * except X from t
,但它從未進入ANSI標準。事實上,我懷疑它是否被討論過。
「PLSQL答案,歡迎呢!」
好的,這裏是使用數據字典生成動態插入語句的概念證明。
它作以下假設:
如果這些假設中的任何一個錯誤,您將需要調整代碼。
該過程圍繞USER_TAB_COLUMNS表循環,將列排序爲表的投影順序。它將列名連接到INSERT語句的SELECT子句中,除非名稱是連接所提供的文字時替換列的名稱。最後它使用本地動態SQL來運行組裝的INSERT語句。
create or replace procedure clone_minus_one
(p_sub_col in user_tab_columns.column_name%type
, p_sub_val in varchar2)
is
stmt varchar2(32767) := 'insert into source_table select ';
begin
for lrec in (select column_name
, column_position
from user_tab_columns.
where table_name = 'SOURCE_TABLE'
order by column_position)
loop
if lrec.column_position != 1
then
stmt := stmt ||',';
end if;
if lrec.column_name != p_sub_col
then
stmt := stmt ||lrec.column_name;
else
stmt := stmt ||''''||p_sub_val||'''';
end if;
end loop;
stmt := stmt || ' from source_table';
execute immediate stmt;
end;
/
您可以按照您的描述完成,只要您選擇的列正確排列。
以下是有效的
INSERT INTO T
SELECT 'new', y, z, t, u, v, ...
FROM T
WHERE x = 'old'
,或者你可以試試這個(粗糙的腳本未測試)
CREATE TABLE TEMPTABLE AS SELECT * FROM T WHERE X = 'Old';
UPDATE TEMPTABLE SET X='New';
INSERT INTO T (SELECT * FROM TEMPTABLE);
DROP TABLE TEMPTABLE;
您必須在選擇中列出所需的所有列,但只要它們按正確的順序映射到列,則查詢將起作用。 –
@Hugh Jones:好的,重新提出的問題:我想避免列出INSERT部分中的所有列,並在SELECT部分列出除x以外的所有列。這不夠清楚嗎? – Benoit
我迂腐了嗎?抱歉。 –
以下是走得太遠,以免一些打字海事組織,但我喜歡挑戰,所以這裏去...
insert into T
select * from T
where x='old';
commit;
-- update every other row to 'new'
update T
set x='new'
where rowid in
(
select rowid from
(select rownum rnum, rowid row_id
from T
where x='old'
)
where mod(rnum,2)=0
);
commit;
在2個步驟,而我個人倒在只查詢表格的all_tab_columns(按column_id排序)並複製/粘貼到我的腳本/過程中。但可能是一些其他的原因,以避免這一點,不知道。
你試過了嗎? –
@Hugh Jones:當然,INSERTING沒有列出列將插入默認值。我想複製現有的行。 – Benoit
您在上面顯示的查詢將具有您正在尋找的效果。 –