« 2024年5月 | トップページ | 2024年7月 »

2024年6月29日 (土)

帰ってきた! 標準はあるにはあるが癖の多いSQL #12 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(後編)ー 列エイリアスの扱いにも癖がある!

Previously on Mac De Oracle
前回は、帰ってきた! 標準はあるにはあるが癖の多いSQL #11 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(前編)でした、

引用符にも多少の方言が存在すること、NULLのソート方法にも同様に方言が存在することを確認しました。
今回はその後編です。

引用符で囲んだ識別子(列名、表名、列エイリアス、表エイリアス)を英語だと、Quoted Identifier と記載されシノニムはあまり見かけません。(SQL-1992などでは、delimited identifier と記されている程度ですかね)日本語のマニュアル等では翻訳影響だと思いますが、多少揺れていたりします。

Oraclerのみなさんだと、引用識別子 のほうが馴染み深い日本語訳だと思いますが、他のRDBMSの日本語マニュアルでは、引用符付き識別子 と記載されていたりします。とうのは前回にも書いてますが、Oracle Database/PostgreSQL/MySQLの間でも多少表現は違ったりします。

参考)
Database Oracle / Release 19 / SQL言語リファレンス / データベース・オブジェクト名および修飾子 / データベース・オブジェクトのネーミング規則
MySQL 8.0 リファレンスマニュアル / 言語構造 / スキーマオブジェクト名
PostgreSQL 13.1文書 / 第4章 SQLの構文 / 4.1. 字句の構造


という前置きはこれぐらいで。本日のお題。列エイリアスの扱いの癖!

今日のお題は、列エイリアスの扱いの癖 を見てみます(気づかないと意外にハマりますよーーw)

今回も前回同様、お馴染みの、emp表を、Oracle Database 23ai/PostgreSQL 13.14/MySQL 8.0.36 それぞれに作成してあります。(以下はOracle Database)

SCOTT@localhost:1521/freepdb1> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)

SCOTT@localhost:1521/freepdb1> select * from emp order by empno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500 30
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850 30
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14 rows selected.


では、前回のおさらいから、MySQLだけ癖が強い結果となりましたが、問い合わせたい結果はどれも正しいですよね!(標準はあるにはあるが、癖の多いSQLらしい。素晴らしい結果ですよねw)

Oracle Database 23ai

SCOTT@localhost:1521/freepdb1> set null [null]
SCOTT@localhost:1521/freepdb1> @quoted_identification.sql
1 SELECT
2 mgr AS "Boss's emp no."
3 , COUNT(empno) AS head_counts
4 FROM
5 emp
6 GROUP BY
7 "Boss's emp no."
8 ORDER BY
9* "Boss's emp no." NULLS FIRST

Boss's emp no. HEAD_COUNTS
-------------- -----------
[null] 1
7566 2
7698 5
7782 1
7788 1
7839 3
7902 1

7 rows selected.

PostgreSQL 13.14

perftestdb=> \pset null [null]
Null表示は"[null]"です。
perftestdb=> \! cat quoted_identification.sql
SELECT
mgr AS "Boss's emp no."
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"Boss's emp no."
ORDER BY
"Boss's emp no." NULLS FIRST
;
perftestdb=> \i quoted_identification.sql
Boss's emp no. | head_counts
----------------+-------------
[null] | 1
7566 | 2
7698 | 5
7782 | 1
7788 | 1
7839 | 3
7902 | 1
(7 行)


MySQL 8.0.36

mysql> \! cat quoted_identification.sql
SELECT
mgr AS `Boss's emp no.`
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
`Boss's emp no.`
ORDER BY
`Boss's emp no.` IS NULL DESC
,`Boss's emp no.` ASC
;
mysql>
mysql> \. quoted_identification.sql
+----------------+-------------+
| Boss's emp no. | head_counts |
+----------------+-------------+
| NULL | 1 |
| 7566 | 2 |
| 7698 | 5 |
| 7782 | 1 |
| 7788 | 1 |
| 7839 | 3 |
| 7902 | 1 |
+----------------+-------------+
7 rows in set (0.01 sec)


今日は、上記のクエリー列エイリアスにちょっと意地の悪い変更を行なって、その挙動の違いを見てみたいと思います。(おもしろいよ、それぞれの個性が出てて)
オリジナルでは、mgr AS "Boss's emp no." としていた列エイリアスですが、まずは、 mgr AS empno と、非識別引用子にして、かつ、emp表の列名である empno と同じ名称にしてあります。。。 AS 列エイリアス にはなっているので文法的には正しいです。。。よね。ちょっと嫌な予感はしますがw

(MySQLの場合、ORDER BY句の構文が異なります。以下、Oracle Database 23ai/PostgreSQL向け)

Before

SELECT
mgr AS Boss's emp no."
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"Boss's emp no."
ORDER BY
"Boss's emp no." NULLS FIRST;


