Saturday, March 14, 2015

SQL Server T-SQL examples for Backup

USE [master]
GO
EXEC master.dbo.sp_addumpdevice 
@devtype = N'disk', @logicalname = N'BackupStore', @physicalname = N'C:\MSSQL12.PROD1\MSSQL\Backup\BackupStore.bak'
GO


BACKUP DATABASE [NORTHWND] TO  DISK = N'C:\Northwind.bak' WITH NOFORMAT, INIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

BACKUP DATABASE [NORTHWND] TO  DISK = N'C:\Northwind.bak' WITH  RETAINDAYS = 2, -- EXPIREDATE = N'03/14/2015 00:00:00'
    FORMAT, INIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, COMPRESSION,  STATS = 10, CONTINUE_AFTER_ERROR
GO


BACKUP DATABASE [NORTHWND] TO [BackupStore] WITH NOFORMAT, NOINIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

BACKUP DATABASE [NORTHWND] TO  [BackupStore] WITH  DIFFERENTIAL , NOFORMAT, NOINIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO


BACKUP LOG [NORTHWND] TO  [BackupStore] WITH NOFORMAT, NOINIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10, CHECKSUM
GO

BACKUP LOG [NORTHWND] TO  [BackupStore] WITH NOFORMAT, NOINIT,  NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO
declare @backupSetId as int
select @backupSetId = position from msdb..backupset where database_name=N'NORTHWND' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'NORTHWND' )
if @backupSetId is null begin raiserror(N'Verify failed. Backup information for database ''NORTHWND'' not found.', 16, 1) end
RESTORE VERIFYONLY FROM  [BackupStore] WITH  FILE = @backupSetId,  NOUNLOAD,  NOREWIND
GO

-- Backup Tail of Translog
BACKUP LOG [NORTHWND] TO  [BackupStore] WITH  NO_TRUNCATE , NOFORMAT, NOINIT, 
NAME = N'NORTHWND-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  NORECOVERY , COMPRESSION,  STATS = 10
GO

/*
Msg 33101, Level 16, State 1, Line 51
Cannot use certificate 'DatabaseSecureBackup', because its private key is not present or it is not protected by the database master key. SQL Server requires the ability to automatically access the private key of the certificate used for this operation.
Msg 3013, Level 16, State 1, Line 51
BACKUP DATABASE is terminating abnormally.
USE [Master];
CREATE CERTIFICATE DatabaseSecureBackup
   ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
   WITH SUBJECT = 'Database Secure Backup',
   EXPIRY_DATE = '20181031';
GO
*/


USE master;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<UseStrongPasswordHere>';
go
CREATE CERTIFICATE DatabaseSecureBackup2 WITH SUBJECT = 'Database Secure Backup2';
go

BACKUP DATABASE [NORTHWND] TO  DISK = N'C:\Northwind.bak'
WITH FORMAT, INIT,  MEDIANAME = N'New Secure Media',  NAME = N'NORTHWND-Full Database Backup',
SKIP, NOREWIND, NOUNLOAD, ENCRYPTION(ALGORITHM = AES_256, SERVER CERTIFICATE = [DatabaseSecureBackup2]),  STATS = 10
GO

/*
Warning: The certificate used for encrypting the database encryption key has not been backed up. You should immediately back up the certificate and the private key associated with the certificate. If the certificate ever becomes unavailable or if you must restore or attach the database on another server, you must have backups of both the certificate and the private key or you will not be able to open the database.
11 percent processed.
20 percent processed.
30 percent processed.
40 percent processed.
51 percent processed.
61 percent processed.
70 percent processed.
80 percent processed.
90 percent processed.
Processed 576 pages for database 'NORTHWND', file 'Northwind' on file 1.
100 percent processed.
Processed 1 pages for database 'NORTHWND', file 'Northwind_log' on file 1.
BACKUP DATABASE successfully processed 577 pages in 0.845 seconds (5.327 MB/sec).
*/

Thursday, March 12, 2015

Schedule a RMAN script using Oracle Scheduler on Windows Platform

 

Step 1: Create rman script file: (c:\rman\rman_validate.rcv in this example)

backup validate check logical database;

Step2: Create rman batch scripts: (c:\rman\rman_validate.bat in this example)

set ORACLE_HOME=C:\Oracle\product\11.2.0\dbhome_1
set ORACLE_SID=ORCL112
set NLS_DATE_FORMAT="YYYY-MON-DD HH24:MI:SS"

%ORACLE_HOME%\bin\rman target / log c:\rman\rman_validate.log cmdfile c:\rman\rman_validate.rcv

exit 0

Step 3: Schedule it  (Both Version 1 and Version 2 are working)
Version 1:

begin
    dbms_scheduler.drop_job (
        job_name    => 'DATABASE_VALIDATION_VIA_RMAN');
end;
/
       

begin
    dbms_scheduler.create_job(
        job_name        => 'DATABASE_VALIDATION_VIA_RMAN',
        job_type        => 'EXECUTABLE',
        job_action        => 'c:\rman\rman_validate.bat',
        start_date        => trunc(systimestamp)+4/24,
        repeat_interval        => 'FREQ=DAILY;BYHOUR=4;BYMINUTE=0',
        enabled            => false,
        comments        => 'Database validation job via RMAN validate command');
end;
/
           

begin
    dbms_scheduler.run_job(job_name=>'DATABASE_VALIDATION_VIA_RMAN',USE_CURRENT_SESSION=>true); -- true is default
end;
/

Version 2:

begin
    dbms_scheduler.drop_job (
        job_name    => 'DATABASE_VALIDATION_VIA_RMAN');
end;
/
       

begin
    dbms_scheduler.create_job(
        job_name        => 'DATABASE_VALIDATION_VIA_RMAN',
        job_type        => 'EXECUTABLE',
        job_action        => 'C:\WINDOWS\SYSTEM32\CMD.EXE',
        number_of_arguments    =>3,
        start_date        => trunc(systimestamp)+4/24,
        repeat_interval        => 'FREQ=DAILY;BYHOUR=4;BYMINUTE=0',
        enabled            => false,
        comments        => 'Database validation job via RMAN validate command');

    dbms_scheduler.set_job_argument_value('DATABASE_VALIDATION_VIA_RMAN',1,'/q');
    dbms_scheduler.set_job_argument_value('DATABASE_VALIDATION_VIA_RMAN',2,'/c');
    dbms_scheduler.set_job_argument_value('DATABASE_VALIDATION_VIA_RMAN',3,'c:\rman\rman_validate.bat');

    dbms_scheduler.enable('DATABASE_VALIDATION_VIA_RMAN');
end;
/
           

begin
    dbms_scheduler.run_job(job_name=>'DATABASE_VALIDATION_VIA_RMAN',USE_CURRENT_SESSION=>true); -- true is default
end;
/

 

Suggestions for Windows Platforms:

 

•The OracleJobScheduler Windows Service must be started before external jobs will run.
  (except for jobs in the SYS schema and jobs with credentials).
•The user that the OracleJobScheduler Windows Service runs as must have the "Log on as batch job" Windows privilege.
•A batch file (ending in .bat) cannot be called directly by the Scheduler. Instead a cmd.exe must be used and the name of the batch file passed in as an argument.

Tuesday, March 10, 2015

Fast Mirror Resync in Real Example (new feature since Oracle 11.1)

SQL> select g.group_number,g.name dgname,d.path, d.repair_timer
  2  from v$asm_disk d,v$asm_diskgroup g
  3  where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         PATH                           REPAIR_TIMER
