log

日々の記録と、書くことを楽しむためのブログです

【Django】文字コードエラーでdumpdataに失敗してしまったとき

発生した問題

DjangoでDBのデータをバックアップするために、dumpdataコマンドを利用しました。

> python manage.py dumpdata アプリ名 > ファイル名.json

すると……。

CommandError:Unable to serialize database: 'cp932' codec can't encode character '\u212a' in position 5: iligal multibyte sequence

というエラーメッセージが出てしまいます。
ざっくり言うと「cp932コーデックで\u212aという文字を扱えないからダンプできないよー」と言ってるみたいです。
ちなみに\u212aというのはケルビンみたいです。

文字コードを調べる

とにかく悪さをしているのは文字コードか、と思いました。
実行した環境のサーバはwindows Serverなので、デフォルトでcp932でプログラムを実行している可能性があるな、と踏みます。

なので、サーバの文字コードを調べます。
コマンドプロンプトで以下のコマンドを実行します。

> chcp

すると、「932」と出てきます。思った通り、cp932のようです。

UTF8モードで実行する

コマンドを実行するときの文字コードをUTF8にできれば何とかなりそうだなと思い当たります。
調べてみると、pythonをUTF8モードで実行できるオプションがあることを知りました。
PEP 540 – Add a new UTF-8 Mode

これを踏まえ、コマンドを修正して

> python -X utf8 manage.py dumpdata アプリ名 > ファイル名.json

としました。
すると、つつがなくダンプが実行されました。
やったね。

まとめ

集中できるテキストエディタを作ろう

自分好みのテキストエディタっぽいものを、JSを使って自分で作ってみます。

作りたいもの

邪魔なメニューが極力表示されてない、エモを邪魔しないテキストエディタを作りたい。
テキストエディタとはいいますが、プログラム向けのあれのことではありません。日本語.txt用です。

今回は最小限の機能にします。

搭載する機能

  • 真ん中に文字を書き込めるスペースがある
  • メニューを開閉できる
  • 文字数を表示(スペースと改行は含めない)
  • フォントを変えられる

完成図

完成図(メニュー閉)
完成図(メニュー開)

コード

出来上がったものがこちらです。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
    <title>t e x t</title>
</head>
<body>
    <!-- メニュー -->
    <div id="menu">
        <nav>
            <div class="inner">
                <div id="settings">
                    <span>
                        <label>Font:</label>
                        <select id="font-select">
                            <option value="font-noto-sans" selected>Noto Sans JP</option>
                            <option value="font-zen-maru">Zen Maru Gothic</option>
                            <option value="font-shipori">Shippori Mincho</option>
                            <option value="font-klee-one">Klee One</option>
                            <option value="font-sawarabi-gothic">Sawarabi Gothic</option>
                            <option value="font-hina-mincho">Hina Mincho</option>
                            <option value="font-kiwi-maru">Kiwi Maru</option>
                            <option value="font-noto-serif">Noto Serif JP</option>
                            <option value="font-zen-old-mincho">Zen Old Mincho</option>
                        </select>
                    </span>
                </div>
            </div>
        </nav>

        <div class="menu_btn" onclick="open_menu()">
            <span></span>
            <span></span>
            <span></span>
        </div>

    </div>

    <!-- 書き込みスペース -->
    <main id="writing_space">
        <textarea id="textarea" oninput="count()" class="font-noto-sans" wrap="soft"></textarea>
        <p id="counter">0</p>
    </main>
    <script src="index.js"></script>
</body>
</html>

解説

  • .menu_btnの中にspanが並んでいるのは、そのエリアを黒塗りしてハンバーガーメニューの三本線を作るためです
  • #textareaにoninput属性があります。これは入力されるごとにcount()イベントが発動するという意味です。文字数カウントに使います。

CSS

@import url('https://fonts.googleapis.com/css2?family=Hina+Mincho&family=Kiwi+Maru&family=Klee+One&family=Noto+Sans+JP&family=Noto+Serif+JP&family=Sawarabi+Gothic&family=Shippori+Mincho&family=Zen+Maru+Gothic&family=Zen+Old+Mincho&display=swap');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
  font-family: 'Noto Sans JP', sans-serif;
  color: #333;
}