After

SELECT
mgr AS empno
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
empno
ORDER BY
empno NULLS FIRST;

では、早速、MySQLから実験してみましょう!

mysql> desc emp;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| empno | smallint | NO | PRI | NULL | |
| ename | varchar(10) | YES | | NULL | |
| job | varchar(10) | YES | | NULL | |
| mgr | smallint | YES | | NULL | |
| hiredate | date | YES | | NULL | |
| sal | decimal(7,2) | YES | | NULL | |
| comm | decimal(7,2) | YES | | NULL | |
| deptno | smallint | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.05 sec)

mysql> \! cat quoted_identification2.sql
SELECT
mgr AS empno
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
empno
ORDER BY
empno IS NULL DESC
,empno ASC
;


おおおおおおおおおーーーーーーー。想定外の結果がががががー(いや、予想してましたよw)。

mysql> \. quoted_identification2.sql
+-------+-------------+
| empno | head_counts |
+-------+-------------+
| NULL | 1 |
| 7566 | 1 |
| 7566 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7782 | 1 |
| 7788 | 1 |
| 7839 | 1 |
| 7839 | 1 |
| 7839 | 1 |
| 7902 | 1 |
+-------+-------------+
14 rows in set, 1 warning (0.02 sec)


ワーニングがでてますね。覗いてみると、どうやら、empno が曖昧だけど、実行しておいたから。。。。と。emp表のempnoと mgr列に対する列エイリアス、どちらか曖昧だけど、とりあえず、emp表のempno列の方でやっといたでーーー。ということみたいですね。まじか。。。 AS 列エイリアス とSQLで書いてるから列エイリアスとしてみてくれんの???(ちょっとわざとらしいセリフを入れてみましたw)

mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1052 | Column 'empno' in group statement is ambiguous |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)


そうか、列エイリアスと表の列名が被ってて、曖昧だと。 では、 引用符を使って、これは、列エイリアスだーーーーーーとわかるように書けば良いのでは??  
ということで試してみる。

