Oracle 12c in Solaris 11.3 installieren

Benutzer und Gruppen anlegen

for group in oinstall dba oper backpdba asmdba dgdba kmdba asmadmin asmoper; do 
if grep -q $group /etc/group; 
   then  
      echo "group: $group exist"; 
   else 
      /usr/sbin/groupadd $group; 
fi; 
done

useradd -m -g oinstall -G dba,backpdba,dgdba,kmdba,asmdba,asmoper oracle
useradd -m -g oinstall -G asmadmin,asmdba grid
usermod -R root oracle
passwd oracle
passwd grid
id -a oracle 
id -p oracle

projadd -U oracle -K "project.max-shm-memory=(priv,4g,deny)" user.oracle

su - oracle
prctl -n project.max-shm-memory -i process $$
exit

Packete installieren

for pkg in pkg://solaris/system/dtrace pkg://solaris/developer/assembler pkg://solaris/developer/build/make pkg://solaris/system/xopen/xcu4 pkg://solaris/x11/diagnostic/x11-info-clients pkg://solaris/compress/unzip pkg://x11/library/libxp xauth xclock xterm SUNWgnu-readline SUNWgcc SUNWgccruntime SUNWfont-xorg-core SUNWlibC SUNWcsl gcc; do
     if pkg list $pkg >/dev/null 2>&1;
        then       
             echo "package already installed: $pkg";    
        else      
             echo "Installing: "$pkg;       
             pkg install $pkg >/dev/null 2>&1;
     fi ; 
done

rlwrap
cd /root
wget http://utopia.knoware.nl/~hlub/uck/rlwrap/rlwrap-0.41.tar.gz
tar xvzf rlwrap-0.41.tar.gz
cd /root/rlwrap-0.41
./configure
make
make install

Oracle Clusterware pre script
  mountpoint/grid/rootpre.sh

Oracle_Home, FRA und Source erstellen

if [ ! -e "/u01/app/oracle/product/12.1.0/db_1" ]; 
    then 
    mkdir -p /u01/app/oracle/product/12.1.0/db_1;
fi
if [ ! -e "/osource" ]; 
    then 
    mkdir /osource; 
fi

mount_point ersetzen!

if [ ! -e "/mount_point/fast_recovery_area" ];
    then
    mkdir -p /mount_point/fast_recovery_area;
fi
chown -R oracle:oinstall /u01/app 
chmod -R 775 /u01/app 
chown -R oracle:oinstall /osource 
chmod -R 775 /osource
chown oracle:oinstall /mount_point/fast_recovery_area
chmod 775 /mount_point/fast_recovery_area

Profile fuer Oracle User bearbeiten

cat >> /export/home/oracle/.profile << EOF
 umask 022
 ulimit -s 32768
 ulimit -n 65536
 export ORACLE_BASE=/u01/app/oracle
 export ORACLE_HOME=/u01/app/oracle/product/12.1.0/db_1
 export ORACLE_SID=em13
 export ORACLE_UNQNAME=em13
 export ORACLE_HOSTNAME=`hostname`
 export PATH=\$ORACLE_HOME/bin:$PATH:.
 export TZ=CEST
 alias sql='/usr/local/bin/rlwrap sqlplus'
 alias rman='/usr/local/bin/rlwrap rman'
EOF

Die folgende Schritte sind als oracle anmelden und die Installation´s Files übertragen und entpacken.
Eine ssh Session mit X öffnen (ssh -X oracle@server + xforwording in Putty)
Den Installer (database/runInstaller.sh) starten.

Oder:

Eine ssh Session öffnen
Den Installer (database/runInstaller.sh) -silent -noconfig bzw: Oracle Doc

Notizen zu Oracle Developer Monthly Jan. 2016 – DBMS_ASSERT

Erst mal das danke an Herrn Carsten Czarski für den Vortrag
YouTube

Schutz vor SQL Injection bei dynamischem SQL v1

create or replace procedure get_from_table(
        p_emp_table_name in varchar2
) is
type t_cur is ref cursor;

cur t_cur;
empno_col number;
ename_col varchar2(100);

