Wednesday, December 18, 2013

NOLOCK .... Think twice


Not all the RDBMS are the same.

One of the most important distinction between Oracle and  SQL Server / DB2 is that , in Oracle  readers does not block writers and writers does not block readers. This is called read consistency .

In SQL Server , readers does block writers and vice versa with the default setting. Most of developers use NOLOCK hint to alleviate this locking issue.  Not many are aware of the fact that NOLOCK does allow dirty ( uncommited) reads . That means , you could be reporting on non-existent data. Dirty reads are indeed dirty and dangerous.

Let us see an example.

We will create a test database and check the setting.

C:\>sqlcmd -W
1> create database testiso;
2> go
1> select name , snapshot_isolation_state , snapshot_isolation_state_desc , is_read_committed_snapshot_on from sys.databases where name ='TESTISO';
2> go
name snapshot_isolation_state snapshot_isolation_state_desc is_read_committed_snapshot_on
---- ------------------------ ----------------------------- -----------------------------
testiso 0 OFF 0

(1 rows affected)



You can visit this link ( http://msdn.microsoft.com/en-us/library/ms178534.aspx) for the description of the properties.

Let us have two sessions , where session 1 creates a table , inserts a record into a table  within a transaction.

Session 1
=========
1> create table t ( c1 int identity(1,1) , c2 int , c3 varchar(25) ) ;
2> go

1> insert into t ( c2 , c3) values ( 10, 'Test Record1') ;
2> go

(1 rows affected)

1> begin transaction
2> insert into t ( c2 , c3) values ( 20, 'Test Record2') ;
3> go

(1 rows affected)


Now open another session ( Let us say Session 2 ) and SELECT the record from the table t.

1> select * from t;
2> go


Now this session will hang till the transaction in Session 1 is either commited / rolled back.

Let us kill the SELECT in session 2 and  issue the same SELECT with NOLOCK hint.

Sqlcmd: Warning: The last operation was terminated because the user pressed CTRL+C.
1> select * from t with(nolock)
2> go
c1 c2 c3
-- -- --
1 10 Test Record1
2 20 Test Record2

(2 rows affected)
1>

Great . Now the session does not hang ; it gives an result set back . Look at the second record . This record is placed within a transaction ; so there is a chance , this transaction may be rolled back . As we used NOLOCK hint , my query can the uncommited result sets as well.

Now let us go back to SESSION 1 and rollback the transaction .

1> rollback;
2> go


1> select * from t 
2> go
c1 c2 c3
-- -- --
1 10 Test Record1



Now , with NOLOCK hint , you produced an report with a non existent data . That is DANGEROUS .

We can mitigate this issue with the different setting in the database.
Let us change the default setting of the database.

1> ALTER DATABASE testiso SET ALLOW_SNAPSHOT_ISOLATION ON;
2> go
1> ALTER DATABASE testiso SET READ_COMMITTED_SNAPSHOT ON;
2> go

1> select name , snapshot_isolation_state , snapshot_isolation_state_desc , is_read_committed_snapshot_on from sys.databases where name ='TESTISO';
2> go
name snapshot_isolation_state snapshot_isolation_state_desc is_read_committed_snapshot_on
---- ------------------------ ----------------------------- -----------------------------
testiso 1 ON 1

(1 rows affected)


Let us repeat the same test . ie , Insert a record into a table  within a transaction.


Session 1
=========

 1> use testiso
 2> go
 Changed database context to 'testiso'.
 1> begin transaction
 2> insert into t ( c2 , c3) values ( 20, 'Test Record2') ;
 3> go

 (1 rows affected)


Session 2
=========


1> select * from t;
2> go

c1 c2 c3
-- -- --
1 10 Test Record1


Now , with this setting , the query in Session 2 does not hang and does not produce uncommited records and produces correct results .  But does have impact on tempdb. From my perspective , its worth it.

Comments Welcome.



Tuesday, October 8, 2013

ORA-20001: comma-separated list invalid near .... ( Another misleading oracle error message )





Some times , you wonder why Oracle would give non-useful error message as below .

I was trying to run one of the scheduler job manually . I bumped into ORA-20001 . It was not informational error message .  There was no command separated values in the command . Was able to fix and run the job when  I enclosed into double quotes.



exec  DBMS_SCHEDULER.run_job('DATA REPOSITRY')
Error report:
ORA-20001: comma-separated list invalid near Y
ORA-06512: at "SYS.DBMS_UTILITY", line 272
ORA-06512: at "SYS.DBMS_SCHEDULER", line 482
ORA-06512: at line 1

The correct usage of the command .



exec  DBMS_SCHEDULER.run_job('"DATA REPOSITRY"') ;


Friday, August 16, 2013

FETCH X ROWS in Oracle 12c ( New Feature !)


Oracle 12c has introduced "FETCH" n rows clause in the SELECT statement. Though , it is a "new" feature , Oracle seems to be doing the same good old techniques what the developers were doing for the last decade or so using Analytical functions.

Let us look at the example below.

The highlighted one in the following select statement is one of 12c feature. As it can be seen from the predicate information in the execution plan , Oracle is using ROW_NUMBER function. If you look at the execution plans' predicate information and results , it is pretty much the same.

Have to admit , the new feature shortens the SELECT statement and avoids the subquery .


SQL> select * from scott.emp order by empno fetch first 4 rows only;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20


Execution Plan
----------------------------------------------------------
Plan hash value: 2801941731

----------------------------------------------------------------------------------------
| Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |        |    14 |  1582 |     2   (0)| 00:00:01 |
|*  1 |  VIEW                         |        |    14 |  1582 |     2   (0)| 00:00:01 |
|*  2 |   WINDOW NOSORT STOPKEY       |        |    14 |   532 |     2   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   532 |     2   (0)| 00:00:01 |
|   4 |     INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=4)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMP"."EMPNO")<=4)
 