MySQLのデフォルトの引用符(`)バッククォートで囲った結果。。。だめだ。。。。引用識別子にしても、表の列側としてハンドリングされている。。。。。

mysql> \! cat quoted_identification2.sql
SELECT
mgr AS `empno`
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
`empno`
ORDER BY
`empno` IS NULL DESC
,`empno` ASC
;
mysql> \. quoted_identification2.sql
+-------+-------------+
| empno | head_counts |
+-------+-------------+
| NULL | 1 |
| 7566 | 1 |
| 7566 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7698 | 1 |
| 7782 | 1 |
| 7788 | 1 |
| 7839 | 1 |
| 7839 | 1 |
| 7839 | 1 |
| 7902 | 1 |
+-------+-------------+
14 rows in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1052 | Column 'empno' in group statement is ambiguous |
+---------+------+------------------------------------------------+
1 row in set (0.00 sec)

mysql>


気を取り直して、PostgreSQL ではどうなのでしょう?

perftestdb=> \d+ emp
テーブル"public.emp"
列 | タイプ | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 統計目標 | 説明
----------+-----------------------+----------+---------------+------------+------------+----------+------
empno | numeric(4,0) | | not null | | main | |
ename | character varying(10) | | | | extended | |
job | character varying(9) | | | | extended | |
mgr | numeric(4,0) | | | | main | |
hiredate | date | | | | plain | |
sal | numeric(7,2) | | | | main | |
comm | numeric(7,2) | | | | main | |
deptno | numeric(2,0) | | | | main | |
インデックス:
"pk_emp" PRIMARY KEY, btree (empno)
"ix_deptno" btree (deptno)
外部キー制約:
"fk_deptno" FOREIGN KEY (deptno) REFERENCES dept(deptno)
アクセスメソッド: heap

perftestdb=> \! cat quoted_identification.sql
SELECT
mgr AS empno
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
empno
ORDER BY
empno NULLS FIRST
;

ギョギョ! サカナくんみたいな声がでますね!w MySQLと同じ挙動です!!!! なーーーーーーーんーーーーーーだってーーーーーーーっ。 MySQLとは異なりワーニングもなく、結果が想定結果を違うんだーー。というところから列エイリアスが列エイリアスと認識されていないことに気づいてあげないとならないですね。。。これだと。 難易度が上がったw
MySQL、意外と親切かも。ワーニングで教えてくれるなんて。。。

perftestdb=> \pset null [null]
Null表示は"[null]"です。
perftestdb=> \i quoted_identification.sql
empno | head_counts
--------+-------------
[null] | 1
7566 | 1
7566 | 1
7698 | 1
7698 | 1
7698 | 1
7698 | 1
7698 | 1
7782 | 1
7788 | 1
7839 | 1
7839 | 1
7839 | 1
7902 | 1
(14 行)

では、引用識別子に書き換えてみましょう。。。。。あ、まじで、PostgreSQLもMySQLと同じ挙動ですね。 列エイリアスだよーーーーーと明示しても、表の列としてのハンドリングを優先しています。。。むむむ。

perftestdb=> \pset null [null]
Null表示は"[null]"です。
perftestdb=> \! cat quoted_identification2.sql
SELECT
mgr AS "empno"
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"empno"
ORDER BY
"empno" NULLS FIRST
;
perftestdb=> \i quoted_identification2.sql
empno | head_counts
--------+-------------
[null] | 1
7566 | 1
7566 | 1
7698 | 1
7698 | 1
7698 | 1
7698 | 1
7698 | 1
7782 | 1
7788 | 1
7839 | 1
7839 | 1
7839 | 1
7902 | 1
(14 行)

perftestdb=>


では、ここまでくると、わかりますよね。 前回のエントリーで、MySQL の立ち位置にいるのは、Oracle Database 23ai でーーーす。
なお、23aiからGROUP BYに列エイリアスが書けるようになってます。

結果を見てみましょうw

おおおおおーーーーーー。まじでーーーー。
MySQL/PostgreSQLと異なる挙動。列エイリアス(非引用識別子)と表の列名が被ってる影響で列エイリアスがエイリアスとして認識されていないためエラーとして扱っていますね。興味深い。いや、実はミスに気づきやすいのかも。。。

SCOTT@localhost:1521/freepdb1> set null [null]
SCOTT@localhost:1521/freepdb1> edit quoted_identification.sql

SCOTT@localhost:1521/freepdb1> @quoted_identification.sql
1 SELECT
2 mgr AS empno
3 , COUNT(empno) AS head_counts
4 FROM
5 emp
6 GROUP BY
7 empno
8 ORDER BY
9* empno NULLS FIRST
mgr AS empno
*
ERROR at line 2:
ORA-00979: "MGR": must appear in the GROUP BY clause or be used in an aggregate function
Help: https://docs.oracle.com/error-help/db/ora-00979/


非識別引用子のままだと、表の列名である、empno と区別できない(AS empno と記載しても)ので、引用識別子にしてみます。PostgreSQL/Oracle Databaseの引用符は(")ダブルクォートですよね。

実行してみると。。。。。。あーーーーら不思議、MySQL/PostgreSQLとは異なり、引用識別子にしてあげることで、emp表のempno列とはことなる、列エイリアスと認識して、正しく処理しています。。。なんと。。。というか、この実装のほうが引用識別子の意味としては理解しやすくないですかね。。どうなんだろう。

SCOTT@localhost:1521/freepdb1> !cp quoted_identification.sql quoted_identification2.sql

SCOTT@localhost:1521/freepdb1> edit quoted_identification2.sql

SCOTT@localhost:1521/freepdb1> @quoted_identification2.sql
1 SELECT
2 mgr AS "empno"
3 , COUNT(empno) AS head_counts
4 FROM
5 emp
6 GROUP BY
7 "empno"
8 ORDER BY
9* "empno" NULLS FIRST

empno HEAD_COUNTS
---------- -----------
[null] 1
7566 2
7698 5
7782 1
7788 1
7839 3
7902 1

7 rows selected.

Elapsed: 00:00:00.01
SCOTT@localhost:1521/freepdb1> set linesize 80
SCOTT@localhost:1521/freepdb1> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)

SCOTT@localhost:1521/freepdb1>


引用識別子/非引用識別子が既存の列名と同じ場合の評価の仕方は皆バラバラですねw。思いっきり実装依存の部分なので、列、表名に対するエイリアスを指定する場合には注意しましょう。
(個人的な感覚でしかないですがw

Oracle Databaseの実装のほうが直感的には理解しやすいきがします)

MySQLの場合、PostgreSQL同様に実行されますが、面白い特徴は、ワーニングという形で、"Warning 1052 | Column 'empno' in group statement is ambiguous" を示してくれることですね。MySQLでは warningのカウントに注意!!! 忘れないようにしたいですね。重要なコメントが書かれてたりしますw

この3者の中で、もっとも問題に気づきにくいのは、PostgreSQLでしょうか。。。
挙動がMySQL側に似ているので、MySQLのようにちょっと曖昧だけど、実行だけしておいたよ! 的なワーニングでも返してくれると、
MySQLのように気づきやすくなるかもしれませんね。> 各位


これだから、癖のあるSQLとの付き合いはやめられないwww


Enjoy SQL! そして、癖! もw

ではまた。





関連エントリー
標準はあるにはあるが癖の多いSQL 全部俺 #1 Pagination
標準はあるにはあるが癖の多いSQL 全部俺 #2 関数名は同じでも引数が逆の罠!
標準はあるにはあるが癖の多いSQL 全部俺 #3 データ型確認したい時あるんです
標準はあるにはあるが癖の多いSQL 全部俺 #4 リテラル値での除算の内部精度も違うのよ!
標準はあるにはあるが癖の多いSQL 全部俺 #5 和暦変換機能ある方が少数派
標準はあるにはあるが癖の多いSQL 全部俺 #6 時間厳守!
標準はあるにはあるが癖の多いSQL 全部俺 #7 期間リテラル!
標準はあるにはあるが癖の多いSQL 全部俺 #8 翌月末日って何日?
標準はあるにはあるが癖の多いSQL 全部俺 #9 部分文字列の扱いでも癖が出る><
標準はあるにはあるが癖の多いSQL 全部俺 #10 文字列連結の罠(有名なやつ)
標準はあるにはあるが癖の多いSQL 全部俺 #11 デュエル、じゃなくて、デュアル
標準はあるにはあるが癖の多いSQL 全部俺 #12 文字[列]探すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #13 あると便利ですが意外となかったり
標準はあるにはあるが癖の多いSQL 全部俺 #14 連番の集合を返すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #15 SQL command line client
標準はあるにはあるが癖の多いSQL 全部俺 #16 SQLのレントゲンを撮る方法
標準はあるにはあるが癖の多いSQL 全部俺 #17 その空白は許されないのか?
標準はあるにはあるが癖の多いSQL 全部俺 #18 (+)の外部結合は方言
標準はあるにはあるが癖の多いSQL 全部俺 #19 帰ってきた、部分文字列の扱いでも癖w
標準はあるにはあるが癖の多いSQL 全部俺 #20 結果セットを単一列に連結するにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #21 演算結果にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #22 集合演算にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #23 複数行INSERTにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #24 乱数作るにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #25 SQL de Fractalsにも癖がある:)
標準はあるにはあるが癖の多いSQL 全部俺 おまけ SQL de 湯婆婆やるにも癖がでるw
帰ってきた! 標準はあるにはあるが癖の多いSQL #1 SQL de ROT13 やるにも癖が出るw
帰ってきた! 標準はあるにはあるが癖の多いSQL #2 Actual Plan取得中のキャンセルでも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #3 オプティマイザの結合順評価テーブル数上限にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #4 Optimizer Traceの取得でも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #5 - Optimizer Hint でも癖が多い
帰ってきた! 標準はあるにはあるが癖の多いSQL #6 - Hash Joinの結合ツリーにも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #7 - Hash Joinの実行計画にも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #8 - Hash Joinさせるにも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #9、BOOLEAN型にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)の おまけ - SQL*PlusのautotraceでSQL Analysis Reportが出力される! (23ai〜)
帰ってきた! 標準はあるにはあるが癖の多いSQL #11 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(前編)

| | | コメント (0)

2024年6月23日 (日)

VirtualBox TestBuild 7.0.97r163606 (2024-06-21T11:55:16Z) for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録

2024-06-21に最新のTestBuildが公開されていました。


20240623-112941

恒例のOracle Database 21c on VirtualBox TestBuild for macOS/ARM64 の起動時間の記録です。

 

oracle@Mac-Studio ~ % ./print_env.sh

*** mac info. ***
ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

*** maxOS ver. ***
Model Name: Mac Studio
Chip: Apple M1 Ultra
Total Number of Cores: 20 (16 performance and 4 efficiency)
Memory: 64 GB

*** VirtualBox ver. ***
7.0.97r163606

 

M1で停止時間が2桁秒台になったほか、起動時間も改善してますね!

起動1回目 : 130 sec
停止1回目 : 66 sec
起動2回目 : 145 sec
停止2回目 : 45 sec

 

 

oracle@angelfish ~ % ./print_env.sh

*** mac info. ***
Model Name: MacBook Air
Chip: Apple M2
Total Number of Cores: 8 (4 performance and 4 efficiency)
Memory: 24 GB

*** macOS ver. ***
ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

*** VirtualBox ver. ***
7.0.97r163606

 

 

起動停止時間の記録をとり始めてから、M2でも最短記録ですね!!!! 

起動1回目 : 108 sec
停止1回目 : 34 sec
起動2回目 : 91 sec
停止2回目 : 49 sec

 

今回は、起動停止時間ともこれまでの最速値です。(^^) (^^) (^^)

次回のリリースが楽しみですね。。。

 

VMのOSバージョンなどは過去のエントリーを見ていただくとして、M1/M2 それぞれ以下のPostgreSQL/MySQL/Oracle Databaseが起動することを確認。

 

PostgreSQL

[master@localhost ~]$ sudo su - postgres -c 'psql -d perftestdb -U discus -p 5432 -W -h localhost -c "select version()"'

version
----------------------------------------------------------------------------------------------------------
PostgreSQL 13.14 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-20), 64-bit
(1 行)

 

MySQL

[master@localhost ~]$ mysql -u scott -D perftestdb -p -h localhost -e 'select version();'

+-----------+
| version() |
+-----------+
| 8.0.36 |
+-----------+

 

Oracle Database 21c

[oracle@localhost ~]$ sqlplus / as sysdba @version

...略...

BANNER_FULL
----------------------------------------------------------------------
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0

 

Oracle Database 23ai

[oracle@localhost ~]$ sql hr/oracle@localhost:1521/freepdb1 @version

...略...

BANNER_FULL
________________________________________________________________________________
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05

 

VirtualBox Team がんばれ〜〜〜〜〜 :)

では、次回の起動停止時間ログをお楽しみに:)

 

 



MySQL 8.0.32 , PostgreSQL 13.4 and Oracle Database 21c on Oracle Linux 8 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r160702
ySQL 8.0.32 , PostgreSQL 13.6 and Oracle Database 21c on Oracle Linux 8.5 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r161342
MySQL 8.0.32 , PostgreSQL 13.6 and Oracle Database 21c on Oracle Linux 8.5 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r161709
MySQL 8.0.36 , PostgreSQL 13.14, Oracle Database 21c, Oracle Database 23ai on VirtualBox for Apple Silicon Test Build 7.0.97_BETA r162957
VirtualBox TestBuild for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録 / 7.0.97r162957(2024/4/26) / 7.0.97r163029(2024/5/3)
VirtualBox TestBuild 7.0.97r163376 (2024-05-28T15:08:56Z) for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録
VirtualBox TestBuild 7.0.97r163425 (2024-06-05T13:13:46Z) for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録

 

 

| | | コメント (0)

2024年6月22日 (土)

帰ってきた! 標準はあるにはあるが癖の多いSQL #11 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(前編)

Oracle ACE Program的に新年度に切り替わり。今期もOracle ACE Proに認定されました。:)

前置きはそれぐらいにして、今日の本題。

column expressionのaliasや、 table, view, subqueryなどのaliasを指定する際に利用することがある引用符、通常は (")ダブルクォートで囲むわけですが、そんな引用符にも癖があるというお話。
SQL-1992のドラフトではありますが以下のドキュメントを delimited identifier で検索すると見つけることができます。
( (Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992 )

ついでに、世間ではいろいろ言われて肩身の狭い?想いをしているかもしれない NULL. そのNULLのソートが必要になってしまった場合にも、ソートの構文に癖がある!!

ほんと、みんな、癖多すぎますよね!(w
いい感じに差し支えない単語にすると、個性 があるというか... これだからSQLは楽しいって話もありますけども。人によるかなw


Oracle Database 23ai / PostgreSQL 13.14 / MySQL 8.0.36 のそれぞれで、どうなるか見てみましょう。

それぞれのデータベースに以下のような emp表を事前に作成しておきます。Oraclerにはお馴染みの表です:)

SCOTT@localhost:1521/freepdb1> select * from emp order by empno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
7521 WARD SALESMAN 7698 81-02-22 1250 500 30
7566 JONES MANAGER 7839 81-04-02 2975 20
7654 MARTIN SALESMAN 7698 81-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 81-05-01 2850 30
7782 CLARK MANAGER 7839 81-06-09 2450 10
7788 SCOTT ANALYST 7566 87-04-19 3000 20
7839 KING PRESIDENT 81-11-17 5000 10
7844 TURNER SALESMAN 7698 81-09-08 1500 0 30
7876 ADAMS CLERK 7788 87-05-23 1100 20
7900 JAMES CLERK 7698 81-12-03 950 30
7902 FORD ANALYST 7566 81-12-03 3000 20
7934 MILLER CLERK 7782 82-01-23 1300 10

14 rows selected.

まず、Oracle Database 23ai
なぜ最新にしたかと言うと、GROUP BYで alias が利用可能になった最初のリリースだからなのですw (例で利用するクエリで利用する必要があるので)
GROUP BY列の別名または位置の指定が可能に! / 23ai〜 / SQL / FAQ

SCOTT@localhost:1521/freepdb1> select banner_full from v$version;

BANNER_FULL
-------------------------------------------------------------------------------
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05


この例では、別名に空白などを含めているため引用符が必要になります。
Oracle Databaseの場合は昔から (") ダブルクォートですね。
一般的には引用符を必要としない記述にすることが多いのではないでしょうか。プログラムで扱うには面倒ですからね。(印字するだけの目的なら別ですが)
とはいえ、引用符の利用が必須のケースや、コーディング規約次第というところはあります。
SQL言語リファレンス/ データベース・オブジェクト名および修飾子/ データベース・オブジェクトのネーミング規則

NULLの位置が最初に来るようにソートするには、NULLS FIRSTですよね。みなさんもご存知のはず。

Oraclerのみなさんには GROUP BY でいきなりaliasを使う構文で目新しいですよね。すっきり書けるようになって嬉しい:)

SCOTT@localhost:1521/freepdb1> set null [null]
SCOTT@localhost:1521/freepdb1> @quoted_identification.sql
1 SELECT
2 mgr AS "Boss's emp no."
3 , COUNT(empno) AS head_counts
4 FROM
5 emp
6 GROUP BY
7 "Boss's emp no."
8 ORDER BY
9* "Boss's emp no." NULLS FIRST

Boss's emp no. HEAD_COUNTS
-------------- -----------
[null] 1
7566 2
7698 5
7782 1
7788 1
7839 3
7902 1

7 rows selected.


次は、PostgreSQL 
Oracle Database同様、引用符が必要な別名は、ダブルクォートを利用します。( PostgreSQL 16.0 / 4.1.1. 識別子とキーワード )

NULLS FIRSTでNULLをいい感じにソートする方法も同じですね。

perftestdb=> select version();
version
----------------------------------------------------------------------------------------------------------
PostgreSQL 13.14 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-20), 64-bit
(1 行)

perftestdb=>
perftestdb=> \pset null [null]
Null表示は"[null]"です。
perftestdb=> \! cat quoted_identification.sql
SELECT
mgr AS "Boss's emp no."
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"Boss's emp no."
ORDER BY
"Boss's emp no." NULLS FIRST;
;
perftestdb=> \i quoted_identification.sql
Boss's emp no. | head_counts
----------------+-------------
[null] | 1
7566 | 2
7698 | 5
7782 | 1
7788 | 1
7839 | 3
7902 | 1
(7 行)

さて、最後は、MySQLです。

気付いたかと思いますが、本日の癖の主役ですw

MySQLのデフォルトの引用符は、なんと、(`) バッククォートです。手癖で、ダブルクォートをタイプして、え!と一瞬固まる、Oraclerが。。> 俺だよw
( MySQL 8.0 リファレンスマニュアル / 言語構造 / スキーマオブジェクト名 )