/* テキストエリア */
#writing_space{
  display: grid;
  grid-template-rows: 1fr;
  grid-template-columns: 1fr;
  place-items: center;
  margin: 10rem 5rem 5rem 5rem;
}

#writing_space textarea{
  resize: none;
  padding: 10px;
  height: 600px;
  width: 900px;
  border-color: rgb(221, 221, 221);
  border-radius: 6px;
}
textarea:focus{
  outline: none;
}

/* 文字数カウンター */
#counter{
  color: rgb(156, 156, 156);
  font-size: small;
}

/* メニュー */
nav{
  display: block;
  position: fixed;
  background-color: rgb(221, 221, 221);
  top: 0;
  left: -300;
  bottom: 0;
  z-index: 3;
  opacity: 0;
  width: 400px;
}

#menu nav .inner{
  padding: 15px;
}

/* メニューを出す */
.open nav{
  left: 0;
  opacity: 1;
}

/* フォント選択 */
#font-select{
  border-color: rgb(221, 221, 221);
  border-radius: 6px;
}
#font-select:focus{
  outline: none;
}

/* メニューボタン */
.menu_btn{
  display: block;
  position: fixed;
  top: 30px;
  right: 30px;
  width: 30px;
  height: 30px;
  z-index: 3;
  cursor: pointer;
}

/* spanタグで作るハンバーガーメニュー */
.menu_btn span{
  position: absolute;
  display: block;
  left: 0;
  width: 30px;
  height: 3px;
  background-color: #333;
  border-radius: 4px;
}

/* ボタンのデザイン */
.menu_btn span:nth-child(1){
  top: 4px;
}
.menu_btn span:nth-child(2){
  top: 14px;
}
.menu_btn span:nth-child(3){
  bottom: 4px;
}

/* ×ボタン */
.open .menu_btn span:nth-child(1){
  transform: translateY(10px) rotate(-315deg);
}
.open .menu_btn span:nth-child(2){
  opacity: 0;
}
.open .menu_btn span:nth-child(3){
  transform: translateY(-10px) rotate(315deg);
}


/* フォント */
.font-noto-sans{
  font-family: 'Noto Sans JP', sans-serif;
}
.font-zen-maru{
  font-family: 'Zen Maru Gothic', sans-serif;
  font-size: 18px;
  font-weight: 300;
}
.font-shipori{
  font-family: 'Shippori Mincho', serif;
}
.font-klee-one{
  font-family: 'Klee One', cursive;
}
.font-sawarabi-gothic{
  font-family: 'Sawarabi Gothic', sans-serif;
}
.font-hina-mincho{
  font-family: 'Hina Mincho', serif;
}
.font-kiwi-maru{
  font-family: 'Kiwi Maru', serif;
}
.font-noto-serif{
  font-family: 'Noto Serif JP', serif;
}
.font-zen-old-mincho{
  font-family: 'Zen Old Mincho', serif;
}

解説

  • importでグーグルフォントから好みのフォントをインポートします
  • フォントクラスを事前に用意しておき、フォント変更に備えます
  • メニューボタンでメニューを透明→不透明にして表示ができます
    • ※メニュー関係の実装は借りてきたものなので解説は省きます

JS

// 文字数カウント
// 改行とスペースはカウントしない
function count(){
    let text = document.querySelector('#textarea').value;
    text = text.replace(/\n/g, '');
    text = text.replace(/\s/g, '');

    const counter = document.querySelector('#counter');
    counter.innerHTML = text.length
}

// メニュー表示
function open_menu(){
    let nav = document.querySelector('#menu');
    nav.classList.toggle('open');
}

// フォント変更
let font_selecter = document.querySelector('#font-select');
font_selecter.addEventListener('change', (e) => {
    let font_class = e.target.value;

    textarea.classList.remove(...textarea.classList); //テキストエリアのクラスをすべて削除
    textarea.classList.add(font_class);
});

解説

文字数カウント

// 文字数カウント
// 改行とスペースはカウントしない
function count(){
    let text = document.querySelector('#textarea').value;
    text = text.replace(/\n/g, '');
    text = text.replace(/\s/g, '');

    const counter = document.querySelector('#counter');
    counter.innerHTML = text.length
}