------------ ------------------------------ ------------------------------ ------------
           1 DATA                           /dev/rdsk/c2t0d0s6                        0
           1 DATA                           /dev/rdsk/c2t1d0s6                        0
           1 DATA                           /dev/rdsk/c2t2d0s6                        0

SQL> select name,value from v$asm_attribute where group_number=1
  2   and name in ('disk_repair_time','compatible.asm','compatible.rdbms');

NAME                                     VALUE
---------------------------------------- ----------------------------------------
disk_repair_time                         3.6h
compatible.asm                           12.1.0.0.0
compatible.rdbms                         10.1.0.0.0

SQL> alter diskgroup data set attribute 'compatible.rdbms'='11.2';

Diskgroup altered.

SQL> select g.group_number,g.name dgname,d.path, d.repair_timer
  2  from v$asm_disk d,v$asm_diskgroup g
  3  where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         PATH                           REPAIR_TIMER
------------ ------------------------------ ------------------------------ ------------
           1 DATA                           /dev/rdsk/c2t0d0s6                        0
           1 DATA                           /dev/rdsk/c2t1d0s6                        0
           1 DATA                           /dev/rdsk/c2t2d0s6                        0


2015-03-10 23:23:04.823000 +08:00
SQL> alter diskgroup data set attribute 'compatible.rdbms'='11.2'
NOTE: Advancing RDBMS compatibility to 11.2.0.0.0 for grp 1
GMON querying group 1 at 9 for pid 7, osid 1782
SUCCESS: Advanced compatible.rdbms to 11.2.0.0.0 for grp 1
SUCCESS: alter diskgroup data set attribute 'compatible.rdbms'='11.2'
2015-03-10 23:24:17.988000 +08:00
Warning: VKTM detected a time drift.


SQL> !chmod 000 /dev/rdsk/c2t2d0s6


SQL> select g.group_number,g.name dgname,d.path, d.repair_timer from v$asm_disk d,v$asm_diskgroup g where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         PATH                           REPAIR_TIMER
------------ ------------------------------ ------------------------------ ------------
           1 DATA                                                                 12960
           1 DATA                           /dev/rdsk/c2t0d0s6                        0
           1 DATA                           /dev/rdsk/c2t1d0s6                        0

SQL> select g.group_number,g.name dgname,d.name, d.repair_timer from v$asm_disk d,v$asm_diskgroup g where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         NAME                                     REPAIR_TIMER
------------ ------------------------------ ---------------------------------------- ------------
           1 DATA                           DATA_0002                                       12960
           1 DATA                           DATA_0000                                           0
           1 DATA                           DATA_0001                                           0
  


Tue Mar 10 23:35:53 2015
WARNING: Read Failed. group:1 disk:2 AU:0 offset:4096 size:4096
path:Unknown disk
         incarnation:0xf0f0a79d synchronous result:'I/O error'
         subsys:Unknown library krq:0xffff80ffbc948ed8 bufp:0x9c844000 osderr1:0x0 osderr2:0x0
         IO elapsed time: 0 usec Time waited on I/O: 0 usec
WARNING: cache failed reading from group=1(DATA) dsk=2 blk=1 count=1 from disk=2 (DATA_0002) mirror=0 kfkist=0x20 status=0x02 osderr=0x0 file=kfc.c line=12668
Tue Mar 10 23:35:53 2015
Errors in file /u01/app/oracle/diag/asm/+asm/+ASM/trace/+ASM_ora_3468.trc:
ORA-15025: could not open disk "/dev/rdsk/c2t2d0s6"
ORA-27041: unable to open file
Solaris-AMD64 Error: 13: Permission denied
Additional information: 3
ORA-15080: synchronous I/O operation failed to read block 0 of disk 2 in disk group DATA
WARNING: Read Failed. group:1 disk:2 AU:11 offset:4096 size:4096
path:Unknown disk
         incarnation:0xf0f0a79d synchronous result:'I/O error'
         subsys:Unknown library krq:0xffff80ffbc948ed8 bufp:0x9c844000 osderr1:0x0 osderr2:0x0
         IO elapsed time: 0 usec Time waited on I/O: 0 usec
WARNING: cache failed reading from group=1(DATA) dsk=2 blk=1 count=1 from disk=2 (DATA_0002) mirror=1 kfkist=0x20 status=0x02 osderr=0x0 file=kfc.c line=12668
ERROR: cache failed to read group=1(DATA) dsk=2 blk=1 from disk(s): 2(DATA_0002) 2(DATA_0002)
ORA-15080: synchronous I/O operation failed to read block 0 of disk 2 in disk group DATA
ORA-15080: synchronous I/O operation failed to read block 0 of disk 2 in disk group DATA

NOTE: cache initiating offline of disk 2 group DATA
NOTE: process _user3468_+asm (3468) initiating offline of disk 2.4042303389 (DATA_0002) with mask 0x7e in group 1 (DATA) with client assisting
NOTE: checking PST: grp = 1
Tue Mar 10 23:36:00 2015
GMON checking disk modes for group 1 at 10 for pid 27, osid 3468
Tue Mar 10 23:36:00 2015
NOTE: checking PST for grp 1 done.
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0xf0f0a79d, mask = 0x6a, op = clear
Tue Mar 10 23:36:00 2015
GMON updating disk modes for group 1 at 11 for pid 27, osid 3468
WARNING: GMON has insufficient disks to maintain consensus for group 1. Minimum required is 2: updating 2 PST copies from a total of 3.
NOTE: group DATA: updated PST location: disk 0000 (PST copy 0)
NOTE: group DATA: updated PST location: disk 0001 (PST copy 1)
Tue Mar 10 23:36:01 2015
NOTE: PST update grp = 1 completed successfully
NOTE: ospid 3468 initiating cluster wide offline of disk 2 in group 1
Tue Mar 10 23:36:01 2015
NOTE: disk 2 (DATA_0002) in group 1 (DATA) is locally offline for writes
Tue Mar 10 23:36:01 2015
SUCCESS: extent 1 of file 1 group 1 repaired by relocating to a different AU on the same disk or the disk is offline
Tue Mar 10 23:36:02 2015
NOTE: process _b000_+asm (3487) initiating offline of disk 2.4042303389 (DATA_0002) with mask 0x7e in group 1 (DATA) without client assisting
Tue Mar 10 23:36:02 2015
NOTE: sending set offline flag message (3705766140) to 1 disk(s) in group 1
Tue Mar 10 23:36:02 2015
WARNING: Disk 2 (DATA_0002) in group 1 mode 0x1 is now being offlined
Tue Mar 10 23:36:02 2015
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0xf0f0a79d, mask = 0x6a, op = clear
Tue Mar 10 23:36:02 2015
GMON updating disk modes for group 1 at 12 for pid 28, osid 3487
Tue Mar 10 23:36:02 2015
NOTE: PST update grp = 1 completed successfully
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0xf0f0a79d, mask = 0x7e, op = clear
Tue Mar 10 23:36:02 2015
GMON updating disk modes for group 1 at 13 for pid 28, osid 3487
NOTE: group DATA: updated PST location: disk 0000 (PST copy 0)
NOTE: group DATA: updated PST location: disk 0001 (PST copy 1)
Tue Mar 10 23:36:03 2015
NOTE: cache closing disk 2 of grp 1: DATA_0002
Tue Mar 10 23:36:03 2015
NOTE: PST update grp = 1 completed successfully
Tue Mar 10 23:36:03 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
Tue Mar 10 23:36:42 2015
WARNING: Started Drop Disk Timeout for Disk 2 (DATA_0002) in group 1 with a value 12960
Tue Mar 10 23:37:51 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
Tue Mar 10 23:37:51 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002