また、NULLのソートも可能ですが、見たこともない構文でソートします。私まだよくわかってないですが、これで良いらしい。この癖に慣れる必要もありそう。。

+-----------+
| version() |
+-----------+
| 8.0.36 |
+-----------+
1 row in set (0.00 sec)

mysql> \! cat quoted_identification.sql
SELECT
mgr AS `Boss's emp no.`
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
`Boss's emp no.`
ORDER BY
`Boss's emp no.` IS NULL DESC
,`Boss's emp no.` ASC
;
mysql>
mysql> \. quoted_identification.sql
+----------------+-------------+
| Boss's emp no. | head_counts |
+----------------+-------------+
| NULL | 1 |
| 7566 | 2 |
| 7698 | 5 |
| 7782 | 1 |
| 7788 | 1 |
| 7839 | 3 |
| 7902 | 1 |
+----------------+-------------+
7 rows in set (0.01 sec)

ところで、MySQLでも、(")ダブルクォートを引用符にすることができます。
( MySQL 8.0 リファレンスマニュアル / 5.1.11 サーバー SQL モード / ANSI_QUOTES 参照のこと )

sql_modeに ANSI_QUOTESを設定することで使えるようになります。。。。あ〜っ、スッキリ。NULLのソート構文以外はw

mysql> select @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> set session sql_mode = concat(@@sql_mode,',ANSI_QUOTES');
Query OK, 0 rows affected (0.01 sec)

mysql> select @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------------------+
| ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> \! cat quoted_identification.sql
SELECT
mgr AS "Boss's emp no."
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"Boss's emp no."
ORDER BY
"Boss's emp no." IS NULL DESC
,"Boss's emp no." ASC
;
mysql> \. quoted_identification.sql
+----------------+-------------+
| Boss's emp no. | head_counts |
+----------------+-------------+
| NULL | 1 |
| 7566 | 2 |
| 7698 | 5 |
| 7782 | 1 |
| 7788 | 1 |
| 7839 | 3 |
| 7902 | 1 |
+----------------+-------------+
7 rows in set (0.00 sec)

mysql>


ANSI_QUOTESを無効にすると、GROUP BY で指定した alias 無効となり、デフォルトで有効化されているONLY_FULL_GROUP_BYのため、ERROR 1055 となります。なんとなく理解した!

mysql> select @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------------------+
| ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> set session sql_mode = replace(@@sql_mode,'ANSI_QUOTES,','');
Query OK, 0 rows affected (0.00 sec)

mysql> select @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> \! cat quoted_identification.sql
SELECT
mgr AS "Boss's emp no."
, COUNT(empno) AS head_counts
FROM
emp
GROUP BY
"Boss's emp no."
ORDER BY
"Boss's emp no." IS NULL DESC
,"Boss's emp no." ASC
;
mysql> \. quoted_identification.sql
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'perftestdb.emp.mgr' which is not functionally dependent on columns in GROUP BY clause; this is incompatible
with sql_mode=only_full_group_by


そういえば、
英語だと、大抵は、quoted identifier と書かれていますが、日本語表記だと 引用符付き識別子とか、引用識別子、 各社のドキュメントで微妙に違いがあったりして難しいなぁ。と思ったり。
quoted identifier ってカタカタにしたら長くてタイプするの面倒、結局、Oraclerなので、引用識別子/非引用識別子 で通りしゃったりしますけど。


ではでは。
次回へつづく。






関連エントリー
標準はあるにはあるが癖の多いSQL 全部俺 #1 Pagination
標準はあるにはあるが癖の多いSQL 全部俺 #2 関数名は同じでも引数が逆の罠!
標準はあるにはあるが癖の多いSQL 全部俺 #3 データ型確認したい時あるんです
標準はあるにはあるが癖の多いSQL 全部俺 #4 リテラル値での除算の内部精度も違うのよ!
標準はあるにはあるが癖の多いSQL 全部俺 #5 和暦変換機能ある方が少数派
標準はあるにはあるが癖の多いSQL 全部俺 #6 時間厳守!
標準はあるにはあるが癖の多いSQL 全部俺 #7 期間リテラル!
標準はあるにはあるが癖の多いSQL 全部俺 #8 翌月末日って何日?
標準はあるにはあるが癖の多いSQL 全部俺 #9 部分文字列の扱いでも癖が出る><
標準はあるにはあるが癖の多いSQL 全部俺 #10 文字列連結の罠(有名なやつ)
標準はあるにはあるが癖の多いSQL 全部俺 #11 デュエル、じゃなくて、デュアル
標準はあるにはあるが癖の多いSQL 全部俺 #12 文字[列]探すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #13 あると便利ですが意外となかったり
標準はあるにはあるが癖の多いSQL 全部俺 #14 連番の集合を返すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #15 SQL command line client
標準はあるにはあるが癖の多いSQL 全部俺 #16 SQLのレントゲンを撮る方法
標準はあるにはあるが癖の多いSQL 全部俺 #17 その空白は許されないのか?
標準はあるにはあるが癖の多いSQL 全部俺 #18 (+)の外部結合は方言
標準はあるにはあるが癖の多いSQL 全部俺 #19 帰ってきた、部分文字列の扱いでも癖w
標準はあるにはあるが癖の多いSQL 全部俺 #20 結果セットを単一列に連結するにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #21 演算結果にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #22 集合演算にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #23 複数行INSERTにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #24 乱数作るにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #25 SQL de Fractalsにも癖がある:)
標準はあるにはあるが癖の多いSQL 全部俺 おまけ SQL de 湯婆婆やるにも癖がでるw
帰ってきた! 標準はあるにはあるが癖の多いSQL #1 SQL de ROT13 やるにも癖が出るw
帰ってきた! 標準はあるにはあるが癖の多いSQL #2 Actual Plan取得中のキャンセルでも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #3 オプティマイザの結合順評価テーブル数上限にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #4 Optimizer Traceの取得でも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #5 - Optimizer Hint でも癖が多い
帰ってきた! 標準はあるにはあるが癖の多いSQL #6 - Hash Joinの結合ツリーにも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #7 - Hash Joinの実行計画にも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #8 - Hash Joinさせるにも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #9、BOOLEAN型にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)の おまけ - SQL*PlusのautotraceでSQL Analysis Reportが出力される! (23ai〜)

| | | コメント (0)

2024年6月15日 (土)

VirtualBox TestBuild 7.0.97r163425 (2024-06-05T13:13:46Z) for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録

さて、恒例のOracle Database 21c on VirtualBox TestBuild for macOS/ARM64 の起動時間の記録です。
2024-06-05T13:13:46Zに公開されていた。起動自体は非常に安定してきましたね。細かいところは色々あるようですが、正式リリースが待ち遠しい。

oracle@Mac-Studio ~ % ./print_env.sh 

*** mac info. ***
ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

*** maxOS ver. ***
Model Name: Mac Studio
Chip: Apple M1 Ultra
Total Number of Cores: 20 (16 performance and 4 efficiency)
Memory: 64 GB

*** VirtualBox ver. ***
7.0.97r163425


Oracle Database 21c / Mac Studio M1
微妙な差なので変化なしという感じですね。

起動1回目 : 202 sec
停止1回目 : 86 sec
起動2回目 : 163 sec
停止2回目 : 143 sec


oracle@angelfish ~ % ./print_env.sh

*** mac info. ***
Model Name: MacBook Air
Chip: Apple M2
Total Number of Cores: 8 (4 performance and 4 efficiency)
Memory: 24 GB

*** macOS ver. ***
ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

*** VirtualBox ver. ***
7.0.97r163425


Oracle Database 21c / MacBook Air M2
若干、前回公開されたTestBuildより遅くなってる気がしますよね。(たった二回しか起動停止させてないので、参考記録程度なわけですけども)

起動1回目 : 244 sec
停止1回目 : 136 sec
起動2回目 : 201 sec
停止2回目 : 101 sec


Virtualbox-20240605-7097r163425

その他、いつもの起動確認。
PostgreSQL 13.14 / MySQL 8.0.36 / Oracle Database 21c 及び、 23ai (M1/M2それぞれ起動)
GuestOSのバージョンなどはこれまでと同じなので省略して、それぞれのバージョン確認ログで起動確認。

[master@localhost ~]$ mysql -u scott -D perftestdb -p -h localhost -e 'select version();'
Enter password:
+-----------+
| version() |
+-----------+
| 8.0.36 |
+-----------+

[master@localhost ~]$ sudo su - postgres -c 'psql -d perftestdb -U discus -p 5432 -W -h localhost -c "select version()"'
パスワード:
version
----------------------------------------------------------------------------------------------------------
PostgreSQL 13.14 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-20), 64-bit
(1 行)

