From f93eefc319e043b687bf4c397f265c9c89a95709 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 13 Jan 2024 10:49:09 +0800 Subject: [PATCH] Add blog on Oracle database commands --- .../2020-08-28-oracle-programming/index.md | 397 ++++++++++++++++++ .../sqlplus-html.png | Bin 0 -> 6715 bytes .../index.md} | 0 3 files changed, 397 insertions(+) create mode 100755 docs/blog/2020-08-28-oracle-programming/index.md create mode 100644 docs/blog/2020-08-28-oracle-programming/sqlplus-html.png rename docs/blog/{2020-09-07-mysql-programming.md => 2020-08-29-mysql-programming/index.md} (100%) diff --git a/docs/blog/2020-08-28-oracle-programming/index.md b/docs/blog/2020-08-28-oracle-programming/index.md new file mode 100755 index 00000000..2ece0461 --- /dev/null +++ b/docs/blog/2020-08-28-oracle-programming/index.md @@ -0,0 +1,397 @@ +--- +slug: oracle-programming +title: Programming Oracle Database +authors: jiaqi +tags: [Oracle, Database, JPA] +--- + +[//]: # (Copyright Jiaqi Liu) + +[//]: # (Licensed under the Apache License, Version 2.0 (the "License");) +[//]: # (you may not use this file except in compliance with the License.) +[//]: # (You may obtain a copy of the License at) + +[//]: # ( http://www.apache.org/licenses/LICENSE-2.0) + +[//]: # (Unless required by applicable law or agreed to in writing, software) +[//]: # (distributed under the License is distributed on an "AS IS" BASIS,) +[//]: # (WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.) +[//]: # (See the License for the specific language governing permissions and) +[//]: # (limitations under the License.) + + + +Shell +----- + +### Run Oracle SQL script and Exit Afterwards + +```bash +exit | sqlplus -S $user/$pwd@//$server:$port/$service_name @script.sql +``` + +One example value of `$service_name` could be "ORCL". Note that there is a `@` symble preceding the script +path(`script.sql`) + +### Connecting to Oracle DB Instance From the Command Line + +#### (First Time) Install Oracle Instant Client and sqlplus using Homebrew + +1. Download the two files below from [here](http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html). This + is necessary because of Oracle licenses: + + - `instantclient-basic-macos.x64–.zip` + - `instantclient-sqlplus-macos.x64–.zip` + +2. Run + +```bash +brew tap InstantClientTap/instantclient +brew install instantclient-basic +brew install instantclient-sqlplus +``` + +#### Connect + +```bash +sqlplus ${DBUSER}/${DBUSERPASSWORD}@//${HOST}:${PORT}/${SERVICE_NAME} +``` + +where `SERVICE_NAME` is the same thing as "database name" as in MySQL terminology + +### Shell Commands + +#### Display UTF8 + +Whenever a client program (such as `sqlplus`) connects to the database, it tells the database what characterset it is +using. Some environments may have a very restricted characterset and use something like US7ASCII so they don't get +anything that can upset them. + +As you can see in the following example, what is output by a query is dependent on the NLS_LANG setting of a client. + +```shell +C:\>set NLS_LANG=.US7ASCII +C:\>sqlplus ???/???@xe + +SQL*Plus: Release 10.2.0.1.0 - Production on Wed Nov 3 09:31:32 2010 +> select chr(193) from dual; + +C +- +? + +> quit + +C:\>set NLS_LANG=.AL32UTF8 +C:\>sqlplus ???/???@xe + +SQL*Plus: Release 10.2.0.1.0 - Production on Wed Nov 3 09:31:49 2010 +> select chr(193) from dual; + +C +- +┴ +``` + +If your client is Windows, then try the above. If it is a unix(ish) platform, try + +```bash +export NLS_LANG=.AL32UTF8 +``` + +#### Spool SQL Query Output to HTML format in SQLPLUS Oracle + +In SQLPLUS: + +```sql +set pages 500 +SET MARKUP HTML ON +spool report1.html +Select * from hr.departments where department_id < 20; +spool off +``` + +This would generate a "report1.html" file in the directory where SQLPLUS command was invoked and the file looks like +the following: + +![Error loading sqlplus-html.png](./sqlplus-html.png) + +#### Show Tables + +If you have worked with MySQL, you may be familiar with the `SHOW TABLES` command that lists all tables in a database: + +```sql +SHOW TABLES; +``` + +Unfortunately, Oracle **does not** directly support the `SHOW TABLES` command. However, you can list all tables in a +database by querying from various data dictionary views. + +##### Show Tables Owned By the Current User + +To show tables **owned** by the current user, you query from the `user_tables` view. + +```sql +SELECT table_name +FROM user_tables +ORDER BY table_name; +``` + +Note that this view does not show the `OWNER` column. Also, the user_tables table **does not** contain the other tables +that are **accessible** by the current user. + +##### Show Tables Accessible By the Current User + +To show all tables that are currently **accessible** by the current user, regardless of owners, you query from the +`all_tables` view: + +```sql +SELECT table_name +FROM all_tables +ORDER BY table_name; +``` + +If you want to show all tables of a specific owner, you add the `OWNER` column in the `WHERE` clause as shown in the +following query: + +```sql +SELECT * +FROM all_tables +WHERE OWNER = 'OT' +ORDER BY table_name; +``` + +##### Show All Tables in the Oracle Database + +To show **all tables** in the entire Oracle Database, you query from the `dba_tables` view as follows: + +```sql +SELECT table_name +FROM dba_tables; +``` + +You will get the following error message if you don't have access to the `dba_tables` view: + +```bash +ORA-00942: table or view does not exist +``` + +In this case, you should request your database administrator to grant your account either privileges on the `dba_tables` +view, or `SELECT ANY DICTIONARY` privilege, or `SELECT_CATALOG_ROLE` privilege. + +#### [Comparing Dates](https://stackoverflow.com/a/34061999) + +```sql +Select count(*) From Employee +Where to_char(employee_date_hired, 'YYYMMMDDD') > 19940620 +``` + +or + +```sql +Select count(*) From Employee +employee_date_hired > TO_DATE('20-06-1994', 'DD-MM-YYYY'); +``` + +#### [Show Last Command Run](https://stackoverflow.com/a/51193086) + +The 'l' command will show the last run command + +```sql +SQL> l + 1* select owner, count(1) from dba_tables group by owner +SQL> +``` + +To get more than that, turn on history + +```sql +SQL> set history on +SQL> history + 1 select * from dual; + 2 select sysdate from dual; + 3 show history +``` + +#### [Get A List of All Tables](https://stackoverflow.com/a/205746) + +```sql +SELECT OWNER, TABLE_NAME +FROM DBA_TABLES; +``` + +This is assuming that you have access to the `DBA_TABLES` data dictionary view. If you do not have those privileges but +need them, you can request that the DBA explicitly grants you privileges on that table, or, that the DBA grants you the +`SELECT ANY DICTIONARY` privilege or the `SELECT_CATALOG_ROLE` role (either of which would allow you to query any data +dictionary table). Of course, you may want to exclude certain schemas like `SYS` and `SYSTEM` which have large numbers +of Oracle tables that you probably don't care about. + +Alternatively, if you do not have access to `DBA_TABLES`, you can see all the tables that your account has access to +through the `ALL_TABLES` view: + +```sql +SELECT OWNER, TABLE_NAME +FROM ALL_TABLES; +``` + +Although, that may be a subset of the tables available in the database (`ALL_TABLES` shows you the information for all +the tables that your user has been granted access to). + +If you are only concerned with the tables that you own, not those that you have access to, you could use `USER_TABLES`: + +```sql +SELECT TABLE_NAME +FROM USER_TABLES; +``` + +Since `USER_TABLES` only has information about the tables that you own, it does not have an `OWNER` column - the owner, +by definition, is you. + +Oracle also has a number of legacy data dictionary views -- `TAB`, `DICT`, `TABS`, and `CAT` for example -- that could +be used. In general, I would not suggest using these legacy views unless you absolutely need to backport your scripts to +Oracle 6. Oracle has not changed these views in a long time so they often have problems with newer types of objects. For +example, the `TAB` and `CAT` views both show information about tables that are in the user's recycle bin while the +`[DBA|ALL|USER]_TABLES` views all filter those out. `CAT` also shows information about materialized view logs with a +`TABLE_TYPE` of "TABLE" which is unlikely to be what you really want. `DICT` combines tables and synonyms and doesn't +tell you who owns the object. + +Scripting +--------- + +### WHENEVER SQLERROR + +When you have a script that has syntax errors, the script won't exit with error while executing the line that has the +syntax error. We would like to, instead, halt the execution at that point for the script tuning purposes. To do that +`WHENEVER SQLERROR` could be used. + +The commands in the following script cause SQL*Plus to exit and return the SQL error code if the SQL UPDATE command +fails: + +```sql +WHENEVER SQLERROR EXIT SQL.SQLCODE +UPDATE EMP_DETAILS_VIEW SET SALARY = SALARY*1.1; +``` + +### Drop All User Tables + +```sql +BEGIN + FOR cur_rec IN (SELECT object_name, object_type + FROM user_objects + WHERE object_type IN + ('TABLE', + 'VIEW', + 'MATERIALIZED VIEW', + 'PACKAGE', + 'PROCEDURE', + 'FUNCTION', + 'SEQUENCE', + 'SYNONYM', + 'PACKAGE BODY' + )) + LOOP + BEGIN + IF cur_rec.object_type = 'TABLE' + THEN + EXECUTE IMMEDIATE 'DROP ' + || cur_rec.object_type + || ' "' + || cur_rec.object_name + || '" CASCADE CONSTRAINTS'; + ELSE + EXECUTE IMMEDIATE 'DROP ' + || cur_rec.object_type + || ' "' + || cur_rec.object_name + || '"'; + END IF; + EXCEPTION + WHEN OTHERS + THEN + DBMS_OUTPUT.put_line ('FAILED: DROP ' + || cur_rec.object_type + || ' "' + || cur_rec.object_name + || '"' + ); + END; + END LOOP; + FOR cur_rec IN (SELECT * + FROM all_synonyms + WHERE table_owner IN (SELECT USER FROM dual)) + LOOP + BEGIN + EXECUTE IMMEDIATE 'DROP PUBLIC SYNONYM ' || cur_rec.synonym_name; + END; + END LOOP; +END; +/ +``` + +Troubleshooting +--------------- + +### Double Quotes v.s. Single Quotes + +Unlike MySQL which makes double and single quotes interchangeable. + +### Oracle: ORA-00955: name is already used by an existing object + +#### Cause 1 + +You probably have another object with the same name, for example, 'person' + +You can find it by quering `person`: + +```sql +SELECT * FROM user_objects WHERE object_name = 'person'; +``` + +Then drop it (replace `TYPE_OF_OBJECT` by the type of the object from the above query): + +```sql +DROP TYPE_OF_OBJECT person +``` + +#### Cause 2 + +You simply have a stupid `/` at the end of your statement, such as + +```sql +CREATE TABLE some_schema.person ( + ... +); +/ +``` + +Note the `/` at the end of the query statement + +### ORA-02261: such unique or primary key already exists in the table + +You simply have a stupid `/` at the end of your statement, such as + +```sql +CREATE TABLE BRANCH( +BRA_CODE NUMBER NOT NULL PRIMARY KEY, +BRA_NAME VARCHAR(15), +BRA_ADDR VARCHAR(30), + CITY_ID NUMBER); + +ALTER TABLE BRANCH ADD CONSTRAINT UNIQUE_BRANCH_NAME UNIQUE (BRA_NAME); +\ +``` + +Note the `/` at the end of the query statement + +### Change varchar Column to CLOB + +Given that the operation of moving from a varchar column to a CLOB is disallowed, the most straightforward way would be +to create a new column and move the data from the old column to the new column: + +```sql +ALTER TABLE atable ADD (tmpdetails CLOB); +UPDATE atable SET tmpdetails=details; +COMMIT; +ALTER TABLE atable DROP COLUMN details; +ALTER TABLE atable RENAME COLUMN tmpdetails TO details; +``` diff --git a/docs/blog/2020-08-28-oracle-programming/sqlplus-html.png b/docs/blog/2020-08-28-oracle-programming/sqlplus-html.png new file mode 100644 index 0000000000000000000000000000000000000000..5f2caef4eaf9644bd18294925ded269dacd1635b GIT binary patch literal 6715 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 ZLq01r&@^1kY*%RmJWqHZuW}8${U0T|_h0}3 literal 0 HcmV?d00001 diff --git a/docs/blog/2020-09-07-mysql-programming.md b/docs/blog/2020-08-29-mysql-programming/index.md similarity index 100% rename from docs/blog/2020-09-07-mysql-programming.md rename to docs/blog/2020-08-29-mysql-programming/index.md