Here is the equivalent SQL from pre-12c .

SQL> Select * from ( Select  e.* , row_number() over ( partition by 1 order by empno) rn from scott.emp e ) where rn <= 4 ;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20          1
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30          2
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30          3
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20          4


Execution Plan
----------------------------------------------------------
Plan hash value: 2801941731

----------------------------------------------------------------------------------------
| Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |        |    14 |  1400 |     2   (0)| 00:00:01 |
|*  1 |  VIEW                         |        |    14 |  1400 |     2   (0)| 00:00:01 |
|*  2 |   WINDOW NOSORT STOPKEY       |        |    14 |   532 |     2   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   532 |     2   (0)| 00:00:01 |
|   4 |     INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("RN"<=4)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMPNO")<=4)



Comments Welcome.

Tuesday, July 16, 2013

Auto Create Statistics in Oracle 12c.

Exploring Oracle 12c .... 

Prior to Oracle 12c , we usually generate the table statistics  to give it to the Optimizer for generating cost effective plans.
 

In Oracle 12c  , this is done automatically.

Please see the example below .


Oracle 12c
===========

SQL> col product format a50
SQL> col version  format a15

SQL> Select * from product_component_version ;

PRODUCT                                            VERSION         STATUS
-------------------------------------------------- --------------- ---------------------------
NLSRTL                                             12.1.0.1.0      Production
Oracle Database 12c Enterprise Edition             12.1.0.1.0      64bit Production
PL/SQL                                             12.1.0.1.0      Production
TNS for 64-bit Windows:                            12.1.0.1.0      Production

SQL>

SQL> Create table t as Select * from all_objects;

Table created.


SQL> Create table t as Select * from all_objects;

Table created.

SQL> Select table_name , num_rows , last_analyzed from user_tab_statistics where table_name ='T';

TABLE   NUM_ROWS LAST_ANAL
----- ---------- ---------
T          73760 16-JUL-13