begin
  open cur for
     'select empno, ename from '||p_emp_table_name;
  loop
      fetch cur into empno_col, ename_col;
      exit when cur%NOTFOUND;
      dbms_output.put_line(lpad(empno_col, 10, ' ') || ' ' ||ename_col);
  end loop;
  close cur;
end;

SQL> exec get_from_table('EMP');

....

Schutz vor SQL Injection bei dynamischem SQL v2

create or replace procedure get_from_table(
        p_emp_table_name in varchar2
) is
type t_cur is ref cursor;

cur t_cur;
empno_col number;
ename_col varchar2(100);

begin
  open cur for
     'select empno, ename from '||dbms_assert.simple_sql_name(p_emp_table_name);
  loop
      fetch cur into empno_col, ename_col;
      exit when cur%NOTFOUND;
      dbms_output.put_line(lpad(empno_col, 10, ' ') || ' ' ||ename_col);
  end loop;
  close cur;
end;

SQL> exec get_from_table('EMP');

....

ENQUOTE_LITERAL: für SQL-Literale (Parameter)

SQL> select dbms_assert.enquote_literal(q'#Meier#') from dual;
DBMS_ASSERT.ENQUOTE_LITERAL(Q'#MEIER#')
--------------------------------------------------------------------------------
'Meier'
SQL> select dbms_assert.enquote_literal(q'#Meier' or 1=1#') from dual;
*
FEHLER in Zeile 1:
ORA-06502: PL/SQL: numerischer oder Wertefehler
ORA-06512: in "SYS.DBMS_ASSERT", Zeile 409
SQL> select dbms_assert.enquote_literal(q'#Meier'' or 1=1#') from dual;
DBMS_ASSERT.ENQUOTE_LITERAL(Q'#MEIER''OR1=1#')
--------------------------------------------------------------------------------
'Meier'' or 1=1

SQL> select dbms_assert.enquote_name(q'#EMP#') from dual; 
DBMS_ASSERT.ENQUOTE_NAME(Q'#EMP#') 
-------------------------------------------------------------------------------- 
"EMP" 
SQL> select dbms_assert.enquote_name(q'#EMP" union all (...)#') from dual; 
* 
FEHLER in Zeile 1: 
ORA-44003: Ungültiger SQL-Name 
ORA-06512: in "SYS.DBMS_ASSERT", Zeile 479 ORA-06512: in Zeile 1

Notizen zu Oracle Developer Monthly Feb. 16 – Datumsverarbeitung in der Oracle-DB

Erst mal das danke an Herrn Carsten Czarski für den Vortrag.
YouTube Link

zum Datentypen

  • DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE

Datumsformate

  • NLS-Formatmasken, NLS-Datumssprache, Datums-Literale

Datumsarithmetik

  • Arbeiten mit Dezimalzahlen oder mit INTERVAL-Datentypen
SQL> select sysdate, dump(sysdate) dmp from dual; 
SYSDATE                      DMP 
--------------------------- ---------------------------------------- 
22.02.2016 09:50:36          Typ=13 Len=8: 224,7,2,22,9,50,36,0 

1 rows selected.             E0,07 -> Hex 07E0 -> 2016
SQL> select systimestamp, dump(systimestamp) dmp from dual;
SYSTIMESTAMP                  DMP
----------------------------- ------------------------------------------------------------------
22.02.16 09:54:35,389132000   Typ=188 Len=20: 224,7,2,22,8,54,35,0,224,174,49,23,0,0,3,0,0,0,0,0
1 rows selected.

Default Datumsformat richtet sich nach NLS-Session Einstellung

SQL> select * from nls_session_parameters; 
PARAMETER                      VALUE 
------------------------------ ------------------------------------ 
NLS_LANGUAGE                   GERMAN 
NLS_TERRITORY                  GERMANY 
NLS_CURRENCY                   Γé¼ 
NLS_ISO_CURRENCY               GERMANY 
NLS_NUMERIC_CHARACTERS         ,. 
NLS_CALENDAR                   GREGORIAN 
NLS_DATE_FORMAT                DD.MM.YYYY 
NLS_DATE_LANGUAGE              GERMAN 
NLS_SORT                       GERMAN 
NLS_TIME_FORMAT                HH24:MI:SSXFF 
NLS_TIMESTAMP_FORMAT           DD.MM.RR HH24:MI:SSXFF 
NLS_TIME_TZ_FORMAT             HH24:MI:SSXFF TZR 
NLS_TIMESTAMP_TZ_FORMAT        DD.MM.RR HH24:MI:SSXFF TZR 
NLS_DUAL_CURRENCY              Γé¼ 
NLS_COMP                       BINARY 
NLS_LENGTH_SEMANTICS           BYTE 
NLS_NCHAR_CONV_EXCP            FALSE

Default-Datumsformate sind abhängig von NLS

Ohne Formatmaske zu arbeiten, ist gefährlich …

SQL> select to_date('22.02.2016') from dual; 
TO_DATE('22.02.2016') 
--------------------------- 
22.02.2016 00:00:00 

1 rows selected.

Andere Session, andere NLS-Settings …?

SQL> select to_date('22.02.2016') from dual; 
select to_date('22.02.2016') from dual 
* 
FEHLER in Zeile 1: 
ORA-01843: Kein gültiger Monat

Besser: Explizite Formate verwenden

Explizite Formatmaske

SQL> select to_date('22.02.2016', 'DD.MM.YYYY') DAT from dual;
DAT
---------------------------
22.02.2016 00:00:00

Aber …

SQL> select to_date('22-MAR-2016', 'DD-MON-YYYY') DAT from dual;
select to_date('22-MAR-2016', 'DD-MON-YYYY') DAT from dual
*

FEHLER in Zeile 1:
ORA-01843: Kein gültiger Monat

Besser: Explizite Formate verwenden

Explizite Formatmaske und Datumssprache …

SQL> select to_date('22-MAR-2016', 'DD-MON-YYYY', 'nls_date_language=''english''') DAT 
     from dual; 
DAT 
--------------------------- 
22.03.2016 00:00:00

NLS_DATE_LANGUAGE ist wichtig für …

  • Vollständige und abgekürzte Monatsnamen
  • Vollständige und abgekürzte Tagesnamen
  • Erster Tag der Woche (bei uns: Montag, in USA: Sonntag)

NLS-Unabhängige Datums-Literale: Ja, die gibt es auch!

DATE-Literal nur für ein Datum ohne Uhrzeit

SQL> select DATE'2016-01-01' as DATE_INDEPENDENT_NLS from dual; 
DATE_INDEPENDENT_NLS
---------------------------
22.02.2016 00:00:00

TIMESTAMP-Literal

SQL> select TIMESTAMP'2016-01-01 20:00:00.183 CET' as TS_INDEPENDENT_NLS from dual; 
TS_INDEPENDENT_NLS
--------------------------------------
01.01.16 20:00:00,183000000 CET

Klassische Arbeit mit DATE: Addition von Dezimalzahlen

SQL> select sysdate, sysdate + 1 nxt_date from dual;

SYSDATE             NXT_DATE
------------------- -------------------
22.02.2016 11:04:29 23.02.2016 11:04:29

SQL> select sysdate, sysdate - 1/48 nxt_date from dual;

SYSDATE             NXT_DATE
------------------- -------------------
22.02.2016 11:04:34 22.02.2016 10:34:34

SQL> select sysdate, sysdate + 1/(24*60) nxt_date from dual;

SYSDATE             NXT_DATE
------------------- -------------------
22.02.2016 11:04:57 22.02.2016 11:05:57

Arbeit mit INTERVAL-Datentyp

SQL> select sysdate, sysdate + INTERVAL '1' DAY nxt_date from dual;

SYSDATE             NXT_DATE 
------------------- -------------------
22.02.2016 11:04:29 23.02.2016 11:04:29

SQL> select sysdate, sysdate + INTERVAL '30' MINUTE nxt_date from dual; 
SYSDATE             NXT_DATE 
------------------- ------------------- 
22.02.2016 11:04:34 22.02.2016 10:34:34

SQL> select sysdate, sysdate + INTERVAL '1' MINUTE nxt_date from dual; 
SYSDATE             NXT_DATE 
------------------- ------------------- 
22.02.2016 11:04:57 22.02.2016 11:05:57

Aufpassen mit dem MONTH-Interval am Ende eines Monats

SQL> -- 28.01.2016 
SQL> select sysdate, sysdate + INTERVAL '1' MONTH nxt_date from dual; 
SYSDATE             NXT_DATE 
------------------- ------------------- 
28.01.2016 11:04:29 28.02.2016 11:04:29

SQL> -- 30.01.2016
SQL> select sysdate, sysdate + INTERVAL '1' MONTH nxt_date from dual; 
select sysdate, sysdate + INTERVAL '1' MONTH nxt_date from dual; *
FEHLER in Zeile 1:
ORA-01839: Datum für angegebenen Monat nicht gültig

ADD_MONTHS-Funktion berücksichtigt die Monatslängen

SQL> -- 28.01.2016 
SQL> select sysdate, sysdate + INTERVAL '1' MONTH nxt_date from dual; 
SYSDATE             NXT_DATE 
------------------- ------------------- 
28.01.2016 11:04:29 28.02.2016 11:04:29 SQL> -- 30.01.2016 

SQL> select sysdate, add_months(sysdate, 1) nxt_date from dual; 
SYSDATE             NXT_DATE 
------------------- ------------------- 
30.01.2016 11:04:29 29.02.2016 11:04:29

Subtraktion mit DATE liefert Dezimalzahlen zurück.

SQL> select DATE'2016-04-29' - DATE'2016-01-01' date_diff from dual; 
DATE_DIFF 
---------------- 
119 

SQL> select to_date('2016-04-29 12:00', 'YYYY-MM-DD HH24:MI') – to_date('2016-04-27 08:30', 'YYYY-MM-DD HH24:MI') date_diff from dual; 
DATE_DIFF 
---------------- 
2,14583333

Dezimalzahlen lassen sich umrechnen …

SQL> select numtodsinterval( to_date('2016-04-29 12:00', 'YYYY-MM-DD HH24:MI') – to_date('2016-04-27 08:30', 'YYYY-MM-DD HH24:MI'),' 'DAY' ) date_diff from dual; 
DATE_DIFF 
----------------------------- 
+000000002 03:30:00.000000000

Zwei Intervalldatentypen

  • Interval Day to Second
  • Interval Year to Month

Einige Hilfsfunktionen für DATE und TIMESTAMP -1-

TRUNC: Schneidet Teile des Datums ab – default: TRUNC ‚DAY‘

  • TRUNC(‚2016-02-22 14:26‘, ‚DAY‘)  ‚2016-02-22 00:00‘
  • TRUNC(‚2016-02-22 14:26‘, ‚HH‘)  ‚2016-02-22 14:00‘

ROUND: Rundet ein Datum

  • ROUND(‚2016-02-22 14:26‘, ‚HH‘)  ‚2016-02-22 14:00‘
  • ROUND(‚2016-02-22 14:36‘, ‚HH‘)  ‚2016-02-22 15:00‘

EXTRACT: Extrahiert Datumsteile

  • EXTRACT(YEAR from DATE’2016-02-22′)  2016
  • EXTRACT(MONTH from DATE’2016-02-22′)  2

NEXT_DAY: Gibt das Datum des nächsten geforderten Wochentags zurück

  • Achtung: NLS_DATE_LANGUAGE ist hier wichtig!
  • NEXT_DAY(DATE’2016-02-23′, ‚DIE‘)  ‚2016-03-01‘
  • NEXT_DAY(DATE’2016-02-23′, to_char(DATE’2001-01-02′,’DAY‘))

LAST_DAY: Gibt des Monatsultimo zurück

  • LAST_DAY (DATE’2016-02-16′)  ‚2016-02-29‘
  • LAST_DAY (DATE’2016-01-16′)  ‚2016-01-31‘