
いつもお世話になります。
あるテーブルのカラムに、「ある順番に並び替えた上で」自動連番をふって更新させたいのですが、上手くいきません。
当初はシーケンスを作成して試みたのですが、並び替えた上で連番をふることができず無作為な連番になってしまいました。
そこで、色々考えまして以下のように作成しましたが、、、
update tableA set colC = (select rownum from tableA order by colA, colB);
「ORA-00907:右カッコがありません」が出てきます。
文法が間違っておりますでしょうか??
それとも他に何か良い方法がありましたらご教授いただけますでしょうか?
No.8ベストアンサー
- 回答日時:
No.5です。
変数に値を入れただけになっているため、UPDATEしないといけないですね。以下のような感じになると思います。(コンパイル確認までできていませんのでご了承ください。)
この方法ですとあえてシーケンスをつかわなくてもよいかもですね。
declare
seq_no number := 1;
cursor cur1 is
select colA, colB, colC from tableA
order by colA, colB
-- ☆追加(カーソルをFOR UPDATE付きで宣言する)
FOR UPDATE;
begin
for cur_rec in cur1
loop
--☆変更(現在レコードにUPDATEをかける)
--cur_rec.colC := seq_no;
Update tableA set colC = seq_no where current of cur1;
seq_no := seq_no + 1;
end loop;
end;
/
No.7
- 回答日時:
>平行してPL/SQLでも試みているのですが
また思い付きですが、
もうここはシンプルに
フェッチで1件づつ読みながらカレントレコードを更新するのはどうですか?
DECLARE
wk_colA tableA.colA%TYPE;
wk_colB tableA.colB%TYPE;
wk_colC tableA.colC%TYPE;
wk_連番 tableA.colC%TYPE;
CURSOR カーソル名 IS SELECT colA, colB, colC FROM tableA FOR UPDATE order by colA, colB;
BEGIN
wk_連番 の0クリア
OPEN カーソル名;
LOOP
wk_連番 の加算
FETCH カーソル名 INTO wk_colA, wk_colB, wk_colC;
UPDATE tableA SET wk_colC = wk_連番 WHERE CURRENT OF カーソル名;
EXIT WHEN カーソル名%NOTFOUND;
END LOOP;
END;
/
ところで、colA, colBでレコードはユニークになるのですか?
No.6
- 回答日時:
#3です。
>ただカラム数が多いせいか、レスポンスが非常に悪いようです。
このような作業はワンタイムで行うものかと思っていましたが。。
当然レスポンスは悪いです。ORDER BYを何回やるか考えてみたらわかるでしょう。
レコードの並べ替えはどうしても全件必要ですから、1クエリでやるとすればこれ以外の手はないはずです。
(UPDATE句にJOINしたサブクエリを記述する場合、キーが保存されている必要があるので、ROW_NUMBERでもROWNUMでも、今回の例では使えません)
カラムを個別に指定すれば以下の通り b は必要ありませんが、レスポンス改善の効果はあまり期待できません。
UPDATE TABLEA a
SET COLC=(SELECT SEQ FROM
(SELECT ROWNUM SEQ,COLA,COLB FROM (SELECT COLA,COLB FROM TABLEA ORDER BY COLA,COLB))
WHERE COLA=a.COLA AND COLB=a.COLB)
一旦、ROWNUMも保存したワークテーブルに入れてJOIN更新するしかないでしょう。
CREATE TABLE TEMP1 AS
SELECT ROWNUM AS SEQ,COLA,COLB FROM (SELECT COLA,COLB FROM TABLEA ORDER BY COLA,COLB);
ALTER TABLE TEMP1 ADD CONSTRAINT PK1 PRIMARY KEY (COLA,COLB);
UPDATE (SELECT a.COLC,b.SEQ FROM TABLEA a INNER JOIN TEMP1 b ON b.COLA=a.COLA AND b.COLB=a.COLB) t
SET t.COLC=t.SEQ;
No.5
- 回答日時:
すいません、さっきのSQLちょっと書き間違えてしまいました。
以下のように訂正します。
(誤)
select seq_XX.nextval, VW.XX from (SELECT * FROM TBL order by TBL.ZZZ);
(正)
select seq_XX.nextval, VW.XX from (SELECT * FROM TBL order by TBL.ZZZ) VW;
ご回答ありがとうございます!
平行してPL/SQLでも試みているのですが、初心者であまりよくわかっていないのですが、以下のような感じでしょうか?
declare
seq_no number := 1;
cursor cur1 is
select colA, colB, colC from tableA
order by colA, colB
begin
for cur_rec in cur1
loop
cur_rec.colC := seq_no;
seq_no := seq_no + 1;
end loop;
end;
/
ただ、実行してみると上手く更新かかりません。
ご教授いただけますでしょうか??
No.4
- 回答日時:
>当初はシーケンスを作成して試みたのですが、並び替えた上で連番をふることができず無作為な連番になってしまいました。
上記文面から推測ですが、この失敗の原因は、
select seq_XX.nextval, TBL.XX from TBL order by TBL.ZZZ;
と書いてしまったためではないでしょうか?
上記の書き方ですと、ZZZの並び順とシーケンスの番号順が無関係になります。
以下のように書けばZZZの順にシーケンス採番することが可能です。
select seq_XX.nextval, VW.XX from (SELECT * FROM TBL order by TBL.ZZZ);
「当初は」のところに立ち戻って上記方法で可能かどうかご確認ください。
どうしてもUPDATEでやりたいならば、単文のUPDATE文だとシーケンスで連番振るのはちょっと無理なような気がしますので、PL/SQLで処理を組むことをオススメします。
カーソルで並び替えながらSELECTして、一行づつシーケンス番号でUPDATEする要領です。あまり複雑な単文をヒネリ出すよりも、このほうが読みやすく実装もカンタンです。
No.3
- 回答日時:
そもそもROWNUMは、抽出後並び替え前のレコード番号ですから、
SELECT COLA,COLB,ROWNUM FROM TABLEA ORDER BY COLA,COLB
では想定した連番は返ってきません。
したがって、TABLEAに主キーがあるなら(たとえばCOLA,COLBが主キーなら)、
UPDATE TABLEA a
SET COLC=(SELECT SEQ FROM
(SELECT ROWNUM SEQ,b.* FROM (SELECT * FROM TABLEA ORDER BY COLA,COLB) b)
WHERE COLA=a.COLA AND COLB=a.COLB)
主キーもないようなテーブルなら、#2さんのようにワークテーブルを使いますが、
CREATE TABLE TEMP1 AS SELECT COLA,COLB FROM TABLEA;
TRUNCATE TABLE TABLEA;
INSERT INTO TABLEA SELECT COLA,COLB,ROWNUM FROM (SELECT * FROM TEMP1 ORDER BY COLA,COLB);
CREATE TABLE TEMP1 AS SELECT COLA,COLB FROM TABLEA;
DROP TABLE TABLEA;
CREATE TABLE TABLEA AS SELECT COLA,COLB,ROWNUM AS COLC FROM (SELECT * FROM TEMP1 ORDER BY COLA,COLB);
ご回答ありがとうございます。
ただカラム数が多いせいか、レスポンスが非常に悪いようです。
> (SELECT ROWNUM SEQ,b.* FROM (SELECT * FROM TABLEA ORDER BY COLA,COLB) b)
↑の「b.*」は必要なのでしょうか?
試しに消して見ると、「単一行副問い合わせにより2つ以上の行が戻されます」とエラーになってしまいました。
せめて、カラム指定すると早くなるものでしょうか?
No.2
- 回答日時:
思い付きですが、、、
手元にオラクルが無いので試せませんので保証はできませんが、
一旦テンポラリテーブル作るというのはどうですか?
create table temp1 as select colA, colB from tableA;
drop table tableA;
create table tableA as select colA, colB, rownum "colC" from temp1 order by colA, colB;
ご回答ありがとうございます!
試してみましたがCreate table時にはorder byは指定できないようですね。。
他に思いつきで、、、
update (select colC from tableA order by colA, colB) wk
set wk.colC = rownum;
「このビューではデータ操作が無効です」が出てきます。
他に何かありませんでしょうか?
よろしくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle SQL update方法 2 2022/06/22 14:07
- MySQL SQL任意に並び替えをしたい 2 2023/08/28 10:47
- Excel(エクセル) 【エクセル】並び替えからの並び替え方法 7 2022/07/22 09:46
- その他(プログラミング・Web制作) google formsを使ったタスク依頼フォーム作成におけるご相談 1 2023/06/22 15:55
- その他(Microsoft Office) 同じ番号に並び替え 1 2022/10/21 22:37
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- Excel(エクセル) Excelで漢字人名が勝手に並び変わる 2 2023/01/14 22:14
- Excel(エクセル) 棚卸表の前月比の関数等あれば教えてください 2 2023/05/02 18:34
- その他(開発・運用・管理) 複数ファイル名の一括変更について 3 2023/04/27 13:08
- PHP php my adminより取り出したデータ表示 2 2022/06/15 11:56
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Texの枠囲み調節
-
PL/SQL カーソルのFROM句にカー...
-
PL/SQLカーソルの2重FORループ...
-
【PL/SQL】CURSOR ・・・ IS SE...
-
文字列の置換
-
PL/SQLでのSQL文法
-
PL/SQLにて、マスタから取得し...
-
Accessのマクロでモジュールを...
-
Statement ignored というエラー
-
sqlplusでヘッダーが付かない
-
今日の日付が入った行のデータ...
-
callで順に実行されるプロシー...
-
14桁の日付(YYYYMMDDHHMMSS)を...
-
ODBCリンクの際にACCESSでは読...
-
PL/SQLでSPOOLさせたいのですが...
-
キャッシュを使わずにSELECTを...
-
日付型なら変数の先頭になん...
-
Accessの数値から時間に変換す...
-
SQLserver算術オーバーフロ...
-
エクセルVBAでUserFormを起動し...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PL/SQLカーソルの2重FORループ...
-
PL/SQLでのSQL文法
-
Texの枠囲み調節
-
カーソル定義での条件分岐
-
カーソルで集合関数を使った場...
-
自動連番でカラムを更新したい
-
[Oracle9i]PL/SQLでFETCHしても...
-
ROW_NUMBER BY PL/SQL
-
動的なSQLからカーソルを返す。
-
カーソルフェッチにて、最終レ...
-
PL/SQLのOPEN cursor_name FOR...
-
ループカウンタの値
-
PL/SQL カーソルのFROM句にカー...
-
【PL/SQL】CURSOR ・・・ IS SE...
-
PL/SQLで
-
PL/SQLにて、マスタから取得し...
-
カーソルループ内部でログを出力
-
ACCESS VBAでループ中に制御を...
-
PL/SQL)Functionの引数(文字列...
-
指定した時間を除くためのテー...
おすすめ情報