SQL> !chmod 660 /dev/rdsk/c2t2d0s6

SQL> alter diskgroup data online disk 'DATA_0002';

Diskgroup altered.

SQL> select g.group_number,g.name dgname,d.name, d.repair_timer from v$asm_disk d,v$asm_diskgroup g where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         NAME                           REPAIR_TIMER
------------ ------------------------------ ------------------------------ ------------
           1 DATA                           DATA_0000                                 0
           1 DATA                           DATA_0001                                 0
           1 DATA                           DATA_0002                             12408

SQL> col path for a40
SQL> select g.group_number,g.name dgname,d.path, d.repair_timer from v$asm_disk d,v$asm_diskgroup g where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         PATH                                     REPAIR_TIMER
------------ ------------------------------ ---------------------------------------- ------------
           1 DATA                           /dev/rdsk/c2t0d0s6                                  0
           1 DATA                           /dev/rdsk/c2t1d0s6                                  0
           1 DATA                           /dev/rdsk/c2t2d0s6                                  0

SQL> select g.group_number,g.name dgname,d.name, d.repair_timer from v$asm_disk d,v$asm_diskgroup g where d.group_number=g.group_number;

GROUP_NUMBER DGNAME                         NAME                           REPAIR_TIMER
------------ ------------------------------ ------------------------------ ------------
           1 DATA                           DATA_0000                                 0
           1 DATA                           DATA_0001                                 0
           1 DATA                           DATA_0002                                 0


SQL> alter diskgroup data online disk 'DATA_0002'
Tue Mar 10 23:48:54 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
Tue Mar 10 23:48:54 2015
NOTE: client +ASM:+ASM:ASM dismounting group 1 (DATA)
Tue Mar 10 23:48:54 2015
NOTE: initiating resync of disk group 1 disks
DATA_0002 (2)

NOTE: process _user3694_+asm (3694) initiating offline of disk 2.4042303389 (DATA_0002) with mask 0x7e in group 1 (DATA) without client assisting
Tue Mar 10 23:48:54 2015
NOTE: sending set offline flag message (2531577311) to 1 disk(s) in group 1
Tue Mar 10 23:48:54 2015
WARNING: Disk 2 (DATA_0002) in group 1 mode 0x1 is now being offlined
Tue Mar 10 23:48:54 2015
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0xf0f0a79d, mask = 0x6a, op = clear
Tue Mar 10 23:48:54 2015
GMON updating disk modes for group 1 at 21 for pid 7, osid 3694
Tue Mar 10 23:48:54 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
Tue Mar 10 23:48:54 2015
NOTE: PST update grp = 1 completed successfully
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0xf0f0a79d, mask = 0x7e, op = clear
Tue Mar 10 23:48:54 2015
GMON updating disk modes for group 1 at 22 for pid 7, osid 3694
Tue Mar 10 23:48:54 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
Tue Mar 10 23:48:54 2015
NOTE: PST update grp = 1 completed successfully
NOTE: requesting all-instance membership refresh for group=1
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0x0, mask = 0x11, op = assign
Tue Mar 10 23:48:54 2015
GMON updating disk modes for group 1 at 23 for pid 7, osid 3694
Tue Mar 10 23:48:54 2015
NOTE: cache closing disk 2 of grp 1: (not open) DATA_0002
NOTE: group DATA: updated PST location: disk 0000 (PST copy 0)
NOTE: group DATA: updated PST location: disk 0001 (PST copy 1)
Tue Mar 10 23:48:54 2015
NOTE: PST update grp = 1 completed successfully
NOTE: requesting all-instance disk validation for group=1
Tue Mar 10 23:48:54 2015
NOTE: disk validation pending for 1 disk in group 1/0xb6705766 (DATA)
NOTE: Found /dev/rdsk/c2t2d0s6 for disk DATA_0002
NOTE: completed disk validation for 1/0xb6705766 (DATA)
Tue Mar 10 23:48:56 2015
NOTE: discarding redo for group 1 disk 2
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0x0, mask = 0x19, op = assign
Tue Mar 10 23:48:56 2015
GMON updating disk modes for group 1 at 24 for pid 7, osid 3694
NOTE: group DATA: updated PST location: disk 0000 (PST copy 0)
NOTE: group DATA: updated PST location: disk 0001 (PST copy 1)
NOTE: group DATA: updated PST location: disk 0002 (PST copy 2)
Tue Mar 10 23:48:56 2015
NOTE: PST update grp = 1 completed successfully
Tue Mar 10 23:48:56 2015
NOTE: membership refresh pending for group 1/0xb6705766 (DATA)
Tue Mar 10 23:48:56 2015
GMON querying group 1 at 25 for pid 16, osid 1718
NOTE: cache opening disk 2 of grp 1: DATA_0002 path:/dev/rdsk/c2t2d0s6
Tue Mar 10 23:48:56 2015
SUCCESS: refreshed membership for 1/0xb6705766 (DATA)
Tue Mar 10 23:48:56 2015
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0x0, mask = 0x5d, op = assign
Tue Mar 10 23:48:56 2015
GMON updating disk modes for group 1 at 26 for pid 7, osid 3694
Tue Mar 10 23:48:56 2015
NOTE: PST update grp = 1 completed successfully
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0x0, mask = 0x7d, op = assign
Tue Mar 10 23:48:57 2015
GMON updating disk modes for group 1 at 27 for pid 7, osid 3694
Tue Mar 10 23:48:57 2015
NOTE: PST update grp = 1 completed successfully
Tue Mar 10 23:48:57 2015
SUCCESS: alter diskgroup data online disk 'DATA_0002'
Tue Mar 10 23:49:00 2015
NOTE: Attempting voting file refresh on diskgroup DATA
Tue Mar 10 23:49:00 2015
NOTE: starting rebalance of group 1/0xb6705766 (DATA) at power 1
Starting background process ARB0
Tue Mar 10 23:49:00 2015
ARB0 started with pid=24, OS id=3699
NOTE: assigning ARB0 to group 1/0xb6705766 (DATA) with 1 parallel I/O
Tue Mar 10 23:49:01 2015
NOTE: header on disk 2 advanced to format #2 using fcn 0.0
NOTE: F1X0 on disk 2 (fmt 2) relocated at fcn 0.3058: AU 0 -> AU 10
NOTE: header on disk 0 advanced to format #2 using fcn 0.730
NOTE: F1B1 fcn on disk 0 synced at fcn 0.3058
NOTE: header on disk 1 advanced to format #2 using fcn 0.730
NOTE: F1B1 fcn on disk 1 synced at fcn 0.3058
Tue Mar 10 23:49:53 2015
NOTE: initiating PST update: grp 1 (DATA), dsk = 2/0x0, mask = 0x7f, op = assign
Tue Mar 10 23:49:53 2015
GMON updating disk modes for group 1 at 28 for pid 24, osid 3699
Tue Mar 10 23:49:53 2015
NOTE: PST update grp = 1 completed successfully
NOTE: reset timers for disk: 2
NOTE: completed online of disk group 1 disks
DATA_0002 (2)

