Sql scripting sorcerypaper


Published on

oracle foreign key primary key constraints performance tuning MTS IOT 9i block size backup rman corrupted column drop rename recovery controlfile backup clone architecture database archives export dump dmp duplicate rows extents segments fragmentation hot cold blobs migration tablespace locally managed redo undo new features rollback ora-1555 shrink free space user password link TNS tnsnames.ora listener java shutdown sequence

  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Sql scripting sorcerypaper

  1. 1. SQL SCRIPTING SORCERY ORUSING SQL AND SQL*PLUS TO GO BEYOND “SELECT * FROM EMP;”Daniel W. Fink How do I show the manager-employee relationship with the department name instead of number? How do I see the top two salaries in the company? How do I see the top two salaries in each department? How do I select a sample of a production database to create a test database? How do I select a sample from each department to create a test database? How do I report with a Hire Year axis and Department axis format? How do I give different raises if someone was hired between April 1, 1981 and April 1 1982 or was hired at another time? How do I select fields from different tables based upon data? How can I avoid a self-join? How can I create an interactive menu in SQL*Plus? How can I default an accepted field to today’s date? Can I use a select statement inside a decode?Creativity is the key. Look upon the limits of SQL as a floor to build upon,not a ceiling to stop progress.SQL is the language used for all communication with Oracle databases. It is a very simple language with a limited number ofelements, but can be very powerful with a little creativity. Some of the limitations is that are cannot perform IF-THEN-ELSEor LOOP logic. With a little ‘outside the box’ thinking, this logic can be partially duplicated. For any desired result set, thereare usually two or more sql statements that can achieve the desired result. One may be elegant, but a poor performer, whilethe other may be complicated and convoluted, but a real speed demon. Which is better? That is for you to decide.The first topic to be covered is the use of Inline Queries, or selects within a select. Some of the main uses for inline queriesare for Top N, joined-hierarchical, sampling and view-avoidance. The ubiquitous DECODE command will be covered next.We will explore using DECODE for creating matrix reports, making range-of-value decisions and selecting different columnsfrom different tables.Remember, WHAT you ask for and WHAT you receive are NOT always the same!Warning – The topics covered here are examples of creative problem solving and may not be the optimal solution forperformance. In fact, they may cause your query to slow to a crawl. Always test the solutions on a nonproduction platformand consider other avenues, such as PL/SQL or risk incurring the wrath of the DBA. All scripts were run against Oracle8.0.6 on Solaris and Oracle 8.1.6 on Windows NT.Basic ConceptsRow SourceAll data is retrieved from a row source. This may be a base object, such as a table or index, or it may be a result set returnedfrom a previous operation. Oracle will use no more than 2 row sources at any one time. If a query accesses many objects,www.rmoug.org RMOUG Training Days 2001
  2. 2. SQL Scripting Sorcery Finkonly 2 row sources are used at any time. The result set from this operation becomes one of the row sources for the nextoperation.Result SetA result set is the output of an operation. According to relational theory, records are processed in groups, not as atomic units.If two or more tables are joined, there may be intermediate result sets built during the execution of the statement.Access PathsEach time data is retrieved from the database, an access path is used. This may be a full-table scan, by rowid using an indexor by an index scan. The use of a particular access path may be determined by the Oracle optimizer or by using hints.RownumEach row that is retrieved from the database that matches the WHERE condition is placed in a result set. The sequence withinthe result set is the value in the pseudocolumn ROWNUM. If Oracle is using a full-table scan, the first row of the first blockis the first in the result set and is assigned ROWNUM 1. If Oracle uses an index to access the data, the first entry in the indexis assigned ROWNUM 1. Once a complete result set is built, the ORDER BY clause is applied. The result may be that theorder of the result set and the order presented to the user are not the same. If ROWNUM is used, the numbers may be and, infact, usually are, out of sequence.ROWNUM and PREDICATES (the WHERE clause)ROWNUM can be used to restrict the amount of data returned by a query, as we will see shortly. ROWNUM is assigned foreach row that matches all of the applicable conditions in the PREDICATE. For example, ROWNUM is assigned to a rowonly if it matches the deptno condition. One common mistake is trying to use ROWNUM to find values greater than 1.ROWNUM conditions can only be equal to 1 or less than/less than or equal to a number other than 1. The followingstatement will never return a row. select ename from emp where rownum = 2;When the first row is read from the emp table, the PREDICATE is applied. Since this is the first row, it is conditionallyassigned ROWNUM of 1. However, the condition is that ROWNUM must be equal to 2. Since this condition is not met, therow is not placed in the result set. The second row is read. Since the result set is empty, this row is assigned ROWNUM of 1.Once again, the condition is not met and the row is not placed in the result set. This process repeats until all the rows are read.However, the condition never evaluates to TRUE, so no rows are placed in the result set.Hierarchical QueryA hierarchical query is a query representing the recursive relationship of a table. They are also called explosion-of-parts, tree,organizational queries. The main requirement is that a column in the table has an optional relationship to another column. Inthe EMP table, the MGR column is related to the EMPNO column.What is an Inline Query?An inline query is a subquery used in the place of a table or view in the FROM clause of a statement. It is also referred to asan inline view, dynamic query or nested query. It was added in Oracle7.2. This can be used anywhere the FROM clause isused, even in a correlated subquery. The inline query will create a result set that the parent query uses as a row source. select col1, col2 from (select colA col1, colB col2 from table1 Inline Query Parent Query where colA = ‘TRUE’) order by col1;One of the challenges is to return a result set in ordered fashion without using the ORDER BY clause. ROWNUM is anOracle pseudocolumn that represents the order in which the row was retrieved from the database. It is assigned after anyconditions are applied in the WHERE or HAVING clause, but before the ORDER BY clause is applied. However, the use ofan index may cause the result set to be ordered before ROWNUM is assigned. In Oracle8i, the ability to use the ORDER BYclause to the inline query was added. In prior releases, it was necessary to use access paths or other methods, such asDISTINCT or GROUP BY, to return an ordered result set. If there are indexes available to satisfy the sorting criteria, hintswww.rmoug.org RMOUG Training Days 2002
  3. 3. SQL Scripting Sorcery Finkcan be used inside the inline query. Additionally, in order to reverse the sort order to descending, the sort key must bemanipulated.One maintenance consideration is that an application must be rewritten if the underlying objects have a significant change.Because the query is not stored in the data dictionary, dependencies cannot be determined by querying theUSER_DEPENDENCIES view.An inline query is evaluated once per execution of the parent query. It can also be used to reduce network traffic. Oneexample was a view that accessed data across a dblink. By rewriting the view to access the remote data via an inline query,performance was significantly improved. The subquery was executed once and returned one result set across the network,instead of being executed once for each row in the preceding result set.The output of an inline query is a static result set. In other words, it does not change based upon values presented in theparent query. This is very important to remember and a key differentiation between an inline query and a correlated subquery.? How do I show the manager-employee relationship with the department name instead of number?At first glance, this appears to be a fairly straightforward request. The basic query is very simple. It is adding in theDepartment Name that adds a complication. In the EMP table, only the department number (deptno) is kept. This adheres tothe rules of relational design. However, to most users, 10 is not as meaningful as ACCOUNTING, the description of thedepartment (dname) in the DEPT table.Simple hierarchical query SELECT level, LPAD( ,2*LEVEL-2)||emp.ename ename, emp.empno, emp.mgr, emp.deptno FROM Emp CONNECT BY PRIOR emp.empno = emp.mgr START WITH emp.mgr IS NULL LEVEL ENAME EMPNO MGR DEPTNO ---------- --------------- ---------- ---------- ---------- 1 KING 7839 10 2 JONES 7566 7839 20 3 SCOTT 7788 7566 20 4 ADAMS 7876 7788 20 3 FORD 7902 7566 20 2 BLAKE 7698 7839 30 3 ALLEN 7499 7698 30 3 WARD 7521 7698 30 3 MARTIN 7654 7698 30 3 TURNER 7844 7698 30 3 JAMES 7900 7698 30 2 CLARK 7782 7839 10 3 MILLER 7934 7782 10Joined hierarchical QueryTo retrieve the department name, we need to join the DEPT and EMP table. The relationship between them is the DEPTNOcolumn. A simple addition of the DNAME column, DEPT table and the join condition should return the department nameinstead of department number. SELECT level, LPAD( ,2*level-2)||emp.ename ename, emp.empno, emp.mgr, dept.dname FROM Emp, Dept where emp.deptno = dept.deptno CONNECT BY PRIOR emp.empno = emp.mgr START WITH emp.mgr is null; FROM Emp, Deptwww.rmoug.org RMOUG Training Days 2002
  4. 4. SQL Scripting Sorcery Fink * ERROR at line 2: ORA-01437: cannot have join with CONNECT BYUnfortunately, a join within a hierarchical query is not allowed. In order to get around this restriction, we place thehierarchical query within an inline query and the problem is solved. The hierarchical query must be placed as the inlinequery.Joined hierarchical query using an inline view select e.e_level, e.ename, e.empno, e.mgr, d.dname from dept d, (SELECT level e_level, LPAD( ,2*level-2)||emp.ename ename, emp.empno empno, emp.mgr mgr, emp.deptno deptno FROM Emp CONNECT BY PRIOR emp.empno = emp.mgr START WITH emp.mgr is null) e where e.deptno = d.deptno; E_LEVEL ENAME EMPNO MGR DNAME ------- -------------- ---------- ---------- -------------- 1 KING 7839 ACCOUNTING 2 CLARK 7782 7839 ACCOUNTING 3 MILLER 7934 7782 ACCOUNTING 2 JONES 7566 7839 RESEARCH 3 SCOTT 7788 7566 RESEARCH 4 ADAMS 7876 7788 RESEARCH 3 FORD 7902 7566 RESEARCH 2 BLAKE 7698 7839 SALES 3 ALLEN 7499 7698 SALES 3 WARD 7521 7698 SALES 3 MARTIN 7654 7698 SALES 3 TURNER 7844 7698 SALES 3 JAMES 7900 7698 SALESHow about adding the manager’s Name? We simply join with the emp table to get the manager name. It is important toremember to use an outer join, otherwise KING is not returned because the record has no MGR relationship. select e.ename, e.empno, e.mgr, e2.ename, d.dname from dept d, (SELECT rownum e_rownum, LPAD( ,2*level-2)||emp.ename ename, emp.empno empno, emp.mgr mgr, emp.deptno deptno FROM Emp CONNECT BY PRIOR emp.empno = emp.mgr START WITH emp.mgr is null) e, emp e2 where e.deptno = d.deptno and e2.empno (+) = e.mgr order by e.e_rownum; ENAME EMPNO MGR ENAME DNAME ------------------- ---------- ---------- -------------------- -------------- KING 7839 ACCOUNTING JONES 7566 7839 KING RESEARCH SCOTT 7788 7566 JONES RESEARCH ADAMS 7876 7788 SCOTT RESEARCH FORD 7902 7566 JONES RESEARCH SMITH 7369 7902 FORD RESEARCH CLARK 7782 7839 KING ACCOUNTING MILLER 7934 7782 CLARK ACCOUNTING BLAKE 7698 7839 KING SALES TURNER 7844 7698 BLAKE SALESwww.rmoug.org RMOUG Training Days 2002
  5. 5. SQL Scripting Sorcery Fink ALLEN 7499 7698 BLAKE SALES WARD 7521 7698 BLAKE SALES MARTIN 7654 7698 BLAKE SALES JAMES 7900 7698 BLAKE SALESTop N QueriesA Top N query is used to show the top values within a database. For example, a sales department may want to see the top 5Customers by Revenue. One of the limitations in versions of Oracle prior to 8.1.5 was the inability to perform a Top N typequery. Other commercial databases had this functionality, for example, Microsoft Access Top Values and Sybase SETROWCOUNT. In order to simulate this behavior, we use inline queries to create an ordered result set. This type of query isenhanced in Oracle 8.1.6 using the ORDER BY clause in the inline query.The default sorting order for Oracle is ascending, from least to greatest. In the case of numbers, it is the smallest to largest. IfI use the default ordering scheme for salary, the lowest paid employees would be at the beginning of the result set. In pre-Oracle 8.1.5 versions, I must find a method to reverse the sort order. I accomplished this by subtracting the salary from 0.This results in a the larger salary being placed at the front of the result set. In later versions, I simply sort in descending order.? How do I see the top two salaries in the company?The key in this solution is to create a sorted result set and use it to find the lowest salary that meets the qualification. It seemsthat it would be straightforward to use ROWNUM to find the 2nd salary and make a direct comparison. However, it isimportant to remember that ROWNUM = 2 is not a condition that ever evaluates to TRUE.In order to force a descending sort on the result set, I sorted on the negative value of the salary. This caused the largest salaryto be listed first in the result set.Oracle 8.0.6 SELECT ename, empno, sal, deptno, hiredate FROM emp WHERE sal >= (SELECT MIN(i_sal) FROM (SELECT DISTINCT 0-sal r_sal, sal i_sal FROM emp) WHERE ROWNUM <= 2);Oracle 8.1.6 SELECT ename, empno, sal, deptno, hiredate FROM emp WHERE sal >= (SELECT MIN(i_sal) FROM (SELECT sal i_sal FROM emp ORDER BY i_sal desc) WHERE ROWNUM <= 2); ENAME EMPNO SAL DEPTNO HIREDATE ---------- ---------- ---------- ---------- ----------- KING 7839 5000 10 17-NOV-1981 FORD 7902 3000 20 03-DEC-1981 SCOTT 7788 3000 20 09-DEC-1982Each query returns the exact same result set. The ORDER BY clause in 8i makes the 2nd query more understandable andsupportable.www.rmoug.org RMOUG Training Days 2002
  6. 6. SQL Scripting Sorcery Fink? How do I see the top two salaries in each department?Now here is a bit of a puzzler. The top 2 salaries in the company was pretty straightforward. How could I select just thedepartment? Instead of using an inline query as the row source for the parent query, it was used as the row source for acorrelated subquery. Remember, the inline query can be used in any FROM clause, even in a nested correlated subquery! SELECT M.ENAME, M.SAL, M.DEPTNO FROM EMP M WHERE M.SAL >= (SELECT DISTINCT O.SAL FROM EMP O WHERE (O.SAL,2) IN (SELECT I.SAL, ROWNUM FROM (SELECT DISTINCT 0-I2.SAL R_SAL, I2.DEPTNO, I2.SAL, I2.ROWID FROM EMP I2) I WHERE I.DEPTNO = M.DEPTNO)) ORDER BY 3, 2 DESC; ENAME SAL DEPTNO ---------- ---------- ---------- KING 5000 10 CLARK 2450 10 SCOTT 3000 20 FORD 3000 20 BLAKE 2850 30 ALLEN 1600 30Now let’s update TURNER to create duplicate salaries in department 30 and rerun the query. ENAME SAL DEPTNO ---------- ---------- ---------- KING 5000 10 CLARK 2450 10 SCOTT 3000 20 FORD 3000 20 BLAKE 2850 30 ALLEN 1600 30 TURNER 1600 30Note that department 30 returns 3 records because the 2nd salary has two matching values. In essence, Allen and Turner have‘tied’ for second place. How can this be resolved? You could use rownum to restrict further, but you may not return the sameemployee each time.? How do I select a sample of a production database to create a test database?For testing purposes, it is often requested to retrieve a subset of the data. Until Oracle8I and the ability to export a subset ofthe data, the process to manually extract data was difficult. Once you are able to select a sample, the next step of actuallyextracting and transfering the data becomes much easier. The condition using MOD function on the ROWNUM in the inlinequery will evaluate to TRUE for every 3rd record. To extract every 4th record, replace the 3 with a 4. It is just that simple. SELECT ENAME, EMPNO, SAL , I_ROWNUM, ROWNUM FROM (SELECT ENAME, EMPNO, SAL, ROWNUM I_ROWNUM FROM EMP) WHERE MOD(I_ROWNUM,3) = 0www.rmoug.org RMOUG Training Days 2002
  7. 7. SQL Scripting Sorcery Fink ENAME EMPNO SAL I_ROWNUM ROWNUM ---------- ---------- ---------- ---------- ---------- WARD 7521 1250 3 1 MARTIN 7654 1250 6 2 SMITH 7369 800 9 3 BLAKE 7698 2850 12 4Oracle 8.1.6 SELECT ENAME, EMPNO, SAL, ROWNUM FROM EMP SAMPLE (33);This query should return 33% (4 or 5 depending upon sampling algorithm) of the rows in the EMP table, but instead returnedbetween 1 and 7 rows each time it was executed. There is no explanation for this sampling variance. There are significantrestrictions in using the sample clause. Joins and remote tables are not supported and the cost-based optimizer will always beused. In this case, I found that the pre-Oracle8i usage of mod on rownum was more reliable.? How do I select a sample from each department to create a test database?Once again, we use an inline view within the correlated subquery to restrict our result set. SELECT ENAME P_ENAME, DEPTNO P_DEPTNO FROM EMP P WHERE (P.ROWID,1) IN (SELECT I.ROWID I_ROWID, MOD(ROWNUM,3) FROM EMP I WHERE I.DEPTNO = P.DEPTNO) ORDER BY P_DEPTNO; P_ENAME P_DEPTNO ---------- ---------- CLARK 10 ADAMS 20 SMITH 20 TURNER 30 MARTIN 30DecodeWhat is a DECODE?A simple method to implement if-then-else logic. The construct closely resembles the case statement used in severallanguages. It can only do equality comparison. May be abused and create “ugly SQL”. It may not always be the most elegantsolution. DECODE provides an opportunity to be very creative, but it can also create performance and maintenancenightmares. One thing to remember is that each row is processed, but each column can be processed multiple times.IF-THEN-ELSE DECODE (expression, if true1, then1, if true2, then2…else thenn) SELECT ename, deptno, DECODE(deptno, 10, ‘ACCOUNTING’, 20, ‘RESEARCH’, 30, ‘SALES’, ‘NOT INDICATED’) FROM emp; ENAME DEPTNO DECODE(DEPTNO ---------- ---------- ------------- TURNER 30 SALES ALLEN 30 SALESwww.rmoug.org RMOUG Training Days 2002
  8. 8. SQL Scripting Sorcery Fink WARD 30 SALES ADAMS 20 RESEARCH JONES 20 RESEARCH MARTIN 30 SALES CLARK 10 ACCOUNTING SCOTT 20 RESEARCH SMITH 20 RESEARCH KING 10 ACCOUNTING JAMES 30 SALES BLAKE 30 SALES FORD 20 RESEARCH MILLER 10 ACCOUNTING? How do I report with a Hire Year axis and Department axis format?One common request is to implement a Matrix (or Down and Across) report. The main challenge is to know the number ofcolumns that are required. The rows can be flexible, but the columns are fixed. SELECT TO_CHAR(HIREDATE, YYYY) HIRE_YEAR , SUM(DECODE(DEPTNO, 10, SAL+(NVL(COMM,0)), 0)) DEPT_10, SUM(DECODE(DEPTNO, 20, SAL+(NVL(COMM,0)), 0)) DEPT_20, SUM(DECODE(DEPTNO, 30, SAL+(NVL(COMM,0)), 0)) DEPT_30 FROM EMP GROUP BY TO_CHAR(HIREDATE, YYYY); HIRE DEPT_10 DEPT_20 DEPT_30 ---- ---------- ---------- ---------- 1980 0 800 0 1981 7450 5975 11600 1982 1300 3000 0 1983 0 1100 0To switch the axis so that the Years are listed across the top and Departments are listed down the side. SELECT deptno DEPTNO, SUM(DECODE(to_char(hiredate, YYYY), 1980, SAL+(NVL(COMM,0)), 0)) YR_1980, SUM(DECODE(to_char(hiredate, YYYY), 1981, SAL+(NVL(COMM,0)), 0)) YR_1981, SUM(DECODE(to_char(hiredate, YYYY), 1982, SAL+(NVL(COMM,0)), 0)) YR_1982, SUM(DECODE(to_char(hiredate, YYYY), 1983, SAL+(NVL(COMM,0)), 0)) YR_1983 FROM EMP GROUP BY deptno; DEPTNO YR_1980 YR_1981 YR_1982 YR_1983 ---------- ---------- ---------- ---------- ---------- 10 0 7450 1300 0 20 800 5975 3000 1100 30 0 11600 0 0? Changes based upon a range of values using GREATEST and LEASTGREATEST will return the greatest value in a range of valuesLEAST will return the least value in the range of valuesThe format is greatest (n, min_of_range), least(n, max_of_range)www.rmoug.org RMOUG Training Days 2002
  9. 9. SQL Scripting Sorcery Fink SELECT ENAME, HIREDATE, GREATEST(HIREDATE, TO_DATE(01-APR-1981)) GT_DATE, LEAST(HIREDATE, TO_DATE(01-APR-1982)) LT_DATE, DECODE(GREATEST(HIREDATE, TO_DATE(01-APR-1981)), LEAST(HIREDATE, TO_DATE(01-APR-1982)), .1, .05) PAY_RAISE FROM EMP; ENAME HIREDATE GT_DATE LT_DATE PAY_RAISE ---------- ----------- ----------- ----------- ---------- ALLEN 20-FEB-1981 01-APR-1981 20-FEB-1981 .05 WARD 22-FEB-1981 01-APR-1981 22-FEB-1981 .05 JONES 02-APR-1981 02-APR-1981 02-APR-1981 .1 BLAKE 01-MAY-1981 01-MAY-1981 01-MAY-1981 .1 CLARK 09-JUN-1981 09-JUN-1981 09-JUN-1981 .1 TURNER 08-SEP-1981 08-SEP-1981 08-SEP-1981 .1 MARTIN 28-SEP-1981 28-SEP-1981 28-SEP-1981 .1 KING 17-NOV-1981 17-NOV-1981 17-NOV-1981 .1 JAMES 03-DEC-1981 03-DEC-1981 03-DEC-1981 .1 FORD 03-DEC-1981 03-DEC-1981 03-DEC-1981 .1 MILLER 23-JAN-1982 23-JAN-1982 23-JAN-1982 .1 SCOTT 09-DEC-1982 09-DEC-1982 01-APR-1982 .05 ADAMS 12-JAN-1983 12-JAN-1983 01-APR-1982 .05Let’s examine the first record for ALLEN. The decode expression evaluates to ‘01-APR-1981’. The first comparisonexpression evaluates to ‘20-FEB-1981’. Is ‘01-APR-1981’ = ‘20-FEB-1981’? No, therefore the result is not used. There isnot another comparison, so the default value is used.Let’s examine the record for Jones. The decode expression evaluates to ‘02-APR-1981’. The first comparison expressionevaluates to ‘02-APR-1981’. Is ‘01-APR-1981’ = ‘02-APR-1981’? Yes, therefore the result is used.Let’s examine the first record for ADAMS. The decode expression evaluates to ‘12-JAN-1983’. The first comparisonexpression evaluates to ‘01-APR-1982’. Is ‘12-JAN-1983’ = ‘01-APR-1982’? No, therefore the result is not used. There isnot another comparison, so the default value is used.? How do I select fields from different tables based upon data?What if you need to select similar data from different tables. The traditional approach is to perform a union. Using theUSER_ views, we extract information about TABLE and INDEX segments. In this case, the USER_SEGMENTS view isaccessed twice. SELECT S.SEGMENT_NAME, TABLE SEGMENT_TYPE, T.LAST_ANALYZED FROM USER_SEGMENTS S, USER_TABLES T WHERE S.SEGMENT_NAME = T.TABLE_NAME UNION SELECT S.SEGMENT_NAME, INDEX SEGMENT_TYPE, T.LAST_ANALYZED FROM USER_SEGMENTS S, USER_INDEXES T WHERE S.SEGMENT_NAME = T.INDEX_NAME ORDER BY 1; SEGMENT_NAME SEGMENT_TYPE ANALYZE_DATE ------------------------------ ----------------- ------------ BONUS TABLE 06-DEC-2000 DEPT TABLE 06-DEC-2000 DUMMY TABLE EMP TABLE 06-DEC-2000 EMP_2 TABLE IX_DEPTNO INDEX 06-DEC-2000 IX_DNAME INDEX 06-DEC-2000 IX_ENAME INDEX 06-DEC-2000 SALGRADE TABLE 06-DEC-2000The less traditional approach is to perform a union. By using a DECODE with an outer join, the same result set is returned. Inthis case, the USER_SEGMENTS view is accessed only once.www.rmoug.org RMOUG Training Days 2002
  10. 10. SQL Scripting Sorcery Fink SELECT S.SEGMENT_NAME, S.SEGMENT_TYPE, DECODE(S.SEGMENT_TYPE, INDEX, I.LAST_ANALYZED, TABLE, T.LAST_ANALYZED) ANALYZE_DATE FROM USER_SEGMENTS S, USER_TABLES T, USER_INDEXES I WHERE S.SEGMENT_NAME = T.TABLE_NAME (+) AND S.SEGMENT_NAME = I.INDEX_NAME (+); SEGMENT_NAME SEGMENT_TYPE ANALYZE_DATE ------------------------------ ----------------- ------------ BONUS TABLE 06-DEC-2000 DEPT TABLE 06-DEC-2000 DUMMY TABLE EMP TABLE 06-DEC-2000 EMP_2 TABLE IX_DEPTNO INDEX 06-DEC-2000 IX_DNAME INDEX 06-DEC-2000 IX_ENAME INDEX 06-DEC-2000 SALGRADE TABLE 06-DEC-2000? How can I avoid a self-join?One of the common DBA scripts is to look at hit ratios using the V$SYSSTAT view.Is more efficient with small data sets (less than 1 million records). SELECT (1 - SUM(DECODE(name, physical reads, value,0)) / (SUM(DECODE(name, db block gets, value,0)) + (SUM(DECODE(name, consistent gets, value,0))))) * 100 "Read Hit Ratio" FROM v$sysstat; Read Hit Ratio -------------- 99.780491 SELECT (1 - a.value/(b.value + c.value)) * 100 "Read Hit Ratio" FROM v$sysstat a, v$sysstat b, v$sysstat c WHERE a.name = physical reads AND b.name = db block gets AND c.name = consistent gets; Read Hit Ratio -------------- 99.7805272? How can I create an interactive menu in SQL*Plus?sql_menu.sql set verify off pages 0 feed off accept table_choice prompt Enter Table (EMP/DEPT/SALGRADE/EXIT): set termout off spool run_script.sql select decode(UPPER(&table_choice), EMP, @select_emp, DEPT, @select_dept, SALGRADE, @select_salgrade, EXIT, @exit_sqlplus,www.rmoug.org RMOUG Training Days 2002
  11. 11. SQL Scripting Sorcery Fink @select_error) script_choice from dual; spool off @run_script.sqlselect_dept.sql set termout on select * from dept; @sql_menuselect_emp.sql set termout on select * from emp; @sql_menuselect_error.sql select Invalid Menu Choice from dual; @sql_menuselect_salgrade.sql set termout on select * from salgrade; @sql_menuexit_sqlplus.sql exitwww.rmoug.org RMOUG Training Days 2002