この関数はHTMLで指定したとおり、文字を入力するたびに動きます。

let text = document.querySelector('#textarea').value;
text = text.replace(/\n/g, '');
text = text.replace(/\s/g, '');

#textareaの文字を取得し、その中からまず改行と全角スペースを除きます。

  • 「\n」は改行、「\s」は全角スペースを意味します
  • 正規表現のうしろにある「g」はgオプションといいます。これがあることにより、文字列の中のすべての改行とスペースを空白に置き換える(=消す)ことができます。
const counter = document.querySelector('#counter');
counter.innerHTML = text.length

そして、その文字数を.lengthで取得して、文字数を表示する#counterエリアに表示させます


メニュー表示

openクラスを付与することで左側のメニューを可視化します。 toggleなので、クリックするたびにクラスのON/OFFが切り替わります。


フォント変更

#font-selectのセレクトボックスを選択すると関数が動きます。

// フォント変更
let font_selecter = document.querySelector('#font-select');
font_selecter.addEventListener('change', (e) => {
    let font_class = e.target.value;

    textarea.classList.remove(...textarea.classList); //テキストエリアのクラスをすべて削除
    textarea.classList.add(font_class);
});

はじめに、セレクトボックスで選択したもののvalueをとります。これはcssで前もって準備していたフォントクラス名になっています。

let font_class = e.target.value;
<select id="font-select">
    <option value="font-noto-sans" selected>Noto Sans JP</option>
    <option value="font-zen-maru">Zen Maru Gothic</option>
    ...
</select>
.font-noto-sans{
  font-family: 'Noto Sans JP', sans-serif;
}
.font-zen-maru{
  font-family: 'Zen Maru Gothic', sans-serif;
  font-size: 18px;
  font-weight: 300;
}
...

次に、テキストエリアに指定したフォントクラスをつけていくのですが、先に、テキストエリアのclassをすべて削除します。

textarea.classList.remove(...textarea.classList); //テキストエリアのクラスをすべて削除

これにはスプレッド構文を使います。
スプレッド構文

ざっくりいうと、配列などの連なったオブジェクトをいっぺんに順番に処理するときなどに使う構文のようです。
ここでは「textarea.classList」の中身すべてをremoveするということだと思っていただければOKです。

最後に、選択されたフォントクラス名をテキストエリアにくっつけます。

textarea.classList.add(font_class);

これでフォントが変わります。
使う際にはお好みのフォントでお試しください。

おわりに

こんな感じで、最低限書くことができるエディタができました。
F11で全画面にするとかなりいい感じです。

実はこういう風にシンプルな画面のエディタは持ってるのですが、せっかくだから作ってみました。
気分転換にはいいかも。

【HTML】ページの構造を表すタグ早見表

最近のサイトはHTMLの区分けのためになんでもかんでもdivを使わなくなってよくなったんだなぁ……と感心したので、忘れてもいいようにタグと役割をメモしておきます。
「いまさらすぎんだろ」ですが、普段はSEOとか一切関係ないところにいるので……。

ページ構造タグと用途例

ページにひとつだけあればいいタグ

以下のタグは基本的にページ内に1つだけあればいいエリアを示すものになります。

タグ名 意味 用途例
header 上部 ページのヘッダー
footer 下部 ページのフッター
main 主な そのページのメインとなるコンテンツ ※ページ内につき1つが望ましい

mainタグの中にあるのが望ましいタグ

mainの中でコンテンツを表現していくのに使うタグが以下になります。
これらのタグはmain内に複数個あってもかまいません。

タグ名 意味 用途例
article 記事 記事一覧のひとつひとつの塊、ブログ記事本文
section articleの中の文章の章分け

sectionの中に<h1>とか<p>とか使って本文が書かれているといい感じだそうです。

その他のタグ

mainの外でメインコンテンツとは関係のないエリアを表現するのに使います。

タグ名 意味 用途例
nav ナビ ナビゲーションリンクのエリアを示すときに使う
aside 傍ら 本文と関係のないサイドバー(リンクやカテゴリなど)