[oracle@localhost ~]$ sqlplus scott@orclpdb1 @version

...略...

BANNER_FULL
-----------------------------------------------------------------------
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0


[oracle@localhost ~]$ sql hr@192.168.1.138:1521/freepdb1 @version

...略...

BANNER_FULL
________________________________________________________________________________
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05
[oracle@localhost ~]$ cat version.sql
select banner_full from v$version;
exit


これ、ルーティーンになりそうw

ではまた。




MySQL 8.0.32 , PostgreSQL 13.4 and Oracle Database 21c on Oracle Linux 8 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r160702
ySQL 8.0.32 , PostgreSQL 13.6 and Oracle Database 21c on Oracle Linux 8.5 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r161342
MySQL 8.0.32 , PostgreSQL 13.6 and Oracle Database 21c on Oracle Linux 8.5 on VirtualBox for Apple Silicon Test Build 7.0.97_BETA5r161709
MySQL 8.0.36 , PostgreSQL 13.14, Oracle Database 21c, Oracle Database 23ai on VirtualBox for Apple Silicon Test Build 7.0.97_BETA r162957
VirtualBox TestBuild for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録 / 7.0.97r162957(2024/4/26) / 7.0.97r163029(2024/5/3)
VirtualBox TestBuild 7.0.97r163376 (2024-05-28T15:08:56Z) for macOS/ARM64における現時点でのOracle Database 21cの起動、停止時間の記録