SQL> set pagesize 90
SQL> Select table_name , column_name , num_distinct ,    num_buckets ,  histogram , last_analyzed
  2  from user_tab_columns where table_name  ='T';

TABLE COLUMN_NAME          NUM_DISTINCT NUM_BUCKETS HISTOGRAM       LAST_ANAL
----- -------------------- ------------ ----------- --------------- ---------
T     ORACLE_MAINTAINED               2           1 NONE            16-JUL-13
T     EDITIONABLE                     2           1 NONE            16-JUL-13
T     SHARING                         3           1 NONE            16-JUL-13
T     EDITION_NAME                    0           0 NONE            16-JUL-13
T     NAMESPACE                       7           1 NONE            16-JUL-13
T     SECONDARY                       1           1 NONE            16-JUL-13
T     GENERATED                       2           1 NONE            16-JUL-13
T     TEMPORARY                       2           1 NONE            16-JUL-13
T     STATUS                          1           1 NONE            16-JUL-13
T     TIMESTAMP                    1133           1 NONE            16-JUL-13
T     LAST_DDL_TIME                1037           1 NONE            16-JUL-13
T     CREATED                      1061           1 NONE            16-JUL-13
T     OBJECT_TYPE                    23           1 NONE            16-JUL-13
T     DATA_OBJECT_ID                 86           1 NONE            16-JUL-13
T     OBJECT_ID                   73760           1 NONE            16-JUL-13
T     SUBOBJECT_NAME                  0           0 NONE            16-JUL-13
T     OBJECT_NAME                 40132           1 NONE            16-JUL-13
T     OWNER                          17           1 NONE            16-JUL-13

18 rows selected.




Oracle 11g
==========

SQL> set linesize 1000
SQL> set pagesize 90
SQL> col product format a50
SQL> col version  format a15
SQL> Select * from product_component_version ;

PRODUCT                                            VERSION         STATUS
-------------------------------------------------- --------------- ------------------
NLSRTL                                             11.2.0.3.0      Production
Oracle Database 11g Enterprise Edition             11.2.0.3.0      64bit Production
PL/SQL                                             11.2.0.3.0      Production
TNS for 64-bit Windows:                            11.2.0.3.0      Production

SQL> Create table t as Select * from all_objects;

Table created.


SQL> Select table_name , num_rows , last_analyzed from user_tab_statistics where table_name ='T';

TABLE_NAME                       NUM_ROWS LAST_ANAL
------------------------------ ---------- ---------
T

SQL> col table_name format a5
SQL> col column_name format a20
SQL> Select table_name , column_name , num_distinct ,    num_buckets ,  histogram , last_analyzed
  2  from user_tab_columns where table_name  ='T';

TABLE COLUMN_NAME          NUM_DISTINCT NUM_BUCKETS HISTOGRAM       LAST_ANAL
----- -------------------- ------------ ----------- --------------- ---------
T     OWNER                                         NONE
T     OBJECT_NAME                                   NONE
T     SUBOBJECT_NAME                                NONE
T     OBJECT_ID                                     NONE
T     DATA_OBJECT_ID                                NONE
T     OBJECT_TYPE                                   NONE
T     CREATED                                       NONE
T     LAST_DDL_TIME                                 NONE
T     TIMESTAMP                                     NONE
T     STATUS                                        NONE
T     TEMPORARY                                     NONE
T     GENERATED                                     NONE
T     SECONDARY                                     NONE
T     NAMESPACE                                     NONE
T     EDITION_NAME                                  NONE

15 rows selected.

SQL> exec dbms_stats.gather_table_stats ( user , 'T' );

PL/SQL procedure successfully completed.

SQL> Select table_name , num_rows , last_analyzed from user_tab_statistics where table_name ='T';

TABLE   NUM_ROWS LAST_ANAL
----- ---------- ---------
T          56358 16-JUL-13