じゃあdivはお払い箱なのか? と言われるとそうではなくて、本当に上のどれにも当てはまらない最後の手段としてdivが使われるそうです。主にレイアウトの関係でエリアを作りたいときなど。

構造

要するに以下のような構造です。

  • header
  • nav
  • main
    • article
      • section
  • aside
  • footer

使い方

該当するコンテンツを上のタグで包めば完成です。
具体的には下のような感じになればいいようです。

<body>
    <header>
        ヘッダー
    </header>
    <nav>
        <ul>
            <li>このサイトについて</li>
            <li>作品一覧</li>
            <li>お問い合わせ</li>
        </ul>
    </nav>
    <main>
        <article>
            <h1>今日の日記</h1>
            <section>
                <h2>通勤路の誘惑</h2>
                <p>
                    通勤路にそば屋があるんですが、毎朝だしの香りの誘惑がすごいんです。<br />
                    .....
                </p>
            </section>
            <section>
                <h2>サブレもらった</h2>
                <p>
                    仕事中に食べるお菓子っていいですよね。<br />
                    .....
                </p>
            </section>
        </article>
    </main>
    <aside>
        サイドバー
    </aside>
    <footer>
        フッター
    </footer>
</body>

使い分けるための心得

要は、「webページを作るときはコンテンツひとつひとつの役割を明確化し、それを最もよく表しているタグを使おう」ということだと思います。

小説執筆時のテンションづくりについて

わたしは趣味で自分用の小説を書いています。書くことはもちろんですが、方法論を編み出しては試行するのも楽しみの一つで、いろいろこねくり回しています。

今日はそこからひとつ、「自分が小説を書くときのテンションづくり」について記しておきます。
「さぁ、書くぞ!」となったときにまず「書くノリ」をセッティングするための方法です。

うまく書けないときはだいたいこの儀式をやり忘れているので、備忘も兼ねて書いておきます。

これは自己流の方法です。誰しもに当てはまるわけではありません。
しかし、何かをつかむ参考になれば幸いです。

概要

わたしがテンションづくりのためにやっているのは以下の2つです。

  • 目指している文体の小説を読む
  • 焚火の動画を作業用BGMにする

以下で詳しく語っていきます。

目指している文体の小説を読む

まずは自分が好きな、あるいは目指したいと思っている文体の小説を用意します。
それを、声に出して読みます。これだけです。

効果

それによって以下の効果を狙えます。

  • 自分が心地よく思う文体のリズムを体にしみこませる
  • 自分が好きな文体の言葉づかいを体にしみこませる

どれくらいやればいいか

リズムや言葉づかいが体にしみこんで馴染んできたら完了です。一冊最後まで読まなくても大丈夫です。

声に出すなんて……

声に出すなんて恥ずかしいよという人も多いと思います。大きな声で音読しなくても大丈夫です。ぼそぼそ小さな声で読むのでも効果があります。

要は好きな文体を「音」として口先と脳で味わうことができれば効果があるようでした。

心の中で読むのもかまわないとは思いますが、効果を出すにはある程度の集中力が要りました。
必ず文章を「音」として認識しながら注意して読む必要があると思われます。

焚火の動画を作業用BGMにする

文体を体にしみこませたら、あとは書くだけです。私の場合プロットをもとに作った箱書きに合わせて書き始めます。
その時のBGMも、書く時のノリに大いに影響しました。

わたしの場合、焚火の音がベストでした。

パチパチという音が好きな文体の感じと絶妙にマッチしているように感じています。

わたしは英語の小説が日本語に翻訳されたときのあの独特の文体が好きで、そのへんを少し意識して書いているのですが、その文体と火の爆ぜる音がなぜか絶妙にマッチするんですよね。あっちの家にはだいたい暖炉がある(偏見?)からでしょうか?
さまざまな体験が組み合わさってできた個人の「感じ」の話なのできちんと説明できないのですが……。

しかし、バトルシーンやホラーシーンをやる場合はもっと緊迫したBGMをかけることがあります。
でもゆるやかなシーンでは「焚火のテンション」を保つようにしています。