| | | コメント (0)

2024年6月 3日 (月)

DTM / 5月に公開した曲

毎月のルーティーンw

5月に公開したループ一覧
先月は、1つ作ってそのリズムトラックが面白かったのでダブバージョン作って勢いで、マイナーアップデートまでw

まず1曲目

Fallen Leaves Loops Ver.1.2 - Dub version of Sunny Spot Loops / N + 1 Loops

Fallen Leaves Loops のマイナーバージョンアップです。パーカッションなど追加。


Summer Sea Breeze Loops / N + 1 Loops

夏っぽい何かを作ろうと思ってたらこうなってしまったw。この曲のリズムトラック、ベースのループをチョップしまくってますw


Memories - Summer Sea Breeze Loops version / N + 1 Loops

Summer Sea Breeze LoopsMemories Loops Ver. 1.1 をmixしてMemories側に寄せたDub versionってところを狙ったつもりw 
なので、タイトルは、 Memories - Summer Sea Breeze Loops versionに。


Nu Funky Loops in Clouds ( Dance Edittion ) / N + 1 Loops

Summer Sea Breeze LoopsMemories Loops Ver. 1.1 をミックスした Memories - Summer Sea Breeze Loops versionのリズムセクションと、Loops in cloudsCity Lights Loopsの一部を混ぜ込んだ曲ですが、Loops in cloudsに寄せたので、その後継バージョンw
ループの再利用とかガレバンっぽい使い方なのではないかと。。:)


最後は、一つ前の曲のマイナーアップデート
Nu Funky Loops in Clouds ver. 1.1 / N + 1 Loops

Nu Funky Loops in Cloudsのマイナーアップデート、困った時のw VOXとHand Clapトラック追加でw。



上記の曲の親子関係というか繋がりは以下の図の通り。
リズムセクションを流用して、さらにバスドラのトラックを追加したり、一部の効果音だけをパーカッション的に流用追加したり、ガレバンらしい使い方になっているかとw(ガレバンの機能はそれだけではないですけどもね)


20240603-194303


では、また

Enjoy GarageBand and DTM!

| | | コメント (0)