SQL> Select table_name , column_name , num_distinct ,    num_buckets ,  histogram , last_analyzed
  2  from user_tab_columns where table_name  ='T';

TABLE COLUMN_NAME          NUM_DISTINCT NUM_BUCKETS HISTOGRAM       LAST_ANAL
----- -------------------- ------------ ----------- --------------- ---------
T     OWNER                          16           1 NONE            16-JUL-13
T     OBJECT_NAME                 31094           1 NONE            16-JUL-13
T     SUBOBJECT_NAME                 12           1 NONE            16-JUL-13
T     OBJECT_ID                   56358           1 NONE            16-JUL-13
T     DATA_OBJECT_ID                 92           1 NONE            16-JUL-13
T     OBJECT_TYPE                    29           1 NONE            16-JUL-13
T     CREATED                      1122           1 NONE            16-JUL-13
T     LAST_DDL_TIME                1459           1 NONE            16-JUL-13
T     TIMESTAMP                    1429           1 NONE            16-JUL-13
T     STATUS                          2           1 NONE            16-JUL-13
T     TEMPORARY                       2           1 NONE            16-JUL-13
T     GENERATED                       2           1 NONE            16-JUL-13
T     SECONDARY                       1           1 NONE            16-JUL-13
T     NAMESPACE                      10           1 NONE            16-JUL-13
T     EDITION_NAME                    0           0 NONE            16-JUL-13

15 rows selected.

Friday, July 5, 2013

Oracle 12c Installed ... New "fetch" Feature in Oracle 12c

Oracle released its latest version of its database last week .
Installed it this week and started playing with that.

DBCA
====

While creating database via dbca , it has two buttons "Alert Log" and "Activity Log" . By clicking on "Alert Log" , a Java popup window displays the contents of the (legacy ) alert log.

SQL Feature
===========

Started with the "tiny" new feature in SQL . I believe , it will be useful in pagination queries.


SQL> select empno , ename , hiredate from emp order by hiredate;

     EMPNO ENAME      HIREDATE
---------- ---------- ---------
      7369 SMITH      17-DEC-80
      7499 ALLEN      20-FEB-81
      7521 WARD       22-FEB-81
      7566 JONES      02-APR-81
      7698 BLAKE      01-MAY-81
      7782 CLARK      09-JUN-81
      7844 TURNER     08-SEP-81
      7654 MARTIN     28-SEP-81
      7839 KING       17-NOV-81
      7900 JAMES      03-DEC-81
      7902 FORD       03-DEC-81
      7934 MILLER     23-JAN-82
      7788 SCOTT      19-APR-87
      7876 ADAMS      23-MAY-87

14 rows selected.


SQL> select empno , ename , hiredate from emp order by hiredate  fetch first 50 percent rows only;

     EMPNO ENAME      HIREDATE
---------- ---------- ---------
      7369 SMITH      17-DEC-80
      7499 ALLEN      20-FEB-81
      7521 WARD       22-FEB-81
      7566 JONES      02-APR-81
      7698 BLAKE      01-MAY-81
      7782 CLARK      09-JUN-81
      7844 TURNER     08-SEP-81

7 rows selected.


As it can be seen from the example , I can display only the part of the resultset based on %.

Will continue to explore and post my findings as I come across.

Comments Welcome.

Thursday, June 13, 2013

Writing user defined message to Alert Log in Oracle.

In Oracle , there is a undocumented package/API ( dbms_system) to write user defined messages in the alert log.  This can be executed an user with SYSDBA privilege . You may want to use this with caution , as it is not supported by Oracle.

The signature of this procedure call is

dbms_system.ksdwrt ( Trace Identifier , User Defined Message )

Note :
When Trace Identifier is 1 , the message is written to a trace file only.
When Trace Identifier is 2 , the message is written to a alert log only.
When Trace Identifier is 3 , the message is written to a alert log and trace file. 


