Array in procedure
Hi,
I have a procedure that will be receiving TEMPLATE_ID's has input parameter in a procedure. Now there can be more than one template Id passed into the procedure. What is the best way to handle this situation? Can I create some sort of array for an IN parameter in the procedure?
Please Advise,
Marc.
Like you would any other type except you define the type yourself...
Nested Table Type (some people call this "schema-level type" because you create it at the schema level using CREATE TYPE...):
CREATE TYPE collection_type AS TABLE OF VARCHAR2(4000);
CREATE PROCEDURE example_procedure( p_array IN collection_type ) IS
i PLS_INTEGER;
BEGIN
i := p_array.FIRST;
WHILE i IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(p_array(i));
i := p_array.NEXT(i);
END LOOP;
END;
BEGIN
example_procedure( collection_type( 'APPLE', 'ORANGE', 'TOASTER OVEN' ) );
END;
Packaged Associative Array Type (either in a dedicated package or as part of your actual package)
CREATE PACKAGE example_package AS
TYPE array_type IS TABLE OF VARCHAR2(32767)
INDEX BY PLS_INTEGER;
PROCEDURE procedure_name( p_array IN example_package.array_type );
END example_package;
/You can do the package body yourself, but here's an example of calling it...
DECLARE
v_array example_package.array_type;
BEGIN
v_array(1) := 'APPLE';
v_array(2) := 'ORANGE';
v_array(3) := 'TOASTER OVEN';
example_package.procedure_name(p_array => v_array);
END;
Packaged Nested Table Type
CREATE PACKAGE example_package AS
TYPE array_type IS TABLE OF VARCHAR2(32767);
PROCEDURE procedure_name( p_array IN example_package.array_type );
END example_package;
/You can do the package body yourself, but here's an example of calling it...
DECLARE
v_array example_package.array_type := example_package.array_type('APPLE', 'ORANGE', 'TOASTER OVEN');
BEGIN
example_package.procedure_name(p_array => v_array);
END;
/All typed freehand so there might be some syntax typos...
Regards
Similar Messages
-
How can i pass arrays in a procedure as IN parameter
for eg.
If I have a procedure which takes an input login id and a input status
procedure test(loginId IN varchar, status IN varchar)
-- the procedure does insert and update using the input login id and input status
Now, suppose i have a bunch of input login ids and a bunch of status, how can i pass the login id and status values as an array to the procedure instead of calling the procedure in a loop?This is best done using an object type and collection type, so you can make use of bulk SQL to perform the DML. I've given a short demo below:-
First your target table...
SQL> create table my_table ( id number, status varchar2(1) );
Table created.Now we create an object type ( this defines the record structure for your parameter ). We then create a nested table type (collection) based on this record structure:-
SQL> create type login_record_ot as object
2 ( id number
3 , status varchar2(1)
4 );
5 /
Type created.
SQL> create type login_records_ntt as table of login_record_ot;
2 /
Type created.Now a demo package with a procedure to insert the input collection into the target table. This uses the TABLE expression ( combined with CAST just in case you are on 8i )...
SQL> create package pkg as
2 procedure insert_records (
3 login_records_in in login_records_ntt
4 );
5 end pkg;
6 /
Package created.
SQL> create package body pkg as
2
3 procedure insert_records (
4 login_records_in in login_records_ntt
5 ) is
6 begin
7 insert into my_table ( id, status )
8 select x.id
9 , x.status
10 from table( cast( login_records_in as login_records_ntt )) x;
11 dbms_output.put_line( sql%rowcount || ' rows inserted.' );
12 end insert_records;
13
14 end pkg;
15 /
Package body created.Now to use it. I'll load a dummy variable with a collection of IDs/statuses and pass them to the pkg.insert_records procedure...
SQL> declare
2 some_records login_records_ntt := login_records_ntt(
3 login_record_ot( 1, 'X' ),
4 login_record_ot( 2, 'Y' ),
5 login_record_ot( 3, 'Z' ),
6 login_record_ot( 4, 'A' ),
7 login_record_ot( 5, 'B' )
8 );
9 begin
10 pkg.insert_records( some_records );
11 end;
12 /
5 rows inserted.
PL/SQL procedure successfully completed.
SQL>
SQL> select * from my_table;
ID S
1 X
2 Y
3 Z
4 A
5 BRegards
Adrian -
Passing array to Procedure in 8i
I am trying to pass array to a database procedure without any luck yet.
Error i get is unable to bind to specified type .
any suggestions are greatly appreciated i have been trying for 2 days without luck !!Oracle JDBC drivers support SQL Varray and Nested Table datatypes. To bind a array data, use OracleCallableStatement::setARRAY.
Thanks. -
How to see the output of associative array in procedure
Hi ,
I tried the following code
And confused about looking at the output of the associative array.
CREATE OR REPLACE PACKAGE test_pak1
AS
FUNCTION map_object (obj_typ_in VARCHAR2)
RETURN VARCHAR2;
CURSOR c_c1
IS
SELECT * FROM emp;
TYPE test_ttyp IS TABLE OF c_c1%ROWTYPE
INDEX BY PLS_INTEGER;
PROCEDURE search_obj (obj_type VARCHAR2);
END;
CREATE OR REPLACE PACKAGE BODY test_pak1
AS
FUNCTION map_object (obj_typ_in VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
dopl ('Hello');
RETURN abc;
END;
PROCEDURE search_obj (obj_type VARCHAR2)
IS
test_tab test_ttyp;
BEGIN
DOPL (test_tab);
end;
END;In the above code i want to see the output of the test_tab which is in the procedure search_obj.
could you please help me in this
ThanksHi ,
Though the table has the records , the associatve array declared on this table is showing 0 records..
Create or replace package test_pak1 as
FUNCTION map_object ( obj_typ_in VARCHAR2 ) RETURN VARCHAR2;
CURSOR c_c1
IS
SELECT *
FROM dept;
TYPE test_ttyp IS TABLE OF c_c1%ROWTYPE INDEX BY PLS_INTEGER;
procedure search_obj(obj_type varchar2);
end;
Create or replace package body test_pak1 as
FUNCTION map_object ( obj_typ_in VARCHAR2 ) RETURN VARCHAR2
IS
begin
dbms_output.put_line ('Hello');
return 'abc';
end;
procedure search_obj(obj_type varchar2) is
test_tab test_ttyp;
begin
DBMS_OUTPUT.put_line ('nested array count value'|| test_tab.COUNT);
FOR i IN 1 .. test_tab.COUNT LOOP
dbms_output.put_line( test_tab(i).deptno||' '|| test_tab(i).dname); end loop;
end;
end;
begin
test_pak1.search_obj('HYD');
end; Though the table has the records the count of the associative array is showing 0 records ... Why
Thanks -
can any one please tell me how to pass an dynamic array to a Procedure and get an dynamic array of values from Oracle.
Thanks,
PrasenjitPROCEDURE sp_error_report_summary(errorDate IN VARCHAR,
RESULT1 OUT Types.ref_cursor,
RESULT2 OUT Types.ref_cursor,
RESULT3 OUT Types.ref_cursor) IS
error_cursor Types.ref_cursor;
BEGIN
OPEN RESULT1 FOR
SELECT error_message,
site_name,
COUNT(*) COUNT_MSG
FROM error_report
WHERE error_date = errorDate
GROUP BY error_message,
site_name
ORDER BY site_name;
OPEN RESULT2 FOR
SELECT * FROM registration;
OPEN RESULT3 FOR
SELECT * FROM category;
END; -
Passing array as a argument in the Stored Procedure/Function
Hello Friends,
I need a help, i Want one stored proedure/Function which take array as a argument and return an array also.
and the size of array should not be fixed.
I don't want to use Varray because for this I have to specified its size first.
I think Associative arry will work( For dynamic size) but I am not able to run it .
Is Associative arry(Index by Pls_Integer) support JDBC?
If yes, plz give me some clue. I have found some information of associative array in this url
http://www.oracle.com/technology/oramag/oracle/07-jan/o17odp.html
But I am not able to run this package through SQL and also not able to connect it through JDBC.
Is there any other alternative solution?
Thanks & Regards,
manish KumarThis is my table structure :
SQL> desc jobs
Name Null? Type
JOB_ID NOT NULL VARCHAR2(10)
JOB_TITLE NOT NULL VARCHAR2(35)
MIN_SALARY NUMBER(6)
MAX_SALARY NUMBER(6)
My Requirement is, User will enter the above field value in the form of array. I need to store these value and after manupulating this I will return that value also.
Here I am using procedure just for testing purpuse.
In my case I will take one array argumentlike JOB_ID and after manupulating these data I will return that array value.
I am also not able to run this example through SQL.
Can U give me exact code for running this prog.
create or replace package associative_array as
-- define an associative array type for each column in the jobs table
type t_job_id is table of jobs.job_id%type index by pls_integer;
type t_job_title is table of jobs.job_title%type index by pls_integer;
type t_min_salary is table of jobs.min_salary%type index by pls_integer;
type t_max_salary is table of jobs.max_salary%type index by pls_integer;
-- define the procedure that will perform the array insert
procedure array_insert (p_job_id in t_job_id,
p_job_title in t_job_title,
p_min_salary in t_min_salary,
p_max_salary in t_max_salary);
end associative_array;
create or replace package body associative_array as
-- implement the procedure that will perform the array insert
procedure array_insert (p_job_id in t_job_id,
p_job_title in t_job_title,
p_min_salary in t_min_salary,
p_max_salary in t_max_salary) is
begin
forall i in p_job_id.first..p_job_id.last
insert into jobs (job_id,
job_title,
min_salary,
max_salary)
values (p_job_id(i),
p_job_title(i),
p_min_salary(i),
p_max_salary(i));
end array_insert;
end associative_array;
Regards,
manish Kumar -
Pass array to oracle stored procedure
I have such a problem: I have to pass array to stored procedure, so I declare type:
create type tNumberArray as table of number
and create procedure:
create or replace procedure proc_1 (in_param in tNumberArray) as
.... BODY OF PROCEDURE ...
when I call this procedure from C# like this:
int []pParam = new int[3] {1,2,3};
OracleCommand cmd = new OracleCommand("proc_1", dbConn);
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter param14 = new OracleParameter("param", OracleDbType.Decimal);
param14.Value = pParam;
param14.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
param14.Size = 3;
param14.Direction = ParameterDirection.Input;
cmd.Parameters.Add(param14);
cmd.ExecuteNonQuery();
an error occures. It say that there invalid number or type of parameters.
But when I declare both type and procedure in a package everything goes fine.
What is the matter? Did anybody have the same problem?Not I got next problem:
when I cannot pass parameter to stored procedure and get array fro it. In other words returning array from procedure and passing some input parameters to it does not word!
Does anybody know why it happens? -
Associative array type for each blob column in the table
i am using the code in given link
http://www.oracle.com/technology/oramag/oracle/07-jan/o17odp.html
i chnages that code like this
CREATE TABLE JOBS
JOB_ID VARCHAR2(10 BYTE),
JOB_TITLE VARCHAR2(35 BYTE),
MIN_SALARY NUMBER(6),
MAX_SALARY NUMBER(6),
JOBPIC BLOB
CREATE OR REPLACE PACKAGE associative_array
AS
-- define an associative array type for each column in the jobs table
TYPE t_job_id IS TABLE OF jobs.job_id%TYPE
INDEX BY PLS_INTEGER;
TYPE t_job_title IS TABLE OF jobs.job_title%TYPE
INDEX BY PLS_INTEGER;
TYPE t_min_salary IS TABLE OF jobs.min_salary%TYPE
INDEX BY PLS_INTEGER;
TYPE t_max_salary IS TABLE OF jobs.max_salary%TYPE
INDEX BY PLS_INTEGER;
TYPE t_jobpic IS TABLE OF jobs.jobpic%TYPE
INDEX BY PLS_INTEGER;
-- define the procedure that will perform the array insert
PROCEDURE array_insert (
p_job_id IN t_job_id,
p_job_title IN t_job_title,
p_min_salary IN t_min_salary,
p_max_salary IN t_max_salary,
p_jobpic IN t_jobpic
END associative_array;
CREATE OR REPLACE package body SHC_OLD.associative_array as
-- implement the procedure that will perform the array insert
procedure array_insert (p_job_id in t_job_id,
p_job_title in t_job_title,
p_min_salary in t_min_salary,
p_max_salary in t_max_salary,
P_JOBPIC IN T_JOBPIC
) is
begin
forall i in p_job_id.first..p_job_id.last
insert into jobs (job_id,
job_title,
min_salary,
max_salary,
JOBPIC
values (p_job_id(i),
p_job_title(i),
p_min_salary(i),
p_max_salary(i),
P_JOBPIC(i)
end array_insert;
end associative_array;
this procedure is called from .net. from .net sending blob is posiible or not.if yes howOk, that won't work...you need to generate an image tag and provide the contents of the blob column as the src for the image tag.
If you look at my blog entry -
http://jes.blogs.shellprompt.net/2007/05/18/apex-delivering-pages-in-3-seconds-or-less/
and download that Whitepaper that I talk about you will find an example of how to do what you want to do. Note the majority of that whitepaper is discussing other (quite advanced) topics, but there is a small part of it that shows how to display an image stored as a blob in a table. -
Stored procedure/function deployment failure PLS-00306
Hi there,
I'm using
Oracle 10g2 10.2.0.1.0 (with patch set 1 10.2.0.2.0)
ODE 10.2.0.2.20
ODP 10.2.0.2.21
VS 2005
I was able to deploy and run .NET procedure/function from within Visual Studio, but after reconfiguring tnsnames.org and listener.org a couple of times, I began to have this weird problem:
Whenever I deploy a stored procedure (the same one that I could deploy and run without any problem), the icon beside the name of the procedure in the tree list of Oracle Explorer becomes one that has a small "red light" at the corner. The options of "run", "run debug" and "step into" are disabled in the pop-up menu, and if I choose "compile" or "compile debug" from the menu, the "PLS-00306 wrong number or types of arguments in call to 'EXECUTEPROCEDURE'" error will show up -- the same error appears if I execute the procedure in SqlPlus.
Has anyone ever met this problem before?
Thanks so much ...This is my table structure :
SQL> desc jobs
Name Null? Type
JOB_ID NOT NULL VARCHAR2(10)
JOB_TITLE NOT NULL VARCHAR2(35)
MIN_SALARY NUMBER(6)
MAX_SALARY NUMBER(6)
My Requirement is, User will enter the above field value in the form of array. I need to store these value and after manupulating this I will return that value also.
Here I am using procedure just for testing purpuse.
In my case I will take one array argumentlike JOB_ID and after manupulating these data I will return that array value.
I am also not able to run this example through SQL.
Can U give me exact code for running this prog.
create or replace package associative_array as
-- define an associative array type for each column in the jobs table
type t_job_id is table of jobs.job_id%type index by pls_integer;
type t_job_title is table of jobs.job_title%type index by pls_integer;
type t_min_salary is table of jobs.min_salary%type index by pls_integer;
type t_max_salary is table of jobs.max_salary%type index by pls_integer;
-- define the procedure that will perform the array insert
procedure array_insert (p_job_id in t_job_id,
p_job_title in t_job_title,
p_min_salary in t_min_salary,
p_max_salary in t_max_salary);
end associative_array;
create or replace package body associative_array as
-- implement the procedure that will perform the array insert
procedure array_insert (p_job_id in t_job_id,
p_job_title in t_job_title,
p_min_salary in t_min_salary,
p_max_salary in t_max_salary) is
begin
forall i in p_job_id.first..p_job_id.last
insert into jobs (job_id,
job_title,
min_salary,
max_salary)
values (p_job_id(i),
p_job_title(i),
p_min_salary(i),
p_max_salary(i));
end array_insert;
end associative_array;
Regards,
manish Kumar -
Arrays as IN/OUT parameters to stored procs
I need the ability to pass Java arrays as input parameters and receive arrays as output parameters from stored procedures. I searched this forum for "array stored procedure" and came up with 9 posts dating back to April 30, 1999. In every one of these posts, people have asked how this can be done, and as yet there has not been any real solution provided. One messy solution is to add another stored proc that takes the array items as scalars and builds a PL/SQL table to pass to the original stored proc.
I am getting the impression that using arrays for IN/OUT parameters to/from stored procedures is not possible with JDK 1.1. Can it be done with JDK 1.2?
Isn't there anyone from Oracle that can provide an answer or solution?I've searched for a way of passing a rowtype to a stored
procedure or passing an array to a stored procedure.
The following example may have some pertinence. It was posted at
http://www.classicity.com/oracle/htdocs/forums/ClsyForumID124/6.h
tml#
I also think that it would be useful to know how best to pas a
ResultSet or equivalent to a Stored Procedure, if someone has
more information. The idea is to have symmetry between the way
data is retrieved from SP's (CURSORS) and supplied to SP's (???
ARRAY/CURSOR) ?
"[Example]Example of using JDBC with VARRAYS and REF CURSORs"
This example shows how to use JDBC with VARRAYS and REF
CURSORs.
It also shows use of the PreparedStatement and CallableStatement
methods.
The example does the follows:
1. selects from a table of VARRAYs
2. inserts into a table of VARRAYs
3. selects from a table of VARRAYs
4. calls stored procedure -- parameters <ref cursor, varray>
In order to test it, you will need to do two things first:
1) Create related tables and types first. The screipt is given
below.
2) Create a package that gets called from JAVA code. The script
is given below.
======================= Step 1 create tables etc. cute here
==================
-- Run this through SQL*PLUS
drop TABLE varray_table;
drop TYPE num_varray;
drop TABLE sec;
-- create the type
create TYPE num_varray as VARRAY(10) OF NUMBER(12, 2);
-- create the table
create TABLE varray_table (col1 num_varray);
-- create the sec table
create table sec (sec_id number(8) not null, sec_grp_id number
(8) not null,
company_id number(8) not null);
insert into sec values (1,200,11);
insert into sec values (2,1100,22);
insert into sec values (3,1300,33);
insert into sec values (4,1800,44);
==================== End of step
1===========================================
================== Step 2 create package
====================================
-- Run it through sql*plus
CREATE OR REPLACE PACKAGE packageA AS
type sctype is ref cursor return SEC%ROWTYPE;
procedure get_port_consensus(sc IN OUT sctype, arr IN
num_varray);
procedure test_port_consensus(sc IN OUT sctype);
END packageA;
CREATE OR REPLACE PACKAGE BODY packageA AS
procedure test_port_consensus(sc IN OUT sctype)
IS
testArr num_varray := num_varray(200, 1100, 1300, 1800);
BEGIN
get_port_consensus(sc, testArr);
END test_port_consensus;
procedure get_port_consensus(sc IN OUT sctype, arr IN num_varray)
IS
BEGIN
open sc for select * from sec
where sec_grp_id = arr(1)
or sec_grp_id = arr(2)
or sec_grp_id = arr(3)
or sec_grp_id = arr(4);
END get_port_consensus;
END packageA;
===================== End of step 2
===================================
============ JAVA code to test the whole thing
========================
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.oracore.Util;
import oracle.jdbc.driver.*;
import java.math.BigDecimal;
public class ArrayExample
public static void main (String args<>)
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver
// Connect to the database
// You need to put your database name after the @ sign in
// the connection URL.
// The example retrieves an varray of type "NUM_VARRAY",
// materializes the object as an object of type ARRAY.
// A new ARRAY is then inserted into the database.
Connection conn =
DriverManager.getConnection ("jdbc:oracle:oci8:@v81",
"scott", "tiger");
// It's faster when auto commit is off
conn.setAutoCommit (false);
// Create a Statement
Statement stmt = conn.createStatement ();
System.out.println("Querying varray_table");
ResultSet rs = stmt.executeQuery("SELECT * FROM varray_table");
showResultSet (rs);
// now insert a new row
// create a new ARRAY object
int elements<> = { 200, 1100, 1300, 1800 };
ArrayDescriptor desc = ArrayDescriptor.createDescriptor
("NUM_VARRAY",conn);
ARRAY newArray = new ARRAY(desc, conn, elements);
// prepare statement to be inserted and bind the num_varray type
System.out.println("PreparedStatement: Inserting into
varray_table");
PreparedStatement ps =
conn.prepareStatement ("insert into varray_table values (?)");
((OraclePreparedStatement)ps).setARRAY (1, newArray);
ps.execute ();
// query to view our newly inserted row
System.out.println("Querying varray_table again");
rs = stmt.executeQuery("SELECT * FROM varray_table");
showResultSet (rs);
// prepare a callable statement -- call the stored procedure
// passing <ref cursor in out, varray in>
System.out.println("CallableStatement: Calling Stored
Procedure");
OracleCallableStatement oraStmt1 =
(OracleCallableStatement)conn.prepareCall("{ call
packageA.get_port_consensus(?, ?) }");
oraStmt1.registerOutParameter(1, OracleTypes.CURSOR);
oraStmt1.setARRAY(2, newArray);
oraStmt1.execute();
rs = (ResultSet)oraStmt1.getObject(1);
// loop through the result set of the ref cursor and display
while (rs.next()) {
System.out.println(rs.getString("sec_grp_id"));
// Close all the resources
rs.close();
ps.close();
stmt.close();
oraStmt1.close();
conn.close();
public static void showResultSet (ResultSet rs)
throws SQLException
int line = 0;
while (rs.next())
line++;
System.out.println("Row "+line+" : ");
ARRAY array = ((OracleResultSet)rs).getARRAY (1);
System.out.println ("Array is of type "+array.getSQLTypeName());
System.out.println ("Array element is of type
code "+array.getBaseType());
System.out.println ("Array is of length "+array.length());
// get Array elements
BigDecimal<> values = (BigDecimal<>) array.getArray();
for (int i=0; i<values.length; i++)
BigDecimal value = (BigDecimal) values;
System.out.println(">> index "+i+" = "+value.intValue()); -
for rec in cur loop
dID := rec.update_id;
dTYPE := rec.update_type;
dNUMBER := rec.patch_number;
dDESC := rec.description;
dOLD := rec.old_db_version;
--search if patch is already installed, if Yes do nothing, else:
if dID = cID then
--now check version of DB
if cVER = version then
exec procedures(1);
end loop;
Error on line 10
DECLARE
var NUMBER;
version varchar(12);
installed boolean;
--var
ORA-06550: line 79, column 12:
PLS-00103: Encountered the symbol "PROCEDURES" when expecting one of the following:
:= . ( @ % ;
The symbol ":=" was substituted for "PROCEDURES" to continue.
ORA-06550: line 82, column 10:
PLS-00103: Encountered the symbol "LOOP" when expecting one of the following:
why that if statement make for loop broken?stil the same,. i will paste it there all :)
--testing procedure
set serveroutput on
create or replace procedure sampleP is
begin
dbms_output.put_line('write something');
end;
DECLARE
var NUMBER;
version varchar(12);
installed boolean;
--variables for reading from table in database - installed hotfix's
dID varchar(128);
dPACKAGE varchar(50);
dSEQUENCE varchar(50);
dNUMBER varchar(128);
dBASE varchar(256);
dNEW varchar(128);
--variables for reading from table in database - current hotfix
cID varchar(128);
cPACKAGE varchar(50);
dSEQUENCE varchar(50);
cNUMBER varchar(128);
cBASE varchar(256);
cNEW varchar(128);
--procedure's in array
--array for procedures
type p_procedures is table of varchar(100) index by pls_integer;
procedures p_procedures;
--array for hotfix , which version it have
--it must match with procedures array
type p_versions is table of varchar(100) index by pls_integer;
versions p_versions;
CURSOR cur IS SELECT update_id,update_type,patch_number,description,old_db_version FROM SWIZ_DB_UPDATE_HISTORY;
BEGIN
--set hotfix installed to NO = 0
--installed := 0;
--sampleP;
--execute procedures in field
--first fill it with correct names
procedures(1) := 'sampleP;';
procedures(2) := 'sampleP1;';
--then execute them in loop
for v_rec in procedures.first .. procedures.last loop
--execute immediate 'begin ' || procedures(v_rec) || ' end';
DBMS_OUTPUT.put(procedures(v_rec));
end loop;
-- get the current version of database
SELECT version INTO version FROM SWIZ_DB_VERSION;
--info about current hotfix
SELECT ID into cID from A_ID;
SELECT package_id into cTYPE from A_ID;
SELECT base_version into cNUMBER from A_ID;
SELECT description into cDESC from A_ID;
SELECT new_version into cNEW from A_ID;
SELECT seq into cSEQUENCE from A_ID;
--loop that go through history of db updates
for rec in cur loop
dID := rec.update_id;
dTYPE := rec.update_type;
dNUMBER := rec.patch_number;
dDESC := rec.description;
dOLD := rec.old_db_version;
--search if patch is already installed, if Yes do nothing, else:
-- if dID = cID then
--now check version of DB
-- if cVER = version then
execute immediate 'begin ' || procedures(1) || ' end;';
end loop;
--now check if hotfix can be installed to current version of DB
END; -
Hello and thanks in advance! I'm attempting to insert records into a temp table using a loop. I have many declared variables that will be used as criteria in the query. Since the variable are all named the same other than a ascending
numberic to the name, how would I get a variable in a loop to substitute the "numberic" part of the variables? I've created some sudo sql for what I'm trying to achieve:
Declare @Start1 as Date = '2014-01-01'
Declare @Start2 as Date = '2014-15-01'
Declare @Start3 as Date = '2014-18-01'
Declare @i INT = 1
WHILE @i < 20
SELECT .... INTO #MyTemp ...
WHERE OrderDate Like @Start + @i --This is the line I cant seem to get working.
SET @i = @i +1
END>>You have just described a 1950's file system using punch cards (also called unit records) writing to a scratch tape with Autocoder. You have no idea how to write SQL or program in a declarative language. We do not sure temporary files or loops. The
goal is to write one statement that does the task. We do not use local variables; we use expressions that compute their values.<<
What are you talking about or your point? I dont ever remember asking about temporary files. Who is the 'We' you keep referring to? why did you even bother posting with a negative and absolutely unhelpful reponse.
>>That is called an “array” in procedural programming and a repeated group in RDBMS. It also violated First Normal Form (1NF). <<
Wrong. I said that I created variables. I did not say I created an array. Also, you have no idea of what I was trying to accomplish.
>>
If you truly do not care about ever being a good programmer, you can kludge this 1950's code with dynamic SQL. But I will use you as a bad example in my books :( <<
I have no idea who you are and take offense at your entire post attempting to tear me down. Your arrogance and attitude appears to have grown with your forum points. I'm still confused as to why somebody with your so-called expertise
posted such an a$$#*%! comment. -
Hi,
I'm developing a simple app. which will iterate thru' a list of IP address(s) & its Port(s), use SocketMonitor to check the availability of the resource & set an icon (red/green) against each IP, based on its availability, in a DataGrid. When using SocketMonitor, i need to register a listener for the StatusEvent to monitor the availability. Looping isn't working as expected b'coz the StatusEvent is received much later than the looping process, which completes earlier. How can i best achieve this by reading each IP/Port from the list one by one & check that resource's availability?
tia
JK>>You have just described a 1950's file system using punch cards (also called unit records) writing to a scratch tape with Autocoder. You have no idea how to write SQL or program in a declarative language. We do not sure temporary files or loops. The
goal is to write one statement that does the task. We do not use local variables; we use expressions that compute their values.<<
What are you talking about or your point? I dont ever remember asking about temporary files. Who is the 'We' you keep referring to? why did you even bother posting with a negative and absolutely unhelpful reponse.
>>That is called an “array” in procedural programming and a repeated group in RDBMS. It also violated First Normal Form (1NF). <<
Wrong. I said that I created variables. I did not say I created an array. Also, you have no idea of what I was trying to accomplish.
>>
If you truly do not care about ever being a good programmer, you can kludge this 1950's code with dynamic SQL. But I will use you as a bad example in my books :( <<
I have no idea who you are and take offense at your entire post attempting to tear me down. Your arrogance and attitude appears to have grown with your forum points. I'm still confused as to why somebody with your so-called expertise
posted such an a$$#*%! comment. -
How to query uncommited transactions
Hi Does anyone know how to query Oracle database from SQL*Plus to view uncommitted transactions?
ThanksI noticed after I posted that I had used a package I found on the web called list that includes several useful functions. So in case someone wants it, here are the package and body:
***PACKAGE***
CREATE OR REPLACE PACKAGE list AUTHID CURRENT_USER IS
-- All of these functions and procedures have the following parameters:
-- list_in - A delimited list to be parsed.
-- delimiter - The delimiter to be used for parsing the list. Defaults
-- to a comma.
-- null_item - What to do with null items in the list. A null item is created
-- by consecutive occurances of the delimiter. Valid values are
-- 'KEEP' to allow items in the list to be null, or 'SKIP' to ignore
-- null items, ie. treat consecutive occurances of delimiters as a
-- single delimiter. The default is 'KEEP'.
-- delimiter_use - How the delimiter is to be interpreted. Valid values are
-- 'ANY' to treat the entire delimiter string as a single occurance
-- of a delimiter which must be matched exactly, or 'ANY' to treat
-- the delimiter string as a set of single character delimiters, any
-- of which is a delimiter. The default is 'ANY'.
-- Return the first item in a list.
FUNCTION head(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (head,WNDS,WNPS);
-- Return the remainder of a list after the first item and its delimiter.
FUNCTION tail(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (tail,WNDS,WNPS);
-- Return the nth item in a list.
-- The parameter, item_num, denotes which item to return.
FUNCTION item(
list_in IN VARCHAR2,
item_num IN INTEGER DEFAULT 1,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (item,WNDS);
-- Append an item to a list and return the new list.
-- The parameter, item_in, contains the new item to append.
FUNCTION append_item(
list_in IN VARCHAR2,
item_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (append_item,WNDS);
-- Return the number of items in a list.
FUNCTION num_items(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN INTEGER;
PRAGMA RESTRICT_REFERENCES (num_items,WNDS);
-- Search a list for an item, and give its location in the list,
-- or zero IF not found.
-- The parameter, item_in, gives the item to be found in the list.
FUNCTION in_list(
list_in IN VARCHAR2,
item_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN INTEGER;
PRAGMA RESTRICT_REFERENCES (in_list,WNDS);
-- Convert an array to a delimited list.
-- The array to be input is a DBMS_UTILITY.uncl_array so that
-- the LIST package is compatible with the comma_to_table and
-- table_to_comma built ins.
-- In this function, delimiter is always treated as a single
-- string.
FUNCTION array_to_list(
array_in IN DBMS_UTILITY.UNCL_ARRAY,
arrlen_in IN INTEGER,
delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (array_to_list,WNDS,WNPS);
-- Print a list using DBMS_OUTPUT.
PROCEDURE print_list(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY');
-- Convert a list to an array and return the array and its size.
-- This is a procedure because it returns more than one value.
-- The array to be returned is a DBMS_UTILITY.uncl_array so that
-- the LIST package is compatible with the comma_to_table and
-- table_to_comma built ins.
PROCEDURE list_to_array(
list_in IN VARCHAR2,
arrlen OUT BINARY_INTEGER,
array_out OUT DBMS_UTILITY.uncl_array,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY');
-- Sort a list
-- Null items are always skipped when sorting lists, since they would sort
-- to the end of the list anyway. CMPFNC is the name of a function to compare
-- two items. The default of '>' sorts in ascending order, '<' in descending order.
-- If you write your own function to be used for sorting, it must:
-- 1. Take two parameters of type VARCHAR2
-- 2. Return an INTEGER
-- 3. Return a negative number if the first item is to sort lower than
-- the second, a zero if they are to sort as if equal, or a positive
-- number if the first item is to sort higher than the second.
-- 4. Be executable by the user running the sort. Normal naming rules apply.
FUNCTION sort_list(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
cmpfnc IN VARCHAR2 DEFAULT '>',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (sort_list,WNDS);
end;
***END PACKAGE SPEC***
***BEGIN BODY***
CREATE OR REPLACE PACKAGE BODY list IS
current_list VARCHAR2(32760) DEFAULT '';
current_delim VARCHAR2(30) DEFAULT ',';
TYPE list_array IS TABLE OF VARCHAR2(2000)
INDEX BY BINARY_INTEGER;
current_array list_array;
current_arrlen BINARY_INTEGER DEFAULT 0;
current_null_item VARCHAR2(4) DEFAULT '';
current_delimiter_use VARCHAR2(3) DEFAULT '';
-- Find the first delimiter.
FUNCTION find_delimiter(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN BINARY_INTEGER IS
delimiter_loc BINARY_INTEGER;
BEGIN
IF upper(delimiter_use) = 'ALL' THEN
delimiter_loc := INSTR(list_in,delimiter);
ELSIF upper(delimiter_use) = 'ANY' THEN
delimiter_loc := INSTR(TRANSLATE(list_in,delimiter,ltrim(RPAD(' ',LENGTH(delimiter)+1,CHR(31)))),CHR(31));
END IF;
RETURN delimiter_loc;
END find_delimiter;
-- Return the first item in a list.
FUNCTION head(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2 IS
delimiter_loc BINARY_INTEGER;
BEGIN
delimiter_loc := find_delimiter(list_in,delimiter,null_item,delimiter_use);
IF delimiter_loc > 1 THEN
RETURN SUBSTR(list_in,1,delimiter_loc-1);
ELSIF delimiter_loc = 1 THEN
RETURN NULL;
ELSE
RETURN list_in;
END IF;
END head;
-- Return the remainder of a list after the first item and its delimiter.
FUNCTION tail(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2 IS
start_ch BINARY_INTEGER;
BEGIN
start_ch := find_delimiter(list_in,delimiter,null_item,delimiter_use);
IF start_ch = 0 THEN
RETURN NULL;
ELSE
IF upper(delimiter_use) = 'ALL' THEN
start_ch := start_ch + LENGTH(delimiter);
ELSE
start_ch := start_ch + 1;
END IF;
IF start_ch > LENGTH(list_in) THEN
RETURN NULL;
ELSE
RETURN SUBSTR(list_in,start_ch);
END IF;
END IF;
END tail;
-- Convert a list to an array.
PROCEDURE parse_list(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') IS
list_to_parse VARCHAR2(32760);
BEGIN
IF list_in = current_list AND
delimiter = current_delim AND
null_item = current_null_item AND
delimiter_use = current_delimiter_use THEN
NULL;
ELSE
current_list := list_in;
current_delim := delimiter;
current_null_item := upper(null_item);
current_delimiter_use := upper(delimiter_use);
list_to_parse := list_in;
current_arrlen := 0;
WHILE list_to_parse IS NOT NULL LOOP
IF current_null_item <> 'SKIP' OR
head(list_to_parse,delimiter,null_item,delimiter_use) IS NOT NULL THEN
current_arrlen := current_arrlen + 1;
current_array(current_arrlen) := SUBSTR(head(list_to_parse,delimiter,null_item,delimiter_use),1,2000);
END IF;
list_to_parse := tail(list_to_parse, delimiter,null_item,delimiter_use);
END LOOP;
END IF;
END parse_list;
-- Convert a list to an array and return the array and its size.
PROCEDURE list_to_array(
list_in IN VARCHAR2,
arrlen OUT BINARY_INTEGER,
array_out OUT DBMS_UTILITY.uncl_array,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') IS
BEGIN
parse_list(list_in,delimiter,null_item,delimiter_use);
arrlen := current_arrlen;
FOR i IN 1..arrlen LOOP
array_out(i) := SUBSTR(current_array(i),1,240);
END LOOP;
END list_to_array;
-- Print a list using DBMS_OUTPUT.
PROCEDURE print_list(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') IS
BEGIN
DBMS_OUTPUT.ENABLE(100000);
parse_list(list_in,delimiter,null_item,delimiter_use);
FOR i IN 1..current_arrlen LOOP
dbms_output.put_line(SUBSTR(current_array(i),1,240));
END LOOP;
END print_list;
-- Return the number of items in a list.
FUNCTION num_items(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN INTEGER is
BEGIN
parse_list(list_in,delimiter,null_item,delimiter_use);
RETURN current_arrlen;
END num_items;
-- Return the nth item in a list.
FUNCTION item(
list_in IN VARCHAR2,
item_num IN INTEGER DEFAULT 1,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2 is
BEGIN
parse_list(list_in,delimiter,null_item,delimiter_use);
IF item_num NOT BETWEEN 1 AND current_arrlen THEN
RETURN NULL;
ELSE
RETURN current_array(item_num);
END IF;
END item;
-- Append an item to a list and return the new list.
-- The parameter, item_in, contains the new item to append.
FUNCTION append_item(
list_in IN VARCHAR2,
item_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
BEGIN
IF list_in IS NULL THEN
RETURN item_in;
ELSE
RETURN list_in || delimiter || item_in;
END IF;
END append_item;
-- Search a list for an item, and give its location in the list,
-- or zero IF not found.
FUNCTION in_list(
list_in IN VARCHAR2,
item_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
null_item IN VARCHAR2 DEFAULT 'KEEP',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN INTEGER is
BEGIN
parse_list(list_in,delimiter,null_item,delimiter_use);
FOR item_num IN 1..current_arrlen LOOP
IF current_array(item_num) = item_in THEN
RETURN item_num;
END IF;
END LOOP;
RETURN 0;
END in_list;
-- Convert an array to a delimited list.
FUNCTION array_to_list(
array_in IN DBMS_UTILITY.UNCL_ARRAY,
arrlen_in IN INTEGER,
delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
list_out VARCHAR2(32760):= '';
BEGIN
FOR item_num IN 1 .. arrlen_in LOOP
EXIT WHEN LENGTH(list_out) +
LENGTH(array_in(item_num)) > 32760;
list_out := list_out||array_in(item_num);
IF item_num < arrlen_in THEN
list_out := list_out||delimiter;
END IF;
END LOOP;
RETURN list_out;
END array_to_list;
-- Sort a list
FUNCTION sort_list(
list_in IN VARCHAR2,
delimiter IN VARCHAR2 DEFAULT ',',
cmpFnc IN VARCHAR2 DEFAULT '>',
delimiter_use IN VARCHAR2 DEFAULT 'ANY') RETURN VARCHAR2 IS
temp_array list_array;
temp_len PLS_INTEGER := 0;
temp_item VARCHAR2(2000);
list_out VARCHAR2(32760);
PROCEDURE swap (
first_item IN OUT VARCHAR2,
second_item IN OUT VARCHAR2) IS
temp_item VARCHAR2(2000);
BEGIN
temp_item := first_item;
first_item := second_item;
second_item := temp_item;
END swap;
FUNCTION cmp (
first_item IN VARCHAR2,
second_item IN VARCHAR2,
cmpfnc IN VARCHAR2 DEFAULT '=') RETURN INTEGER IS
return_value INTEGER;
BEGIN
IF cmpfnc = '>' THEN
IF first_item < second_item THEN
return_value := -1;
ELSIF first_item = second_item THEN
return_value := 0;
ELSIF first_item > second_item THEN
return_value := 1;
END IF;
ELSIF cmpfnc = '<' THEN
IF first_item > second_item THEN
return_value := -1;
ELSIF first_item = second_item THEN
return_value := 0;
ELSIF first_item < second_item THEN
return_value := 1;
END IF;
ELSE
EXECUTE IMMEDIATE 'BEGIN :I := '||cmpfnc||'(:A,:B); END;'
USING OUT return_value, IN first_item, IN second_item;
END IF;
RETURN return_value;
END cmp;
BEGIN
parse_list(list_in,delimiter,'SKIP',delimiter_use);
FOR item_num IN 1..current_arrlen LOOP
temp_item := current_array(item_num);
FOR i IN 1..temp_len LOOP
IF cmp(temp_array(i),temp_item,cmpfnc) > 0 THEN
swap(temp_array(i),temp_item);
END IF;
END LOOP;
temp_len := temp_len + 1;
temp_array(temp_len) := temp_item;
END LOOP;
FOR item_num IN 1..temp_len LOOP
EXIT WHEN LENGTH(list_out) +
LENGTH(temp_array(item_num)) > 32760;
list_out := list_out||temp_array(item_num);
IF item_num < temp_len THEN
list_out := list_out||delimiter;
END IF;
END LOOP;
RETURN list_out;
END sort_list;
END;
*** END BODY***
Carl -
EA1: A few formatter issues
1. Alignment of AND keywords in select statement is wrong.
function get_segment_size(ownname in varchar2, segname in varchar2, segtype in varchar2) return number is indsize number(16);
begin
begin
select bytes
into indsize
from dba_segments
where owner = ownname
and segment_type = segtype
and segment_name = segname;
exception
when others then
raise;
end;
return indsize;
end;becomes
FUNCTION get_segment_size
ownname IN VARCHAR2,
segname IN VARCHAR2,
segtype IN VARCHAR2 )
RETURN NUMBER
IS
indsize NUMBER ( 16 ) ;
BEGIN
BEGIN
SELECT bytes
INTO indsize
FROM dba_segments
WHERE owner = ownname
AND segment_type = segtype
AND segment_name = segname;
EXCEPTION
WHEN OTHERS THEN
raise;
END;
RETURN indsize;
END;The ANDs are left aligned with the enclosing block rather than right aligned with the 'master keywords'.
2. NUMBER(?,?) and VARCHAR2(?) declarations have parentheses and sizes split over multiple lines.
index_list dba_indexes_tab;
rebuild_stmt varchar2(200);
end_time date;
start_size number(16, 0);
end_size number(16, 0);
batch app_support_batch_runs % rowtype;
batch_results resultset;becomes
index_list dba_indexes_tab;
rebuild_stmt VARCHAR2
200
end_time DATE;
start_size NUMBER
16, 0
end_size NUMBER
16, 0
batch app_support_batch_runs % rowtype;
batch_results resultset;3. Some array subscripted expressions have their parentheses split across multiple lines.
end_time := sysdate;
batch_results := resultset();
batch_results.extend;
batch_results(batch_results.last).asjr_result_type := 'ELAPSED_TIME';
batch_results(batch_results.last).asjr_result_key := 'ALL';
batch_results(batch_results.last).asjr_result_value :=((end_time -batch.asbr_component_start_time) *(24 *60 *60));becomes
end_time := sysdate;
batch_results := resultset
batch_results.extend;
batch_results
batch_results.last
.asjr_result_type := 'ELAPSED_TIME';
batch_results
batch_results.last
.asjr_result_key := 'ALL';
batch_results
batch_results.last
.asjr_result_value :=
( end_time -batch.asbr_component_start_time ) * ( 24 *60 *60 )
;Another similar block later in the same package is left as single lines.
4. 3 seems to apply generally to expressions involving parentheses - array subscripts, procedure calls. Some are done properly, others are spread across multiple lines.
5. Various keywords are not recognised by the formatter, although they are by the syntax highlighter. (They are in bold, but not upper case)
raise
extend
last
immediate
6. There doesn't seem to be away to format the current selection rather than the whole buffer (in the PL/SQL editor)Given this -
select prej.asbr_component_name,
prej.asbr_batch_start_time,
etime.asjr_result_value Elapsed,
prer.asjr_result_value Size_before,
postr.asjr_result_value Size_after,
prer.asjr_result_value -postr.asjr_result_value Shrinkage
from app_support_batch_runs prej
inner join app_support_job_result prer on prer.asjr_asbr_id = prej.asbr_id
inner join app_support_job_result postr on postr.asjr_asbr_id = prej.asbr_id
inner join app_support_job_result etime on etime.asjr_asbr_id = prej.asbr_id
where prer.asjr_result_type = 'START_SIZE'
and postr.asjr_result_type = 'END_SIZE'
and etime.asjr_result_type = 'ELAPSED_TIME'
order by prej.asbr_component_name;with [em]indent AND/OR[em] unchecked, you get this.
SELECT prej.asbr_component_name ,
prej.asbr_batch_start_time ,
etime.asjr_result_value Elapsed ,
prer.asjr_result_value Size_before,
postr.asjr_result_value Size_after,
prer.asjr_result_value -postr.asjr_result_value Shrinkage
FROM app_support_batch_runs prej
INNER JOIN app_support_job_result prer
ON prer.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result postr
ON postr.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result etime
ON etime.asjr_asbr_id = prej.asbr_id
WHERE prer.asjr_result_type = 'START_SIZE'
AND postr.asjr_result_type = 'END_SIZE'
AND etime.asjr_result_type = 'ELAPSED_TIME'
ORDER BY prej.asbr_component_name;The problems with this are.
1) The sql statement as a whole is indented (ie the select keyword)
2) Despite 1), INNER, AND and ORDER are NOT indented at all whereas the should be at least level with the select. I suspect the problem may be that it is trying to right align 'INNER JOIN' and 'ORDER BY' with the SELECT-FROM-WHERE.I thing the ON of the join clauses is right aligned.
3) The column list isn't right. The columns should be left aligned and positioned one space to the right of the select keyword ( or at a pinch on a new line, indented from the select keyword by 2 columns)
with [em]indent AND/OR[em] checked, you get this.
SELECT prej.asbr_component_name ,
prej.asbr_batch_start_time ,
etime.asjr_result_value Elapsed ,
prer.asjr_result_value Size_before,
postr.asjr_result_value Size_after,
prer.asjr_result_value -postr.asjr_result_value Shrinkage
FROM app_support_batch_runs prej
INNER JOIN app_support_job_result prer
ON prer.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result postr
ON postr.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result etime
ON etime.asjr_asbr_id = prej.asbr_id
WHERE prer.asjr_result_type = 'START_SIZE'
AND postr.asjr_result_type = 'END_SIZE'
AND etime.asjr_result_type = 'ELAPSED_TIME'
ORDER BY prej.asbr_component_name;This is better but still has the problems with right-alignment.
With [em]Right-align master keywords[em] unchecked...
SELECT prej.asbr_component_name ,
prej.asbr_batch_start_time ,
etime.asjr_result_value Elapsed ,
prer.asjr_result_value Size_before,
postr.asjr_result_value Size_after,
prer.asjr_result_value -postr.asjr_result_value Shrinkage
FROM app_support_batch_runs prej
INNER JOIN app_support_job_result prer
ON prer.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result postr
ON postr.asjr_asbr_id = prej.asbr_id
INNER JOIN app_support_job_result etime
ON etime.asjr_asbr_id = prej.asbr_id
WHERE prer.asjr_result_type = 'START_SIZE'
AND postr.asjr_result_type = 'END_SIZE'
AND etime.asjr_result_type = 'ELAPSED_TIME'
ORDER BY prej.asbr_component_name;IMO This is best but I would like ON indented with respect to the INNER JOIN it belongs to.
So in terms of this sql statement, I think the only bug is the alignment of columns. The right alignment option doesn't work very well for longer 'keywords' (mainly the new-fangled sql-92 stuff). Perhaps a redefinition of what constitutes a master keyword would do better.
Maybe you are looking for
-
On OXS 10.8.2, difference between Quicktime and Quicktime 7 Pro ?
I just bought Quicktime 7 Pro however having a hardtime activating and getting it to work. Before buying it, I noticed the default install of OSX 10.8.2 had a Quicktime player. However, to get Quciktime 7 Pro, I read somewhere that I needed to instal
-
Fact Design , Any Aggragation ?
Hi , this is my Fact Table | ProjectID | ProjectSeq | PlanPercentYearly | month | PlanPercentMonthly | | | | | | | | 1 | 1 | 100 | 1 | 10 | | 1 | 1 | 100 | 1 | 10 | | 1 | 1 | 100 | 1 | 5 | | 1 | 2 | 100 | 3 | 20 | | 1 | 2 | 100 | 5 | 10 | | 1 | 2 | 1
-
How to distinguish the PRs triggered by the Project
Dear all expert, could you help me on the following issue? i create a project in CJ20N, i use internal activity and external activity. the materials to be procured are assgined to the internal activity, i release the project, run project MRP and the
-
Spry Master Data Region - Horizontal
I'm using the following tutorial to create navigation for my site: Spry framework for Ajax http://www.adobe.com/designcenter/video_workshop/index.html?id=vid0166 In this example the XML data is listed vertically. Is there a way for the data to be dis
-
How to download and convert RTF/DOC file in DMS into PDF file
Hello. We're on ECC6.0. We have a requirement to get the *.doc or *.rtf file checked in DMS, convert it to pdf format and download it as *.pdf file. The document data is stored in DRAO-ORBLK (LRAW data type). Has anyone programmatically done this? Wh