Tue Mar 10 23:49:53 2015
NOTE: stopping process ARB0
Tue Mar 10 23:49:53 2015
NOTE: requesting all-instance membership refresh for group=1
Tue Mar 10 23:49:53 2015
SUCCESS: rebalance completed for group 1/0xb6705766 (DATA)
NOTE: membership refresh pending for group 1/0xb6705766 (DATA)
Tue Mar 10 23:49:53 2015
GMON querying group 1 at 29 for pid 16, osid 1718
Tue Mar 10 23:49:53 2015
SUCCESS: refreshed membership for 1/0xb6705766 (DATA)
NOTE: Attempting voting file refresh on diskgroup DATA

Sunday, March 8, 2015

T-SQL Reference (Querying Microsoft SQL Server 2012 Databases Jump Start)

--- Introducing SQL Server 2012


USE AdventureWorks2012;

SELECT SalesPersonID, YEAR(OrderDate) AS OrderYear
FROM Sales.SalesOrderHeader
WHERE CustomerID = 29974
GROUP BY SalesPersonID, YEAR(OrderDate)
HAVING COUNT(*) > 1
ORDER BY SalesPersonID, OrderYear;

select 1; -- quick way to perform validate performance

SELECT unitprice, OrderQty, (unitprice * OrderQty)
FROM sales.salesorderdetail;

-- AS is the recommended way
SELECT s.unitprice, s.OrderQty, (s.unitprice * s.OrderQty) as TotalCost
FROM sales.salesorderdetail as s;


SELECT s.unitprice, s.OrderQty, (s.unitprice * s.OrderQty)  TotalCost
FROM sales.salesorderdetail s;

 
SELECT s.unitprice, s.OrderQty, TotalCost=(s.unitprice * s.OrderQty) 
FROM sales.salesorderdetail s;
 
-- Advanced SELECT Statements
 
SELECT DISTINCT StoreID
FROM Sales.Customer;

SELECT ProductID, Name, ProductSubCategoryID,
    CASE ProductSubCategoryID
        WHEN 1 THEN 'Beverages'
        ELSE 'Unknown Category'
    END
FROM Production.Product;


SELECT SOH.SalesOrderID,
             SOH.OrderDate,
             SOD.ProductID,
             SOD.UnitPrice,
             SOD.OrderQty
FROM Sales.SalesOrderHeader AS SOH
JOIN Sales.SalesOrderDetail AS SOD
ON SOH.SalesOrderID = SOD.SalesOrderID;

SELECT SOH.SalesOrderID,
             SOH.OrderDate,
             SOD.ProductID,
             SOD.UnitPrice,
             SOD.OrderQty
FROM Sales.SalesOrderHeader AS SOH,
Sales.SalesOrderDetail AS SOD
WHERE SOH.SalesOrderID = SOD.SalesOrderID;

-- Customers that did not place orders:
SELECT CUST.CustomerID, CUST.StoreID, ORD.SalesOrderID, ORD.OrderDate
FROM Sales.Customer AS CUST
LEFT OUTER JOIN Sales.SalesOrderHeader AS ORD
ON CUST.CustomerID = ORD.CustomerID
WHERE ORD.SalesOrderID IS NULL;

-- Combine each row from first table with each row from second table All possible combinations are displayed
SELECT EMP1.BusinessEntityID, EMP2.JobTitle
FROM HumanResources.Employee AS EMP1
CROSS JOIN HumanResources.Employee AS EMP2;

-- Return all employees with ID of employee’s manager when a manager exists (INNER JOIN):
SELECT  EMP.EmpID, EMP.LastName,
        EMP.JobTitle, EMP.MgrID, MGR.LastName
FROM    HR.Employees AS EMP
INNER JOIN HR.Employees AS MGR
ON EMP.MgrID = MGR.EmpID ;

-- Return all employees with ID of manager (OUTER JOIN). This will return NULL for the CEO:
SELECT  EMP.EmpID, EMP.LastName,
      EMP.Title, MGR.MgrID
FROM HumanResources.Employee AS EMP
LEFT OUTER JOIN HumanResources.Employee AS MGR
ON EMP.MgrID = MGR.EmpID;


-- Filter rows for customers to display top 20 TotalDue items
SELECT TOP (20) SalesOrderID, CustomerID, TotalDue
FROM Sales.SalesOrderHeader
ORDER BY TotalDue DESC;

-- Filter rows for customers to display top 20 TotalDue items with ties (output could be more than 20 if ties exist)
SELECT TOP (20) WITH TIES SalesOrderID, CustomerID, TotalDue
FROM Sales.SalesOrderHeader
ORDER BY TotalDue DESC;

-- Filter rows for customers to display top 1% of TotalDue items
SELECT TOP (1) PERCENT SalesOrderID, CustomerID, TotalDue
FROM Sales.SalesOrderHeader
ORDER BY TotalDue DESC;

-- pagination
SELECT * FROM Production.Product ORDER BY ProductID
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY


SELECT CHOOSE (3, 'A', 'B', 'C', 'D', 'E', 'F') AS Result -- Result is 'C'

SELECT PARSE('02/12/2012' AS datetime2 USING 'en-US') AS parse_result;

SELECT format(getdate(), 'yyyy-MM-dd hh:mm:ss', 'en-US') AS format_result;

SELECT GETDATE() as "GETDATE()",
    GETUTCDATE() as "GETUTCDATE",
    CURRENT_TIMESTAMP as "CURRENT_TIMESTAMP",
    SYSDATETIME() as "SYSDATETIME()",
    SYSUTCDATETIME() as "SYSUTCDATETIME()",
    SYSDATETIMEOFFSET() as "SYSDATETIMEOFFSET()";
/*-----------
GETDATE()               GETUTCDATE              CURRENT_TIMESTAMP       SYSDATETIME()               SYSUTCDATETIME()            SYSDATETIMEOFFSET()
----------------------- ----------------------- ----------------------- --------------------------- --------------------------- ----------------------------------
2015-03-08 20:40:31.733 2015-03-08 12:40:31.733 2015-03-08 20:40:31.733 2015-03-08 20:40:31.7268304 2015-03-08 12:40:31.7268304 2015-03-08 20:40:31.7268304 +08:00
-----------
*/

SELECT DATEADD(day,1,'20120212');
-- Returns last day of month as start date, with optional offset
SELECT EOMONTH('20120212');

SELECT DATEDIFF(day,'20120925',SYSDATETIME())

-- CAST is ANSI
SELECT CAST(SYSDATETIME() AS date) AS 'TodaysDate';
SELECT CONVERT(CHAR(8), CURRENT_TIMESTAMP,112) AS ISO_style;

SELECT SalesOrderID, YEAR(OrderDate) AS OrderYear;
FROM Sales.SalesOrderHeader;

SELECT DB_NAME() AS current_database;

-- IIF returns one of two values, depending on a logical test Shorthand for a two-outcome CASE expression
SELECT ProductID, ListPrice,
IIF(ListPrice > 50, 'high', 'low') AS PricePoint
FROM Production.Product;

-- Grouping and Aggregating Data


SELECT COUNT (DISTINCT SalesOrderID) AS UniqueOrders,
AVG(UnitPrice) AS Avg_UnitPrice,
MIN(OrderQty)AS Min_OrderQty,
MAX(LineTotal) AS Max_LineTotal
FROM Sales.SalesOrderDetail;

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY OrderDate) AS RN
    ,*
    From Sales.SalesOrderHeader
) AS a
WHERE RN=1;