人によっては雨の音や川の音、PCのタイピング音がいいということがあると思います。
「好きな文体と合わせて食うとめっちゃおいしい」食べ合わせを見つけてみましょう。

まとめ

以上がわたしが小説を書くときにテンションづくりのためにしていることです。
こうしてみると「音」に重きを置いているのが分かりました。

自分に合った方法を探して、これからも書くことを楽しんでいきましょう。

【JS】カスタムデータ属性について

カスタムデータ属性とは

HTML5から導入された新たな属性のことです。
htmlのタグにはvalueやidなどの属性がありますが、カスタムデータ属性を使うことでオリジナルの属性を作ることができます。
そして、その属性に文字列を格納することができます。

要素にデータを持つといえばvalueが思いつきますが、valueはすべてのタグで使えるわけではありません。しかし、カスタムデータ属性ならdivなどすべてのHTMLタグが持つことができます。

用途

カスタムデータ属性にはさまざまな使用シーンがあります。

  • jsで要素を取得する目印にしたり、要素にデータを格納したり
  • 中身が動的に変化するデータを扱うのに向いてるかもしれない
  • cssセレクタにすることもできる

カスタムデータ属性のつけかた

タグの中に属性と同じふんいきで「data-データ属性名」と記述すればカスタムデータ属性を設定することができます。

<div class="item" data-flower="tulip">...</div>

「data-flower」がカスタムデータ属性。その中にtulipという文字列データを持たせています。

カスタムデータ属性を使う(JS)

const element = document.querySelector('.item');
const flower = element.dataset.flower;
console.log(flower);
// tulip
  1. カスタムデータ属性を持つ要素を取得
  2. datasetプロパティを使って、データ属性名「flower」のデータを取得する
    • data-flowerをjsで呼ぶときは「flower」でよいのがポイント
  3. 出力すると「tulip」と表示される

datasetプロパティ

カスタムデータ属性をJavascriptで扱うときは、datasetプロパティを使うことになります。
データの取得も格納も、さらにデータ属性の設定もこの属性を使って行います。

データを取得する

datasetを使ってデータを取得するには以下のようにします。

const 変数 = 要素.dataset.データ属性名;

使用例)

const element = document.querySelector('.item');
const flower = element.dataset.flower;

「data-flower」の値が変数flowerに格納されます。


データを格納する

データを属性に格納するには以下のようにします。

要素.dataset.データ属性名 = 値;

使用例)

const element = document.querySelector('.item');
element.dataset.flower = "rose";

itemクラスを持つ要素の「data-flower」に「rose」という文字列が格納されます。
ちなみに、数値を格納したとしても文字列として扱われます。


カスタムデータ属性を設定する

jsからカスタムデータ属性を新たに設定することも可能です。
以下のようにします。

要素.dataset.データ属性名 = 値;

使用例)

<div class="item" data-flower="tulip">...</div>
const element = document.querySelector('.item');
element.dataset.number = 1;
// <div class="item" data-flower="tulip" data-number="1">...</div>

itemクラスを持つ要素にはもともと「data-number」という属性はありません。
しかしelement.dataset.number = 1というコードを書くことで、data-numberという属性が作成されて、指定した値が格納されます。
やり方はデータの格納とまったく同じですね。

カスタムデータ属性を使う(CSS)

CSSセレクタにカスタムデータ属性を使う方法も記しておきます。

[data-flower="tulip"]{
    color: red;
}

以上のcssを当てると、data-flowerがtulipの要素だけ文字色が赤くなります。
クリックイベントなどと組み合わせて動的にスタイルを当てたいときなんかに使えそうですね。

【HTML・CSS】電子書籍風の縦書き小説ページを作る

電子書籍っぽい見た目の小説ページの作り方です。
主にスマホで見られることを想定し、レスポンシブっぽい感じで作ります。

完成品

PC表示

縦書き文章表示(PC)

スマホ表示(シミュレーション)