Here is an example.


SQL> show parameter user_dump_de

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
user_dump_dest                       string      C:\app\mohideen\diag\rdbms\zmdb
                                                 rd11\zmdbrd11\trace



SQL> exec dbms_system.ksdwrt(1, 'Writing Alert message with 1');

PL/SQL procedure successfully completed.

SQL> exec dbms_system.ksdwrt(2, 'Writing Alert message with 2');

PL/SQL procedure successfully completed.

SQL> exec dbms_system.ksdwrt(3, 'Writing Alert message with 3');

PL/SQL procedure successfully completed.



C:\app\mohideen\diag\rdbms\zmdbrd11\zmdbrd11\trace>type alert_zmdbrd11.log
Thu Jun 13 15:31:44 2013
Writing Alert message with 2
Writing Alert message with 3



C:\app\mohideen\diag\rdbms\zmdbrd11\zmdbrd11\trace>type zmdbrd11_ora_8928.trc
Trace file C:\APP\MOHIDEEN\diag\rdbms\zmdbrd11\zmdbrd11\trace\zmdbrd11_ora_8928.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
Windows NT Version V6.1 Service Pack 1
CPU                 : 8 - type 8664, 8 Physical Cores
Process Affinity    : 0x0x0000000000000000
Memory (Avail/Total): Ph:4194M/12285M, Ph+PgF:14916M/24569M
Instance name: zmdbrd11
Redo thread mounted by this instance: 1
Oracle process number: 20
Windows thread id: 8928, image: ORACLE.EXE (SHAD)


*** 2013-06-13 15:31:38.973
*** SESSION ID:(131.1077) 2013-06-13 15:31:38.973
*** CLIENT ID:() 2013-06-13 15:31:38.973
*** SERVICE NAME:(SYS$USERS) 2013-06-13 15:31:38.973
*** MODULE NAME:(sqlplus.exe) 2013-06-13 15:31:38.973
*** ACTION NAME:() 2013-06-13 15:31:38.973

Writing Alert message with 1

*** 2013-06-13 15:31:52.171
Writing Alert message with 3