SELECT * FROM (
    SELECT RANK () OVER (PARTITION BY CustomerId ORDER BY OrderDate DESC) AS RN
    ,*
    From Sales.SalesOrderHeader
) AS a
WHERE RN=1;
 
 
SELECT * FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY OrderDate) AS RN
    ,*
    From Sales.SalesOrderHeader
) AS a
WHERE RN=1;

SELECT *
    FROM Sales.SalesOrderHeader a
    WHERE a.SalesOrderID=(select top 1 SalesOrderID from Sales.SalesOrderHeader b where a.CustomerID=b.CustomerID order by OrderDate)
order by a.CustomerID;

WITH a AS (
    SELECT ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY OrderDate) AS RN
    ,*
    From Sales.SalesOrderHeader
)
SELECT * FROM a where RN=1;


CREATE FUNCTION Sales.fn_LineTotal (@SalesOrderID INT)
RETURNS TABLE
AS
RETURN
    SELECT SalesOrderID,
    CAST((OrderQty * UnitPrice * (1 - SpecialOfferID))
    AS DECIMAL(8, 2)) AS LineTotal
    FROM    Sales.SalesOrderDetail
    WHERE   SalesOrderID = @SalesOrderID ;


DECLARE @OrderId INT=43826;
SELECT *FROM Sales.fn_LineTotal(@OrderId);
GO

-- SET Operators, Windows Functions, and Grouping

-- APPLY is a table operator used in the FROM clause and can be either a CROSS APPLY or OUTER APPLY
-- Operates on two input tables, left and right
-- Right table is often a derived table or a table-valued function
SELECT c.CustomerID
    ,c.AccountNumber
    ,o.*
From Sales.Customer AS c
OUTER APPLY (
    SELECT TOP 5 soh.OrderDate, Soh.SalesOrderID  FROM  sales.SalesOrderHeader AS soh
    WHERE soh.CustomerID=c.CustomerID
    ORDER BY soh.OrderDate DESC
) AS o
WHERE c.TerritoryID=3;


/*
    RANK Returns the rank of each row within the partition of a result set. May include ties and gaps.
    DENSE_RANK    Returns the rank of each row within the partition of a result set. May include ties but will not include gaps.
    ROW_NUMBER Returns a unique sequential row number within partition based on current order.
    NTILE    Distributes the rows in an ordered partition into a specified number of groups. Returns the number of the group to which the current row belongs.
    LAG    Returns an expression from a previous row that is a defined offset from the current row. Returns NULL if no row at specified position.
    LEAD    Returns an expression from a later row that is a defined offset from the current row. Returns NULL if no row at specified position.
    FIRST_VALUE    Returns the first value in the current window frame. Requires window ordering to be meaningful.
    LAST_VALUE Returns the last value in the current window frame. Requires window ordering to be meaningful.
*/

SELECT *
        ,Amount-LAG(Amount,1,0) OVER (PARTITION BY AccountID ORDER BY TransactionDate, TransactionID) AS DIFF
        ,SUM(Amount) OVER (PARTITION BY AccountID) AS FinalBalance
        ,SUM(Amount) OVER(
            PARTITION BY AccountID
            ORDER BY TransactionDate, TransactonID
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWS -- default with order by
        ) AS CurrentBalance
FROM Transactions
WHERE AccountID=25
ORDER BY AccountID,TransactionDate,TransactionID;


/*
    Pivoting includes three phases:
    Grouping determines which element gets a row in the result set
    Spreading provides the distinct values to be pivoted across
    Aggregation performs an aggregation function (such as SUM)
*/

SELECT Category, [2006],[2007],[2008]
FROM ( SELECT Category, Qty, Orderyear
     FROM Sales.CategoryQtyYear) AS D
PIVOT(SUM(QTY) FOR orderyear
        IN([2006],[2007],[2008])
        ) AS pvt;
       
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;       

-- Using UNPIVOT to normalize the table
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
    Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
GO

SELECT VendorID, Employee, Orders
FROM
   (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
   FROM pvt) p
UNPIVOT
   (Orders FOR Employee IN
      (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO       


SELECT TerritoryID, CustomerID, SUM(TotalDue) AS TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY
GROUPING SETS((TerritoryID),(CustomerID),());

--CUBE provides shortcut for defining grouping sets given a list of columns
-- All possible combinations of grouping sets are created
SELECT TerritoryID, CustomerID, SUM(TotalDue) AS TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY CUBE(TerritoryID, CustomerID)
ORDER BY TerritoryID, CustomerID;

-- ROLLUP provides shortcut for defining grouping sets, creates combinations assuming input columns form a hierarchy
SELECT TerritoryID, CustomerID, SUM(TotalDue) AS TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY ROLLUP(TerritoryID, CustomerID)
ORDER BY TerritoryID, CustomerID;

-- 06 | Modifying Data in SQL Server

INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, ModifiedDate)
VALUES (N'Square Yards', N'Y2', GETDATE());
GO

INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, ModifiedDate)
VALUES
    (N'Square Feet', N‘F2', GETDATE()),
    (N'Square Inches', N‘I2', GETDATE());

INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, ModifiedDate, Country)
VALUES ((N'Square Miles', N'M2', GETDATE()); DEFAULT);

-- INSERT...SELECT is used to insert the result set of a query into an existing table
INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, ModifiedDate)
SELECT Name, UnitMeasureCode, ModifiedDate
FROM Sales.TempUnitTable
WHERE ModifiedDate < '20080101';

-- INSERT...EXEC is used to insert the result of a stored procedure or dynamic SQL expression into an existing table
INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode, ModifiedDate)
EXEC Production.Temp_UOM
    @numrows = 5, @catid=1;

-- SELECT...INTO is similar to INSERT...SELECT but SELECT...INTO creates a new table each time the statement is executed
-- Copies column names, data types, and nullability Does not copy constraints or indexes
SELECT Name, UnitMeasureCode, ModifiedDate
INTO Production.TempUOMTable
FROM Production.UnitMeasure
WHERE orderdate < '20080101';

-- IDENTITY property with a starting number of 100 and incremented by 10 as each row is added
CREATE TABLE Production.IdentityProducts(
productid int IDENTITY(100,10) NOT NULL,
productname nvarchar(40) NOT NULL,
categoryid int NOT NULL,
unitprice money NOT NULL)  
   

-- Define a sequence
CREATE SEQUENCE dbo.InvoiceSeq AS INT START WITH 5 INCREMENT BY 5;
-- Retrieve next available value from sequence
SELECT NEXT VALUE FOR dbo.InvoiceSeq;

UPDATE Production.UnitMeasure
   SET ModifiedDate = (GETDATE())
   WHERE UnitMeasureCode = 'M2';
  

MERGE INTO schema_name.table_name AS TargetTbl
    USING (SELECT <select_list>) AS SourceTbl
    ON (TargetTbl.col1 = SourceTbl.col1)
    WHEN MATCHED THEN
        UPDATE SET col2 = SourceTbl.col2
WHEN NOT MATCHED THEN
    INSERT (<column_list>)
    VALUES (<value_list>);

ALTER TABLE Production.TransactionHistoryArchive
ADD CONSTRAINT PK_TransactionHistoryArchive_TransactionID
PRIMARY KEY CLUSTERED (TransactionID);

ALTER TABLE Sales.SalesOrderHeaderSalesReason
ADD CONSTRAINT FK_SalesReason
FOREIGN KEY (SalesReasonID)
REFERENCES Sales.SalesReason (SalesReasonID)
ON DELETE CASCADE
ON UPDATE CASCADE ;