縦書き文章表示(スマホ

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>タイトル</title>
</head>
<body>
    <div id="text-content">
        <h1 id="text_title">作品タイトル</h1>
        <p>
             テキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
             テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br />
        </p>
    </div>
</body>
</html>

ポイント

  • metaタグでviewportを設定し、レスポンシブに対応します

CSS

*{
    margin: 0;
    padding: 0;
}

body{
    font-family: serif;
    color: #333;
}

/* 表示エリア全体 */
#text-content{
    margin-top: 20px;
    margin-bottom: 20px;
    width: 100%;
    overflow: auto;
    writing-mode: vertical-rl;
    text-orientation: upright;
}

/* 作品タイトル */
#text_title{
    padding-left: 5px;
    font-size:1.6em;
}

/* 本文 */
#text-content p{
    font-size: 1.2em;
    letter-spacing: 0.1em;
    line-height: 1.8em;
}

ポイント

#text-content(テキスト表示エリア全体)

  • width: 100%を設定します。これをしないとスマホ表示の時に下に謎の空白が出来てしまいます
  • writing-mode: vertical-rlを設定し、縦書き表示にします
  • text-orientation: uprightで英数字の向きも縦にします
  • overflow: autoで画面外にはみ出た部分を横スクロールで表示できるようにします

#text-content p(本文)

  • font-sizeをemで指定することにより、文字サイズが画面に合わせた大きさになります。しっくりくる大きさにしてください
  • letter-spacingを指定し、字間を調整します。お好みでどうぞ
  • line-heightを指定し、行間を調整します。こちらもお好みでどうぞ

フォントをGoogleFontsなどのステキなものに変更すると、さらにそれっぽくなります。

ROW_NUMBER() OVER()で重複データの排除

結構おもしろい方法だったので、備忘のため記しておきます。
使用しているDBはOracleです。

前提

たとえば、ITEM_LISTというテーブルからデータを持ってきたいとします。
こんなデータです。

ITEM_CD ITEM_NAME ITEM_CATEGORY CREATE_DATE
01 たぬき どうぶつ 12/12
02 卵焼き 食べ物 10/01
01 たぬき どうぶつ 08/13
03 モルモット どうぶつ 08/13

ITEM_CDとITEM_CATEGORYで、「どうぶつ」カテゴリの「たぬき」が重複しています。
重複データは必要ない。さらにITEM_LISTテーブルにはユニークキーたるIDカラムがないので、IDを振りたい。
そんな用事があるときにROW_NUMBER()とOVER()を使います。

サンプル

SELECT
  ROWNUM ID, -- 行番号はIDと名付ける
  TBL.* -- TBLクエリの全てを取る
FROM
(
    SELECT
        LIST.*, -- LISTテーブルの全データ取得
        ROW_NUMBER() OVER(
            PARTITION BY
                ITEM_CD, --アイテムコード……
                ITEM_CATEGORY -- と、アイテムカテゴリーの重複を許さない
            ORDER BY
                ITEM_CD -- アイテムコード昇順で並べる
        ) RW_NUM
    FROM
        ITEM_LIST LIST
) TBL
WHERE
    TBL.RW_NUM = 1 -- TBLクエリのうち、ROW_NUMBERが1のものだけ抽出。すなわち、重複のうち1番目のものだけ抽出

上のサンプルのOVER()の中では以下のことを指定しています。
ITEM_LISTテーブルを「ITEM_CDとITEM_CATEGORY」の塊で括り、その中でITEM_CDが若い順に並べる。

このルールで作った順位データはRW_NUMと名付けます。
そして、その順位とアイテムデータが組み合わさったサブクエリはTBLと呼びます。

WHERE句にて、重複データを除くためTBLのRW_NUMが1以外のデータはすべて捨てます。
なぜなら2番目以後はすべて重複データだからです。
ORDER BYに入れたいカラムが特にないときはパーティションと同じカラムでも大丈夫です。

最後に、メインとなるクエリでは、TBLクエリのデータを丸ごと取得し、その一行一行にROWNUMを利用してIDを振ります。

結果

先のSQLで取得した結果、このようになるはずです。

ID ITEM_CD ITEM_NAME ITEM_CATEGORY CREATE_DATE
1 01 たぬき どうぶつ 12/12
2 02 卵焼き 食べ物 10/01
3 03 モルモット どうぶつ 08/13

08/13に登録された「たぬき」は重複とみなされて消えています。