At times , this trick could be useful . You can see my another post on how to monitor the alert log (
http://mfzahirdba.blogspot.com/2010/10/monitoring-alert-log.html) .

Comments Welcome.

Wednesday, February 13, 2013

ORA-14257 - One of the misleading error message.



Sometimes , you wonder why Oracle would give misleading error message .  
This is reference to ORA-14257.


SQL Error: ORA-14257: cannot move partition other than a Range, List, System, or Hash partition
14257. 00000 -  "cannot move partition other than a Range or Hash partition"
*Cause:    User attempt to move a partition that is not a Range or Hash
           partition which is illegal
*Action:   Specify MOVE PARTITION for a Range or Hash partition only



As part of database maintenance route , we may need to change the storage of some segments . In this case , we are moving the partition(s) to a different tablespace.   When you a simple partitioned table , we need specify the move command at the partition level ; but if  is a composite partitioned table , the move command should be at the sub-partition level.  If you wrongfully specified the partition level move for a composite partitioned table , then Oracle throws ORA-14257 ( a misleading text).

Here is an example.

SQL> DROP TABLE storesales purge ;

Table dropped.

SQL> CREATE TABLE storesales
  2    (
  3      storekey  INT NOT NULL ,
  4      datekey   INT NOT NULL ,
  5      regionkey INT NOT NULL ,
  6      saleqty   INT NOT NULL ,
  7      CONSTRAINT PK_storesales_sp PRIMARY KEY (datekey , regionkey , storekey )
  8    )
  9    PARTITION BY LIST ( datekey )
 10    (
 11           PARTITION P_2012 VALUES ( 12 )
 12      ,    PARTITION P_2013 VALUES ( 13 )
 13    ) ;

Table created.

SQL>   SELECT table_name ,
  2    composite ,
  3    partition_name ,
  4    tablespace_name
  5  FROM user_tab_partitions
  6  WHERE table_name ='STORESALES' ;

TABLE_NAME                     COM PARTITION_NAME                 TABLESPACE_NAME
------------------------------ --- ------------------------------ ------------------------------
STORESALES                     NO  P_2012                         USERS
STORESALES                     NO  P_2013                         USERS

SQL> alter table storesales move partition p_2012 tablespace tbscsb;

Table altered.

SQL> alter table storesales move partition p_2013 tablespace tbscsb;

Table altered.

SQL> SELECT table_name ,
  2    composite ,
  3    partition_name ,
  4    tablespace_name
  5  FROM user_tab_partitions
  6  WHERE table_name ='STORESALES' ;

TABLE_NAME                     COM PARTITION_NAME                 TABLESPACE_NAME
------------------------------ --- ------------------------------ ------------------------------
STORESALES                     NO  P_2012                         TBSCSB
STORESALES                     NO  P_2013                         TBSCSB

SQL>


As we can see , this table is of simple partition  (composite = NO ) the table partitions have been moved to "TBSCSB" ( different tablespace) with no issues.

Now , let us create a composite partitioned table and perform similar operations. 

SQL>  drop table storesales_cp purge ;

Table dropped.

SQL>  Create table storesales_cp
  2   (    storekey int not null
  3      , datekey int not null
  4      , regionkey int not null
  5      , saleqty int not null
  6       , CONSTRAINT PK_storesales_cp PRIMARY KEY (datekey , regionkey , storekey )
  7      )
  8    PARTITION BY LIST (datekey)
  9    SUBPARTITION BY LIST (regionkey)
 10   (
 11   PARTITION P_2012 VALUES ( 12 )
 12   ( SUBPARTITION P2012_0  VALUES (0)     ,
 13     SUBPARTITION P2012_1  VALUES (1)     ,
 14     SUBPARTITION P2012_7  VALUES (7)     ,
 15     SUBPARTITION P2012_9  VALUES (9)
 16    )
 17   ,
 18   PARTITION P_2013 VALUES ( 13 )
 19    ( SUBPARTITION P2013_0  VALUES (0)     ,
 20     SUBPARTITION P2013_1  VALUES (1)     ,
 21     SUBPARTITION P2013_7  VALUES (7)     ,
 22     SUBPARTITION P2013_9  VALUES (9)
 23    )
 24    ) ;

Table created.

SQL>   SELECT table_name ,
  2    composite ,
  3    partition_name ,
  4    tablespace_name
  5  FROM user_tab_partitions
  6  WHERE table_name ='STORESALES_CP' ;

TABLE_NAME                     COM PARTITION_NAME                 TABLESPACE_NAME
------------------------------ --- ------------------------------ ------------------------------
STORESALES_CP                  YES P_2012                         USERS
STORESALES_CP                  YES P_2013                         USERS

SQL> alter table storesales_cp move partition p_2012 tablespace tbscsb;
alter table storesales_cp move partition p_2012 tablespace tbscsb
                                         *
ERROR at line 1:
ORA-14257: cannot move partition other than a Range, List, System, or Hash partition



Oracle should have provided me an error message that this is a composite partition but not the above.

Let us perform the move operations at the sub-partition level. 

SQL> SELECT table_name ,
  2    partition_name ,
  3    subpartition_name ,
  4    tablespace_name
  5  FROM user_tab_subpartitions
  6  WHERE table_name ='STORESALES_CP' ;

TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME              TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ------------------------------
STORESALES_CP                  P_2012                         P2012_0                        USERS
STORESALES_CP                  P_2012                         P2012_1                        USERS
STORESALES_CP                  P_2012                         P2012_7                        USERS
STORESALES_CP                  P_2012                         P2012_9                        USERS
STORESALES_CP                  P_2013                         P2013_0                        USERS
STORESALES_CP                  P_2013                         P2013_1                        USERS
STORESALES_CP                  P_2013                         P2013_7                        USERS
STORESALES_CP                  P_2013                         P2013_9                        USERS

8 rows selected.


 
 SQL> alter table storesales_cp move subpartition p2012_0 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2012_1 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2012_7 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2012_9 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp move subpartition p2013_0 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2013_1 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2013_7 tablespace tbscsb;

Table altered.

SQL> alter table storesales_cp  move subpartition p2013_9 tablespace tbscsb;

Table altered.

SQL>


SQL> SELECT table_name ,
  2    partition_name ,
  3    subpartition_name ,
  4    tablespace_name
  5  FROM user_tab_subpartitions
  6  WHERE table_name ='STORESALES_CP' ;

TABLE_NAME                     PARTITION_NAME                 SUBPARTITION_NAME              TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ------------------------------
STORESALES_CP                  P_2012                         P2012_0                        TBSCSB
STORESALES_CP                  P_2012                         P2012_1                        TBSCSB
STORESALES_CP                  P_2012                         P2012_7                        TBSCSB
STORESALES_CP                  P_2012                         P2012_9                        TBSCSB
STORESALES_CP                  P_2013                         P2013_0                        TBSCSB
STORESALES_CP                  P_2013                         P2013_1                        TBSCSB
STORESALES_CP                  P_2013                         P2013_7                        TBSCSB
STORESALES_CP                  P_2013                         P2013_9                        TBSCSB

8 rows selected.

SQL>



Now , the move operations are successful.  I believe, in the upcoming release of Oracle ( Oracle 12c) , some of the partition management are made easier . Hopefully , Oracle changes the text of this message as well. 

Comments welcome. 

 

Tuesday, January 22, 2013

Book : SQL Server Window Functions

One of my favorite tool-set in Oracle database  is Analytical functions . I used it , wherever appropriate . Most of time , it has solved my problems , which otherwise been done by procedural logic ( aka PL/SQL ) .

Analytical functions has been implemented in Oracle since 1993 - almost  two decades.

You might wonder  ... the title says .... SQL Server .. and this guy talks about Oracle .

With the release of SQL Server 2012  ,  SQL Server has almost all the analytical functions as Oracle.

Currently , I am reading the book "Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions" [ Microsoft Press]. It is pretty interesting and easy read. This book has lot of new stuff for T-SQL developers.  I was surprised to see the name of Oracle Cheif Technogist name ( Tom Kyte ) in one of the chapters [ side notes - where the author mentions about the proposal of new analytical functionality].


I wish both Oracle / MS maintains the same terminology on these functions ( instead of calling it as "analytical " or " window" functions , settle on one nomenclature ) .

Wednesday, January 2, 2013

Encrypt Connections to SQL Server

By default , the connections to SQL Server are not encrypted.

C:\>sqlcmd -W
1>  Select  protocol_type , encrypt_option  from sys.dm_exec_connections;
2> go


protocol_type encrypt_option
------------- --------------
TSQL FALSE
TSQL FALSE


We  can use SSL to encrypt the connections using SQL Server  Configuration Manager . 
Here are the steps.

a)  Expand "SQL Server Network Configuration " in the left panel
b) Right Click on  the "Protocols for XXXX" ( where XXXX is the ServiceName ) and select Properties.
c) Select "Yes" in the "Force Encryption " in the "Flags" tab.
d) Select the certificate in the "Certificate" tab. ( Note : If you don't specify  the certificate , SQL Server uses the self signed certificate) .
e) Click OK and restart the service(s) 


To verify the changes , run the following SQL .


C:\>sqlcmd -W
1>  Select  protocol_type , encrypt_option  from sys.dm_exec_connections;
2> go
protocol_type encrypt_option
------------- --------------
TSQL TRUE
TSQL TRUE
TSQL TRUE
TSQL TRUE


Comments Welcome.