CREATE TABLE Production.TransactionHistoryArchive4
(TransactionID int NOT NULL,
CONSTRAINT AK_TransactionID UNIQUE(TransactionID) );


ALTER TABLE DBO.NewTable
ADD ZipCode int NULL
CONSTRAINT CHK_ZipCode
CHECK (ZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]');

ALTER TABLE Sales.CountryRegionCurrency
ADD CONSTRAINT Default_Country
DEFAULT 'USA' FOR CountryRegionCode;

CREATE TRIGGER reminder1 ON Sales.Customer
AFTER INSERT, UPDATE
AS RAISERROR ('Notify Customer Relations', 16, 10);

DELETE Sales.ShoppingCartItem OUTPUT DELETED.* WHERE ShoppingCartID = 20621;
--Verify the rows in the table matching the WHERE clause have been deleted.
SELECT COUNT(*) AS [Rows in Table]
FROM Sales.ShoppingCartItem
WHERE ShoppingCartID = 20621;

--BEGIN TRAN
    DECLARE @tmp TABLE (ProductID INT PRIMARY KEY);
   
    UPDATE Production.Product SET Name=UPPER(Name)
    OUTPUT INSERTED.ProductID INTO @tmp
    WHERE ListPrice >10;
   
    SELECT * from @tmp -- @tmp can be referenced to retrieve original modified rows

-- ROLLBACK TRAN;

-- 07 | Programming with T-SQL

--Declare,initialize, and use a variable
DECLARE @SalesPerson_id INT = 5;
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS CustCount
FROM (
SELECT YEAR(OrderDate) AS OrderYear, CustomerID
FROM Sales.SalesOrderHeader
WHERE SalesPersonID = @SalesPerson_id
) AS DerivedYear
GROUP BY OrderYear;

-- Values can be assigned with a SET command or a SELECT statement
-- SET can only assign one variable at a time. SELECT can assign multiple variables at a time
-- When using SELECT to assign a value, make sure that exactly one row is returned by the query


--Declare and initialize variables
DECLARE @numrows INT = 3, @catid INT = 2;

--Use variables to pass parameters to procedure
EXEC Production.ProdsByCategory
    @numrows = @numrows, @catid = @catid;
GO


-- Create a synonym for the Product table in AdventureWorks
CREATE SYNONYM dbo.MyProduct
FOR AdventureWorks.Production.Product;
GO
-- Query the Product table by using the synonym.
SELECT ProductID, Name
FROM MyProduct
WHERE ProductID < 5;
GO

IF OBJECT_ID (‘Production.Product', 'U') IS NOT NULL
    PRINT 'I am here and contain data, so don’t delete me’;
   
IF OBJECT_ID (‘Production.Product', 'U') IS NOT NULL
    PRINT 'I am here and contain data, so don’t delete me’
ELSE
  PRINT ‘Table not found, so feel free to create one’
GO

DECLARE @BusinessEntID AS INT = 1, @Title AS NVARCHAR(50);
WHILE @BusinessEntID <=10
   BEGIN
    SELECT @Title = JobTitle FROM HumanResources.Employee
        WHERE BusinessEntityID = @BusinessEntID;
    PRINT @Title;
    SET @BusinessEntID += 1;
   END;
GO
   
BEGIN TRY
    -- Generate a divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
         ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO

BEGIN TRY
    -- Table does not exist; object name resolution error not caught.
SELECT * FROM IDontExist;
END TRY
BEGIN CATCH
    SELECT
         ERROR_NUMBER() AS ErrorNumber
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
GO

BEGIN TRY
    SELECT 100/0 AS 'Problem';
END TRY
BEGIN CATCH
    PRINT 'Code inside CATCH is beginning'
    PRINT 'MyError: ' + CAST(ERROR_NUMBER()
        AS VARCHAR(255));
    THROW;
END CATCH

-- Transactions extend batches
BEGIN TRY
BEGIN TRANSACTION
  INSERT INTO Sales.SalesOrderHeader... --Succeeds
  INSERT INTO Sales.SalesOrderDetail... --Fails
COMMIT TRANSACTION -- If no errors, transaction completes
END TRY
BEGIN CATCH
--Inserted rows still exist in Sales.SalesOrderHeader SELECT ERROR_NUMBER()
ROLLBACK TRANSACTION --Any transaction work undone
END CATCH;


-- SQL Server does not automatically roll back transactions when errors occur
-- To roll back, either use ROLLBACK statements in error-handling logic or enable XACT_ABORT
-- XACT_ABORT specifies whether SQL Server automatically rolls back the current transaction when a runtime error occurs
-- When SET XACT_ABORT is ON, the entire transaction is terminated and rolled back on error, unless occurring in TRY block
-- SET XACT_ABORT OFF is the default setting
-- Change XACT_ABORT value with the SET command:
SET XACT_ABORT ON;

-- 08 | Retrieving SQL Server Metadata and Improving Query Performance


--Pre-filtered to exclude system objects
SELECT  name, object_id, schema_id, type, type_desc
FROM sys.tables;

--Includes system and user objects
SELECT name, object_id, schema_id, type, type_desc
FROM sys.objects;

SELECT TABLE_CATALOG, TABLE_SCHEMA,
    TABLE_NAME, TABLE_TYPE
FROM    INFORMATION_SCHEMA.TABLES;

SELECT VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME,     TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,     COLUMN_NAME
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE;

SELECT VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME,     TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,     COLUMN_NAME
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE;

SELECT @@VERSION AS SQL_Version;

SELECT SERVERPROPERTY('ProductVersion') AS version;

SELECT SERVERPROPERTY('Collation') AS collation;

SELECT session_id, login_time, program_name
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;


SELECT    referencing_schema_name,     referencing_entity_name,    referencing_class_desc
FROM     sys.dm_sql_referencing_entities('Sales.SalesOrderHeader', 'OBJECT');
GO

--no parameters so lists all database
EXEC sys.sp_databases;

--single parameter of name of table
EXEC sys.sp_help N'Sales.Customer';

--multiple named parameters
EXEC sys.sp_tables
    @table_name = '%',    
    @table_owner = N'Sales';


CREATE PROCEDURE Production.ProdsByProductLine
(@numrows AS int, @ProdLine AS nchar)
AS
SELECT TOP(@numrows) ProductID,
    Name, ListPrice
FROM     Production.Product
WHERE     ProductLine = @ProdLine;

--Retrieve top 50 products with product line = M
EXEC Production.ProdsByProductLine 50, ‘M’

 

Friday, March 6, 2015

Create user friendly device alias on Solaris for ASM


oracle@solaris:~$ ls -l /dev/rdsk/c2t*d0s6
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t0d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@0,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t1d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@1,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t2d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@2,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t3d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@3,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t4d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@4,0:g,raw


oracle@solaris:~$ ls -l /devices/pci@0,0/pci1000,8000@14/*g,raw |grep oracle
crw-rw----   1 oracle   dba      208, 198 Mar  6 21:37 /devices/pci@0,0/pci1000,8000@14/sd@0,0:g,raw
crw-rw----   1 oracle   dba      208, 262 Mar  6 21:37 /devices/pci@0,0/pci1000,8000@14/sd@1,0:g,raw
crw-rw----   1 oracle   dba      208, 326 Mar  6 21:37 /devices/pci@0,0/pci1000,8000@14/sd@2,0:g,raw
crw-rw----   1 oracle   dba      208, 390 Mar  6 21:37 /devices/pci@0,0/pci1000,8000@14/sd@3,0:g,raw
crw-rw----   1 oracle   dba      208, 454 Mar  6 21:37 /devices/pci@0,0/pci1000,8000@14/sd@4,0:g,raw

root@solaris:/u01/asmdisks# mknod disk1 c 208 198
root@solaris:/u01/asmdisks# mknod disk2 c 208 262
root@solaris:/u01/asmdisks# mknod disk3 c 208 326
root@solaris:/u01/asmdisks# mknod disk4 c 208 390
root@solaris:/u01/asmdisks# mknod disk5 c 208 454
root@solaris:/u01/asmdisks# chmod 660 disk*
root@solaris:/u01/asmdisks# chown oracle:dba disk*
root@solaris:/u01/asmdisks# ls -l disk*
crw-rw----   1 oracle   dba      208, 198 Mar  6 22:55 disk1
crw-rw----   1 oracle   dba      208, 262 Mar  6 23:04 disk2
crw-rw----   1 oracle   dba      208, 326 Mar  6 23:05 disk3
crw-rw----   1 oracle   dba      208, 390 Mar  6 23:05 disk4
crw-rw----   1 oracle   dba      208, 454 Mar  6 23:05 disk5
root@solaris:/u01/asmdisks#

oracle@solaris:/u01/asmdisks$  kfod status=TRUE disks=all dscvgroup=true asm_diskstring=/u01/asmdisks/
--------------------------------------------------------------------------------
Disk          Size Header    Path                                     Disk Group   User     Group
================================================================================
   1:      16331 Mb MEMBER    /u01/asmdisks/disk1                      DATA         oracle   dba
   2:      16331 Mb MEMBER    /u01/asmdisks/disk2                      DATA         oracle   dba
   3:      16331 Mb MEMBER    /u01/asmdisks/disk3                      DATA         oracle   dba
   4:      16331 Mb CANDIDATE /u01/asmdisks/disk4                      #            oracle   dba
   5:      16331 Mb CANDIDATE /u01/asmdisks/disk5                      #            oracle   dba
--------------------------------------------------------------------------------
ORACLE_SID ORACLE_HOME
================================================================================
      +ASM /u01/app/oracle/product/12.1.0/grid
oracle@solaris:/u01/asmdisks$  kfod status=TRUE disks=all dscvgroup=true
--------------------------------------------------------------------------------
Disk          Size Header    Path                                     Disk Group   User     Group
================================================================================
   1:      16331 Mb MEMBER    /dev/rdsk/c2t0d0s6                       DATA         oracle   dba
   2:      16331 Mb MEMBER    /dev/rdsk/c2t1d0s6                       DATA         oracle   dba
   3:      16331 Mb MEMBER    /dev/rdsk/c2t2d0s6                       DATA         oracle   dba
   4:      16331 Mb CANDIDATE /dev/rdsk/c2t3d0s6                       #            oracle   dba
   5:      16331 Mb CANDIDATE /dev/rdsk/c2t4d0s6                       #            oracle   dba
--------------------------------------------------------------------------------
ORACLE_SID ORACLE_HOME
================================================================================
      +ASM /u01/app/oracle/product/12.1.0/grid

Command line references for kfod:


_asm_a/llow_only_raw_disks              KFOD allow only raw devices [_asm_allow_only_raw_disks=(TRUE)/FALSE]
_asm_l/ibraries         ASM Libraries[_asm_libraries=lib1,lib2,...]
_asms/id                ASM Instance[_asmsid=sid]
_b/oot          Running in pre-install env (boot=TRUE/FALSE)
_f/lexinfo              Provide flexinfo      (_flexinfo=TRUE/FALSE)
_p/atch_lib             Patchlib [_patch_lib=<asmclntsh_path>]
_u/ser          OS Username
asm_/diskstring         ASM Diskstring [asm_diskstring=discoverystring, discoverystring ...]
asmc/ompatibility               Include diskgroup ASM compatibility [asmcompatibility=TRUE/(FALSE)]
cli/ent_cluster         client cluster name
clus_/version           cluster version
clust/er                KFOD cluster [cluster=TRUE/(FALSE)]
db_/unique_name         db_unique_name for ASM instance[db_unique_name=dbname]
dbc/ompatibility                Include diskgroup DB compatibility [dbcompatibility=TRUE/(FALSE)]
disk_/access            Disk access method [disk_access=DIRECT/(INDIRECT)]
disks           Disks to discover [disks=raw,asm,badsize,all]
ds/cvgroup              Include group name [dscvgroup=TRUE/(FALSE)]
f/orce          Force option to delete files (force=TRUE/FALSE)
g/roup          Disks in diskgroup [group=diskgroup]
h/ostlist               hostlist[hostlist=host1,host2,...]
metadata_a/usize                AU Size for Metadata Size Calculation
metadata_c/lients               Client Count for Metadata Size Calculation
metadata_d/isks         Disk Count for Metadata Size Calculation
metadata_n/odes         Node Count for Metadata Size Calculation
metadata_r/edundancy            Redundancy for Metadata Size Calculation
na/me           Include disk name [name=TRUE/(FALSE)]
no/hdr          KFOD header suppression [nohdr=TRUE/(FALSE)]
ol/r            Import credentials to OLR [olr=TRUE/(FALSE)]
op              KFOD options type [OP=DISKS/CANDIDATES/MISSING/GROUPS/INSTS/VERSION/PATCHES/PATCHLVL/CLIENTS/RM/RMVERS/DFLTDSTR/GPNPDSTR/METADATA/CREDCRECLUS/GETCLSTYPE/CREDEXPORT/GETASMGUID/CREDDELCLUS/CREDVERIFY/UPGRADEVERIFY/ALL]
p/file          ASM parameter file [pfile=parameterfile]
r/im_disk_access                Rim disk access method [rim_disk_access=DIRECT/(INDIRECT)]
s/tatus         Include disk header status [status=TRUE/(FALSE)]
v/erbose                KFOD verbose errors [verbose=TRUE/(FALSE)]
w/rap           wrap file for credentials
oracle@solaris:/u01/asmdisks$ kfod asm_diskstring=/u01/asmdisk/*  status=TRUE disk=all
KFOD-00101: LRM error [107] while parsing command line arguments
_asm_a/llow_only_raw_disks              KFOD allow only raw devices [_asm_allow_only_raw_disks=(TRUE)/FALSE]
_asm_l/ibraries         ASM Libraries[_asm_libraries=lib1,lib2,...]
_asms/id                ASM Instance[_asmsid=sid]
_b/oot          Running in pre-install env (boot=TRUE/FALSE)
_f/lexinfo              Provide flexinfo      (_flexinfo=TRUE/FALSE)
_p/atch_lib             Patchlib [_patch_lib=<asmclntsh_path>]
_u/ser          OS Username
asm_/diskstring         ASM Diskstring [asm_diskstring=discoverystring, discoverystring ...]
asmc/ompatibility               Include diskgroup ASM compatibility [asmcompatibility=TRUE/(FALSE)]
cli/ent_cluster         client cluster name
clus_/version           cluster version
clust/er                KFOD cluster [cluster=TRUE/(FALSE)]
db_/unique_name         db_unique_name for ASM instance[db_unique_name=dbname]
dbc/ompatibility                Include diskgroup DB compatibility [dbcompatibility=TRUE/(FALSE)]
disk_/access            Disk access method [disk_access=DIRECT/(INDIRECT)]
disks           Disks to discover [disks=raw,asm,badsize,all]
ds/cvgroup              Include group name [dscvgroup=TRUE/(FALSE)]
f/orce          Force option to delete files (force=TRUE/FALSE)
g/roup          Disks in diskgroup [group=diskgroup]
h/ostlist               hostlist[hostlist=host1,host2,...]
metadata_a/usize                AU Size for Metadata Size Calculation
metadata_c/lients               Client Count for Metadata Size Calculation
metadata_d/isks         Disk Count for Metadata Size Calculation
metadata_n/odes         Node Count for Metadata Size Calculation
metadata_r/edundancy            Redundancy for Metadata Size Calculation
na/me           Include disk name [name=TRUE/(FALSE)]
no/hdr          KFOD header suppression [nohdr=TRUE/(FALSE)]
ol/r            Import credentials to OLR [olr=TRUE/(FALSE)]
op              KFOD options type [OP=DISKS/CANDIDATES/MISSING/GROUPS/INSTS/VERSION/PATCHES/PATCHLVL/CLIENTS/RM/RMVERS/DFLTDSTR/GPNPDSTR/METADATA/CREDCRECLUS/GETCLSTYPE/CREDEXPORT/GETASMGUID/CREDDELCLUS/CREDVERIFY/UPGRADEVERIFY/ALL]
p/file          ASM parameter file [pfile=parameterfile]
r/im_disk_access                Rim disk access method [rim_disk_access=DIRECT/(INDIRECT)]
s/tatus         Include disk header status [status=TRUE/(FALSE)]
v/erbose                KFOD verbose errors [verbose=TRUE/(FALSE)]
w/rap           wrap file for credentials

Labeling disks on Oracle Solaris for ASM diskgroup candidate disks (using format)

format> disk


AVAILABLE DISK SELECTIONS:
       0. c1t0d0 <ATA-VBOX HARDDISK-1.0-62.76GB>
          /pci@0,0/pci8086,2829@d/disk@0,0
       1. c1t2d0 <ATA-VBOX HARDDISK-1.0-30.00GB>
          /pci@0,0/pci8086,2829@d/disk@2,0
       2. c2t0d0 <DEFAULT cyl 2085 alt 2 hd 255 sec 63 cyl 2085 alt 2 hd 255 sec 63>
          /pci@0,0/pci1000,8000@14/sd@0,0
       3. c2t1d0 <VBOX-HARDDISK-1.0 cyl 2086 alt 2 hd 255 sec 63>
          /pci@0,0/pci1000,8000@14/sd@1,0
       4. c2t2d0 <VBOX-HARDDISK-1.0 cyl 2086 alt 2 hd 255 sec 63>
          /pci@0,0/pci1000,8000@14/sd@2,0
       5. c2t3d0 <VBOX-HARDDISK-1.0 cyl 2086 alt 2 hd 255 sec 63>
          /pci@0,0/pci1000,8000@14/sd@3,0
       6. c2t4d0 <VBOX-HARDDISK-1.0 cyl 2086 alt 2 hd 255 sec 63>
          /pci@0,0/pci1000,8000@14/sd@4,0
Specify disk (enter its number)[2]: 3
selecting c2t1d0
[disk formatted]
No Solaris fdisk partition found.

format> partition
WARNING - This disk may be in use by an application that has
          modified the fdisk table. Ensure that this disk is
          not currently in use before proceeding to use fdisk.
format> fdisk
No fdisk table exists. The default partition for the disk is:

  a 100% "SOLARIS System" partition

Type "y" to accept the default partition,  otherwise type "n" to edit the
partition table.
y

format> partition


PARTITION MENU:
        0      - change `0' partition
        1      - change `1' partition
        2      - change `2' partition
        3      - change `3' partition
        4      - change `4' partition
        5      - change `5' partition
        6      - change `6' partition
        7      - change `7' partition
        select - select a predefined table
        modify - modify a predefined partition table
        name   - name the current table
        print  - display the current table
        label  - write partition map and label to the disk
        !<cmd> - execute <cmd>, then return
        quit

partition> print
Current partition table (default):
Total disk cylinders available: 2085 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders        Size            Blocks
  0 unassigned    wm       0               0         (0/0/0)           0
  1 unassigned    wm       0               0         (0/0/0)           0
  2     backup    wu       0 - 2084       15.97GB    (2085/0/0) 33495525
  3 unassigned    wm       0               0         (0/0/0)           0
  4 unassigned    wm       0               0         (0/0/0)           0
  5 unassigned    wm       0               0         (0/0/0)           0
  6 unassigned    wm       0               0         (0/0/0)           0
  7 unassigned    wm       0               0         (0/0/0)           0
  8       boot    wu       0 -    0        7.84MB    (1/0/0)       16065
  9 unassigned    wm       0               0         (0/0/0)           0

       
partition> 6
Part      Tag    Flag     Cylinders        Size            Blocks
  6 unassigned    wm       0               0         (0/0/0)           0

Enter partition id tag[unassigned]:
Enter partition permission flags[wm]:
Enter new starting cyl[0]: 2 <--- can be 3 as well, just to skip cyl 0 to avoid VTOC
Enter partition size[0b, 0c, 2e, 0.00mb, 0.00gb]: 2082c
partition> print
Current partition table (unnamed):
Total disk cylinders available: 2085 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders        Size            Blocks
  0 unassigned    wm       0               0         (0/0/0)           0
  1 unassigned    wm       0               0         (0/0/0)           0
  2     backup    wu       0 - 2084       15.97GB    (2085/0/0) 33495525
  3 unassigned    wm       0               0         (0/0/0)           0
  4 unassigned    wm       0               0         (0/0/0)           0
  5 unassigned    wm       0               0         (0/0/0)           0
  6 unassigned    wm       2 - 2083       15.95GB    (2082/0/0) 33447330
  7 unassigned    wm       0               0         (0/0/0)           0
  8       boot    wu       0 -    0        7.84MB    (1/0/0)       16065
  9 unassigned    wm       0               0         (0/0/0)           0

partition> label
Ready to label disk, continue? y

root@solaris:~# /usr/sbin/prtvtoc /dev/rdsk/c2t0d0s2
* /dev/rdsk/c2t0d0s2 partition map
*
* Dimensions:
*     512 bytes/sector
*      63 sectors/track
*     255 tracks/cylinder
*   16065 sectors/cylinder
*    2087 cylinders
*    2085 accessible cylinders
*
* Flags:
*   1: unmountable
*  10: read-only
*
* Unallocated space:
*       First     Sector    Last
*       Sector     Count    Sector
*       16065     16065     32129
*    33479460     16065  33495524
*
*                          First     Sector    Last
* Partition  Tag  Flags    Sector     Count    Sector  Mount Directory
       2      5    01          0  33495525  33495524
       6      0    00      32130  33447330  33479459
       8      1    01          0     16065     16064

root@solaris:~# ls -l /dev/rdsk/c2t*d0s6
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t0d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@0,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t1d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@1,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t2d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@2,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t3d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@3,0:g,raw
lrwxrwxrwx   1 root     root          50 Mar  2 17:10 /dev/rdsk/c2t4d0s6 -> ../../devices/pci@0,0/pci1000,8000@14/sd@4,0:g,raw
root@solaris:~# chown oracle:dba /dev/rdsk/c2t*d0s6
root@solaris:~# chmod 660 /dev/rdsk/c2t*d0s6

image