Possible to do variable number of REPLACE in SQL?
Hello. Using Oracle 10G, R2
Wondering if it is possible to do a variable number of REPLACE() entirely in SQL in a view.
input_table.text_column = This (b)is(/b) some (i)text(/i) with (u)formatting(/u) codes
Note: Using ( and ) to represent < and >
rows in format_codes_table:
(b)
(/b)
(i)
(/i)
(u)
(/u)
(p)
(/p)
etc. (The number of format_codes is not fixed)
Desired output: This is some text with formatting codes
This could be done with a user-defined function and then use that function in a SQL:
create or replace function remove_format_codes(input_p IN varchar2)
return varchar2
v_output varchar2(2000);
is
begin
v_output := input_p;
for r1 in (select format_code from format_codes_table)
loop
v_output := replace(v_output, r1.format_code);
end loop;
return v_output;
end;
create or replace view unformatted_output_vw
as
select remove_format_codes(input_table.text_column) as unformatted_output
from input_table
/I tried this SQL:
select replace(input_table.text_column, format_codes_table.format_code) as unformatted_output
from input_table
,format_codes_table
/But it only replaces one format code at a time, and it is not recursive so the output is like this:
This is(/b) some (i)text(/i) with (u)formatting(/u) codes
This (b)is some (i)text(/i) with (u)formatting(/u) codes
This (b)is(/b) some text(/i) with (u)formatting(/u) codes
This (b)is(/b) some (i)text with (u)formatting(/u) codes
etc.
I've google'd Oracle recursive sql, looked at CONNECT BY, LEAD, LAG, MODEL, and I've also looked at a
Tom Kyte example for varying in lists (http://tkyte.blogspot.com/2006/06/varying-in-lists.html),
but I can't seem to find a way to replicate the loop in my user-defined function in SQL.
Anyone think this is possible in SQL? If yes, any hints?
Thanks
Hi,
Regular expressions (introduced in Oracle 10) are great for this:
SELECT REGEXP_REPLACE ( text_column
, '<' || -- left angle-bracket
'/?' || -- optional slash
'[bipu]' || -- any one of these characters
'>' -- right angle-bracket
) AS no_tag_text
FROM input_table
;You had some good ideas: recursive subqueries (new in Oracle 11.2), CONNECT BY and MODEL could also do this job, but not nearly as easily.
In case you're interested, the following thread uses MODEL to do nested REPLACEs:
SQL Query
Edited by: Frank Kulash on May 13, 2010 4:08 PM
Edited by: Frank Kulash on May 17, 2010 1:02 PM
Fixed link
Similar Messages
-
Help with removing a variable number using "find and replace"
Hey, I have to remove a variable number from a large number of documents.
How would I do this using "find and replace"
<text><![CDATA[Coloured 250]]></text>
250 is an example of the variable number that I will need to remove so it looks like this:
<text><![CDATA[Coloured]]></text>
Note: the text "coloured" is subject to change also.
ThanksThat's a possibilitly I'll explore. Thanks for the alternate perspective!
(5 minutes later)
Oh well, it was a good thought.
Unfortunately each line of raw original text may contain from 1 to 4 lines of final text. In other words there is no consistency in the number of backslashes (hard returns) in each line of original text, and thus, when backslashes are converted to commas, no consistency in the number of data elements in each data set.
Sadly PS variables will not handle finding a source text line that does not have data for 4 variables. So I either have to go back and add enough commas on each short line to make four individual data elements for each data set... or I simply deal with the hard returns within Photoshop.
I think I've reached the limit of automation on this process. -
Possible to use process substitution a variable number of times?
Hello Archers,
I have a script like so:
#! /bin/bash
( readlink /proc/$$/fd/0 | grep -q "^pipe:" ) || ( file $(readlink /proc/$$/fd/0) | grep -q "character special" )
cat | tee >(awk 'NR % 2 == 0') >(awk '(NR+1) % 2 == 0')
Well, it's pretty trivial at the moment, but the underlying goal is to split the input, so it can be processed in parallel on multiple cores. If I understand correctly, the above code will split the input across exactly two cores. Does there exist some way to put the process substitution (i.e. ">(awk ' ... ')") in a loop?
Before trying to increase the number of cores, I first tried to see whether I could loop just two times with,
cat | tee $(for i in 1 2; do >(awk -vn="$i" '(NR + $n) % 2 == 0'); done)
but that didn't work.
It also occurred to me that maybe I'm presenting an X-Y problem. I did also consider using the split command, but as far as I can tell, it will only dump its output to files; it's no good for piping or process substitution. Any other ideas that would avoid needing to tee across a variable number of process substitutions?
Naturally, I tried a little Googlemancy, but only came up with answers to newbie questions, or tutorials aimed at newbies.
Thank you for your consideration.
Last edited by /dev/zero (2012-03-26 07:16:25)Or if you want to avoid named pipes, since during development they tend to create lots of files, and the script has to clean them up afterwards, take a look at the 'coproc' feature bash has since version 4
Though, remember that 'man bash' under BUGS says, there may only be one active coproc at a time.
According to this it's not really such a big deal though.
And it won't kill the started coprocesses or anything if you start another process...
Here's a sample session: (the spaces are important btw. )
wry:~/ $ bash [19:02:43]
wry@blubmb:~$ coproc c1 ( cat )
[1] 4129
wry@blubmb:~$ coproc c2 ( cat )
bash: warning: execute_coproc: coproc [4129:c1] still exists
[2] 4130
wry@blubmb:~$ echo $c1_PID $c2_PID -- ${c1[@]} ${c2[@]}
4129 4130 -- 63 60 62 58
wry@blubmb:~$ echo aaac1 >&${c1[1]}
wry@blubmb:~$ echo bbbc2 >&${c2[1]}
wry@blubmb:~$ read -u ${c1[0]} line1
wry@blubmb:~$ read -u ${c2[0]} line2
wry@blubmb:~$ echo $line1 and $line2
aaac1 and bbbc2
wry@blubmb:~$ kill $c1_PID $c2_PID
wry@blubmb:~$
[1]- Terminated coproc c1 ( cat )
[2]+ Terminated coproc c2 ( cat )
wry@blubmb:~$ exit
exit
Just keep in mind that the filedescriptors you get for a coproc won't be available in subshells you execute with &
Eg. you cannot do
coproc X
( use X ) &
Links: http://wiki.bash-hackers.org/syntax/keywords/coproc -
Can we write function with variable number of argument
Hi
Can anybody tell that can we pass variable number of arguments to a function in oracle 10gR2.
As in function decode we can pass variable no. of arguments upto 255 arguments, similarly can we creat a function which accept any no. of variables.I'm not sure that this is what you were asking about, but depending on the logic you want to implement, you can declare the maximum possible number of parameters to your function, give them default values, and then pass to your func as many parameters as you want:
SQL> create or replace function test(p_a number:=null, p_b number:=null) return varchar2 is
2 Result varchar2(100);
3 begin
4 result:='a='||p_a||', b='||p_b;
5 return(Result);
6 end test;
7 /
Function created
SQL> select test() from dual;
TEST()
a=, b=
SQL> select test(1) from dual;
TEST(1)
a=1, b=
SQL> select test(1,2) from dual;
TEST(1,2)
a=1, b=2
SQL> drop function test;
Function dropped
SQL> -
How to feed a query using a variable defined as Replacement Path-Query
Scenario description : BI NetW 2004S - InfoCube with the following characteristics Customer, OrderDate, OrderYear and the following KeyFigure Number of Pieces.
Objective: I need a query "QB" that shows how many pieces a set of customers has ordered in the year 2008. The set of customers is defined as all customers that in the previous years (the user can select one or more years) have ordered more than 500 pieces within the same year.
Implementation: In general terms the idea is to build a query "QB" with the characteristic "Customer" that is restricted (filtered) using a variable that is fed by another query "QA" (Replacement Path-Query).
In order to have the selection of customers that for each of previous years (2007, 2006, 2005,...) have ordered more than 500 pieces, in the query "QA":
- I put OrderYear as filter and defined a variable in order to ask the user which year/s he wants to analyse to define the selection
- I put Customer and OrderYear in row
- I put the KeyFigure Number of Pieces in column
- I've defined the following condition: Number of Pieces > 500 with the option Caracteristic Assignment = All Characteristics in the Drilldown Indipendently
Now if I run the query "QA" it works correctly showing me all customers that in the selected years have ordered more than 500 pieces within of the same year.
If I run the query "QB" it shows a correct result only if I enter only one year (for example 2006) in the OrderYear field (coming from the query "QA"); if I enter more than one year (for example 2006 and 2007) the selection of customers showed is not the same defined by the first query "QB": I was expecting to see all customers defined from the first query less all customers that have no ordered any piece in 2008.
Questions
1) Why is query "QA" working on a different selection of customers when the user selects more than one year?
2) Cosidering the scenario and the objective described above do you have any other idea?
Thanks
Ciao
RobertoHi Christophe,
it's ok for me if I consider the customer only once in the final selection of customers that feeds the final query, this is my objective.
However as test I've created 2 "input" queries, one related to 2006 and one related to 2007, and then in my destination query I've tried to restrict the customer using 2 variables of type replacement path-query (one attached to the 2006 query and one attached to the 2007 query). Unfortunately when I try to check and save the destination query, Query Designer tells me it is not possible to restrict the characteristic in this way.
Could you please describe me steps you run in to order to restrict a characteristic using more than one variable of type replacement path-query?
Thank you in advance for your answer.
Ciao,
Roberto -
UiXML tables - variable number of columns?
I'm trying to define a <table> in a UIX page which will be generated from a set of parameters. This set of parameters will result in a varying number of columns so I'm looking at providing a DataObjectList which has DataObjects with keys for each of the columns attributes (header text, name of control, value of control etc.). I want to do something similar to <contents data:childData=...> on the <table> contents but this doesn't seem to work. It seems that <table> needs you to know how many columns will be present - is that so or is there some way I can do this?
Cheers
IanIan,
That is correct, the uiMXL <table> element cannot currently support
a variable number of columns (using something akin to the
childData support in other contexts). But there are two approaches
to get what you want.
If you know the range of possible columns, then you can add a <column>
element for each possible column in the <table>'s contents and then
databind the rendered flag of the column element to hide/show the
column as necessary.
However, the real solution to your scenario, where the number of columns
is completely unknown when you're designing the page, is our canonical
example of a time you should write Java code for a portion of your page.
Specifically, you can use the XML <include> element to refer to a
DataProvider that will programatically create a TableBean. This
technique is discussed in the Dynamic Structure for UIX pages
portion of the UIX Developer's Guide. -
Procedure with variable number of columns
Hi, I have a procedure that looks like this:
PROCEDURE PROC(p_cursor OUT sys_refcursor)
And in the procedure, I build up QUERY dynamically and the number of columns varies at runtime.
At the end I do
OPEN p_cursor for QUERY
Then to call this, I'm doing
call PROC(?)
My question is, how would I go about running the query from this procedure, then adding rows or modifying the existing results, then returning the modified data?
What I want to do is add a new row based on some condition, so I still need to return a variable number of columns, but I need to modify the results before I return them.
Is there any way of doing this? I need to do some calculations on the columns (the variable columns), create a new row, insert into result set, and return this new result set.A sys_refcursor is ideally suited to pass back to a front end gui like .NET or Java which can then use that cursor to retrieve the data.
In PL/SQL there is no point in using a sys_refcursor unless you know, at design/compile time what the returned columns are going to be.
If the resultant columns are dynamic, then you have no choice but to use the DBMS_SQL package, where you can parse and execute any SQL statement you like and then use the DBMS_SQL package to describe what the resultant columns are and how many there are. From that you can reference the columns by position rather than by name.
e.g.
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_rowcount NUMBER := 0;
BEGIN
-- create a cursor
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement into the cursor
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- execute the cursor
d := DBMS_SQL.EXECUTE(c);
-- Describe the columns returned by the SQL statement
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- Bind local return variables to the various columns based on their types
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); -- Number
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); -- Date
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Any other type return as varchar2
END CASE;
END LOOP;
-- Display what columns are being returned...
DBMS_OUTPUT.PUT_LINE('-- Columns --');
FOR j in 1..col_cnt
LOOP
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
else 'Other' end);
END LOOP;
DBMS_OUTPUT.PUT_LINE('-------------');
-- This part outputs the DATA
LOOP
-- Fetch a row of data through the cursor
v_ret := DBMS_SQL.FETCH_ROWS(c);
-- Exit when no more rows
EXIT WHEN v_ret = 0;
v_rowcount := v_rowcount + 1;
DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
DBMS_OUTPUT.PUT_LINE('--------------');
-- Fetch the value of each column from the row
FOR j in 1..col_cnt
LOOP
-- Fetch each column into the correct data type based on the description of the column
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------');
END LOOP;
-- Close the cursor now we have finished with it
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
DEPTNO - NUMBER
SAL - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
DEPTNO : 10
SAL : 2450
Row: 2
EMPNO : 7839
ENAME : KING
DEPTNO : 10
SAL : 5000
Row: 3
EMPNO : 7934
ENAME : MILLER
DEPTNO : 10
SAL : 1300
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
JOB - VARCHAR2
MGR - NUMBER
HIREDATE - DATE
SAL - NUMBER
COMM - NUMBER
DEPTNO - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
JOB : MANAGER
MGR : 7839
HIREDATE : 09/06/1981 00:00:00
SAL : 2450
COMM :
DEPTNO : 10
Row: 2
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
MGR :
HIREDATE : 17/11/1981 00:00:00
SAL : 5000
COMM :
DEPTNO : 10
Row: 3
EMPNO : 7934
ENAME : MILLER
JOB : CLERK
MGR : 7782
HIREDATE : 23/01/1982 00:00:00
SAL : 1300
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept where deptno = 10');
-- Columns --
DEPTNO - NUMBER
DNAME - VARCHAR2
LOC - VARCHAR2
Row: 1
DEPTNO : 10
DNAME : ACCOUNTING
LOC : NEW YORK
PL/SQL procedure successfully completed.
SQL>In 11g, you can create a sys_refcursor and then the DBMS_SQL package allows you to convert that refcursor into a DBMS_SQL cursor so that you can get the description of the results and do the same. This isn't available prior to 11g though.
However_ before any of that, you should really ask yourself if there is a real need to dynamically be creating queries. There is rarely any real need to do that and if you're finding it's common in your application then this is often a sign of poor design or poorly defined business requirements (leaving the technical side to try and be "flexible" and hence leading to unmaintainable code etc.). -
Labeling Variable Number of Plots on a Graph?
I'm loading up an unknown number of files and graphing them. Since it can get a bit confusing, I'd like to be able to take a portion of the file name and label each plot on my graph. Since there is a variable number of graphs, I can't seem to work around how to wire the property node. There are several other things I'd like to do with the graph, but dont know if its possible or not such as having a label pop up if your cursor is over a plot.
You are going to have to embed the reference node for the graph into a for-loop like the attached example. File names or portions thereof are built as strings and then added into the property node Plot>>Plot Name.
I'm not sure about how to get a label to pop up if you are over the plot. You might be able to do it with some cursors and associated code.
Attachments:
Graph-Names.vi 20 KB -
Variable number of document info record parameters
Hi guys,
I have a question about adding additional information to document info record.
The situation is following:
Our customer wants us to link original purchase order (PDF file) with it's document info record in SAP. The document itself is stored in another document management system and we have succeeded in linking this object with it's document info record in SAP.
He also wants to have some description data stored in document info record (date, description, name, etc). One odd requirement is copying information about cost centers and costs per each cost center from fields in document management system to some fields in document info record.
The problem is that each purchase order can have various number of cost centers and costs per each cost center!
So, is there any possibility to define some fields in document info record to which I can store variable number of parameters (for example in one case 3 fields, and maybe in another case 1 field)?
Any kind of information will be valuable for me!
Thanks for help!Hi,
But my next question is how can I know how much cost centers will be for some document? If I need to define number of cost centers in advance, then this solution is not very flexible. The best solution would be if I could add values to classification flexibly (for example: one time 3 values and the other time 1 value).
:-Check box additional values in values tab of char. that will allow to enter flexible number of values any time
The other question is about values of parameters. For each cost center I need to enter two values (cost center number, and costs for that cost center). So, for each cost center I need to add 2 values. Is that possible using classification?
:-Create classification with chara. cost center, cost center value and check box additional values as above that will allow you to add values for cost center and cost center value.
Anirudh. -
Variable number of arguments in procedure PL/SQL
Hello everyone,
I have a "simple" question : can a procedure PL/SQL take a variable number of arguments ?
In my case, the procedure is called by the submit button of a form, and the form has variable number of inputs...
Thanks you !862447 wrote:
I have a "simple" question : can a procedure PL/SQL take a variable number of arguments ?No. Not in the style of Pascal and C/C++. E.g. int printf( char * format, … ) in C using va_list.
In my case, the procedure is called by the submit button of a form, and the form has variable number of inputs...There are a couple of merhods.
Code a fixed number of parameters in the procedure signature. Assign defaults to these. The caller can now select which parameters from the fixed list to use and which not.
Create a structure. For example, having a 100 parameters in a signature is something I will call plain stupidity. This creates usability issues, maintenance issues and even performance issues. And debugging will be a nightmare. So instead create a structure (aka record in the PL/SQL language or an object using the SQL language) - where this structure describes (in a structured and logical way) the list of parameters.
Neither of these method however allows the caller to pass a variable number parameters - the parameter signature is fixed. It has a fixed number of defined parameters.
So the only way to simulate a variable parameter signature is to use a collection. The collection itself is of course a single parameter passed. But it can have 0 elements. It can have a 1000 elements. And similar to a va_list in C/C++, the procedure can iterate through the data passed via the parameter by the caller.
Simple example:
//-- define the collection type, e.g. a collection of strings
create or replace type TStrings is table of varchar2(4000);The procedure's signature:
--// passing by referencing and not value should be considered
create or replace procedure FooProc( param TStrings ) is ..And to call this procedure with variable parameters:
--// calling it with 2 param value
FooProc( TString('123','testing') );
--// calling it with 5 param values
FooProc( TString('p1','p2','p3','p4','p5') ); -
How to generate report with dynamic variable number of columns?
How to generate report with dynamic variable number of columns?
I need to generate a report with varying column names (state names) as follows:
SELECT AK, AL, AR,... FROM States ;
I get these column names from the result of another query.
In order to clarify my question, Please consider following table:
CREATE TABLE TIME_PERIODS (
PERIOD VARCHAR2 (50) PRIMARY KEY
CREATE TABLE STATE_INCOME (
NAME VARCHAR2 (2),
PERIOD VARCHAR2 (50) REFERENCES TIME_PERIODS (PERIOD) ,
INCOME NUMBER (12, 2)
I like to generate a report as follows:
AK CA DE FL ...
PERIOD1 1222.23 2423.20 232.33 345.21
PERIOD2
PERIOD3
Total 433242.23 56744.34 8872.21 2324.23 ...
The TIME_PERIODS.Period and State.Name could change dynamically.
So I can't specify the state name in Select query like
SELECT AK, AL, AR,... FROM
What is the best way to generate this report?SQL> -- test tables and test data:
SQL> CREATE TABLE states
2 (state VARCHAR2 (2))
3 /
Table created.
SQL> INSERT INTO states
2 VALUES ('AK')
3 /
1 row created.
SQL> INSERT INTO states
2 VALUES ('AL')
3 /
1 row created.
SQL> INSERT INTO states
2 VALUES ('AR')
3 /
1 row created.
SQL> INSERT INTO states
2 VALUES ('CA')
3 /
1 row created.
SQL> INSERT INTO states
2 VALUES ('DE')
3 /
1 row created.
SQL> INSERT INTO states
2 VALUES ('FL')
3 /
1 row created.
SQL> CREATE TABLE TIME_PERIODS
2 (PERIOD VARCHAR2 (50) PRIMARY KEY)
3 /
Table created.
SQL> INSERT INTO time_periods
2 VALUES ('PERIOD1')
3 /
1 row created.
SQL> INSERT INTO time_periods
2 VALUES ('PERIOD2')
3 /
1 row created.
SQL> INSERT INTO time_periods
2 VALUES ('PERIOD3')
3 /
1 row created.
SQL> INSERT INTO time_periods
2 VALUES ('PERIOD4')
3 /
1 row created.
SQL> CREATE TABLE STATE_INCOME
2 (NAME VARCHAR2 (2),
3 PERIOD VARCHAR2 (50) REFERENCES TIME_PERIODS (PERIOD),
4 INCOME NUMBER (12, 2))
5 /
Table created.
SQL> INSERT INTO state_income
2 VALUES ('AK', 'PERIOD1', 1222.23)
3 /
1 row created.
SQL> INSERT INTO state_income
2 VALUES ('CA', 'PERIOD1', 2423.20)
3 /
1 row created.
SQL> INSERT INTO state_income
2 VALUES ('DE', 'PERIOD1', 232.33)
3 /
1 row created.
SQL> INSERT INTO state_income
2 VALUES ('FL', 'PERIOD1', 345.21)
3 /
1 row created.
SQL> -- the basic query:
SQL> SELECT SUBSTR (time_periods.period, 1, 10) period,
2 SUM (DECODE (name, 'AK', income)) "AK",
3 SUM (DECODE (name, 'CA', income)) "CA",
4 SUM (DECODE (name, 'DE', income)) "DE",
5 SUM (DECODE (name, 'FL', income)) "FL"
6 FROM state_income, time_periods
7 WHERE time_periods.period = state_income.period (+)
8 AND time_periods.period IN ('PERIOD1','PERIOD2','PERIOD3')
9 GROUP BY ROLLUP (time_periods.period)
10 /
PERIOD AK CA DE FL
PERIOD1 1222.23 2423.2 232.33 345.21
PERIOD2
PERIOD3
1222.23 2423.2 232.33 345.21
SQL> -- package that dynamically executes the query
SQL> -- given variable numbers and values
SQL> -- of states and periods:
SQL> CREATE OR REPLACE PACKAGE package_name
2 AS
3 TYPE cursor_type IS REF CURSOR;
4 PROCEDURE procedure_name
5 (p_periods IN VARCHAR2,
6 p_states IN VARCHAR2,
7 cursor_name IN OUT cursor_type);
8 END package_name;
9 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY package_name
2 AS
3 PROCEDURE procedure_name
4 (p_periods IN VARCHAR2,
5 p_states IN VARCHAR2,
6 cursor_name IN OUT cursor_type)
7 IS
8 v_periods VARCHAR2 (1000);
9 v_sql VARCHAR2 (4000);
10 v_states VARCHAR2 (1000) := p_states;
11 BEGIN
12 v_periods := REPLACE (p_periods, ',', ''',''');
13 v_sql := 'SELECT SUBSTR(time_periods.period,1,10) period';
14 WHILE LENGTH (v_states) > 1
15 LOOP
16 v_sql := v_sql
17 || ',SUM(DECODE(name,'''
18 || SUBSTR (v_states,1,2) || ''',income)) "' || SUBSTR (v_states,1,2)
19 || '"';
20 v_states := LTRIM (SUBSTR (v_states, 3), ',');
21 END LOOP;
22 v_sql := v_sql
23 || 'FROM state_income, time_periods
24 WHERE time_periods.period = state_income.period (+)
25 AND time_periods.period IN (''' || v_periods || ''')
26 GROUP BY ROLLUP (time_periods.period)';
27 OPEN cursor_name FOR v_sql;
28 END procedure_name;
29 END package_name;
30 /
Package body created.
SQL> -- sample executions from SQL:
SQL> VARIABLE g_ref REFCURSOR
SQL> EXEC package_name.procedure_name ('PERIOD1,PERIOD2,PERIOD3','AK,CA,DE,FL', :g_ref)
PL/SQL procedure successfully completed.
SQL> PRINT g_ref
PERIOD AK CA DE FL
PERIOD1 1222.23 2423.2 232.33 345.21
PERIOD2
PERIOD3
1222.23 2423.2 232.33 345.21
SQL> EXEC package_name.procedure_name ('PERIOD1,PERIOD2','AK,AL,AR', :g_ref)
PL/SQL procedure successfully completed.
SQL> PRINT g_ref
PERIOD AK AL AR
PERIOD1 1222.23
PERIOD2
1222.23
SQL> -- sample execution from PL/SQL block
SQL> -- using parameters derived from processing
SQL> -- cursors containing results of other queries:
SQL> DECLARE
2 CURSOR c_period
3 IS
4 SELECT period
5 FROM time_periods;
6 v_periods VARCHAR2 (1000);
7 v_delimiter VARCHAR2 (1) := NULL;
8 CURSOR c_states
9 IS
10 SELECT state
11 FROM states;
12 v_states VARCHAR2 (1000);
13 BEGIN
14 FOR r_period IN c_period
15 LOOP
16 v_periods := v_periods || v_delimiter || r_period.period;
17 v_delimiter := ',';
18 END LOOP;
19 v_delimiter := NULL;
20 FOR r_states IN c_states
21 LOOP
22 v_states := v_states || v_delimiter || r_states.state;
23 v_delimiter := ',';
24 END LOOP;
25 package_name.procedure_name (v_periods, v_states, :g_ref);
26 END;
27 /
PL/SQL procedure successfully completed.
SQL> PRINT g_ref
PERIOD AK AL AR CA DE FL
PERIOD1 1222.23 2423.2 232.33 345.21
PERIOD2
PERIOD3
PERIOD4
1222.23 2423.2 232.33 345.21 -
Variable number of parameters to procedure
I have a requirement to pass variable number of parameters for an attribute, to a stored procedure.
example:
procedure getSum(country_code IN varchar2, sum OUT number)
Inside the procedure, I am currently
writing SQL as
where eligible_code in (country_code).
This is ok when I pass just one code.
However I need to deal with n number of
country codes at a given time.
i.e. if I want to pass 3 country codes
as a concatinated string say "A-B-C"
where A, B, C are 3 different codes,
how do I decode them into a
meaning full
where eligible_code in ('A', 'B', 'C')
Or is there any other way of dealing
with this kind of situation.
The bottom line is I must have a stored
procedure, that takes parameter(s).
Any input/suggestion is highly appreciated.Please try the following, substituting the appropriate table name for your_table and the appropriate column name for eligible_code, then see if you can incorporate some of it into your procedure. Please let me know if it works for you or not.
SQL> EDIT getsum
CREATE OR REPLACE PROCEDURE getsum
(country_code IN VARCHAR2,
p_sum OUT NUMBER)
AS
v_country_codes VARCHAR2 (300);
v_sum NUMBER := 0;
v_sql_statement VARCHAR2 (3000);
v_sql_syntax VARCHAR2 (30000);
cursor_name INTEGER;
ignore INTEGER;
BEGIN
v_country_codes := REPLACE (country_code, '-', ''',''');
v_sql_statement := ' SELECT COUNT (*)
INTO :v_sum
FROM your_table
WHERE eligible_code IN (''' | | v_country_codes | | ''');';
v_sql_syntax := 'BEGIN '| | v_sql_statement | |' END;';
cursor_name := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (cursor_name, v_sql_syntax, DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (cursor_name, ':v_sum', v_sum);
ignore := DBMS_SQL.EXECUTE (cursor_name);
DBMS_SQL.VARIABLE_VALUE (cursor_name, ':v_sum', v_sum);
DBMS_SQL.CLOSE_CURSOR (cursor_name);
p_sum := v_sum;
END getsum;
Save the file.
SQL> START getsum
Procedure created.
SQL> VARIABLE g_sum NUMBER
SQL> EXEC getsum ('A-B-C', :g_sum)
PL/SQL procedure successfully completed.
SQL> PRINT g_sum
G_SUM
3
null -
Variable number of arguments in C functions
Hello. I know how to achieve creating a function that accepts a variable number of arguments. For example:
#include <stdio.h>
#include <stdarg.h>
int add (int x, ...);
int main (int argc, const char * argv[])
int result = add(3, 5, 3, 7);
printf("%d", result);
return 0;
int add (int x, ...)
va_list argList;
va_start(argList, x);
int sum = 0;
int i;
for (i = 0; i < x; ++i)
sum += va_arg(argList, int);
va_end(argList);
return sum;
The first argument, x, is sent to the function and represents how many additional optional arguments will be sent to the function (3 in the above example). Then, the definition of the add function totals those remaining (3) arguments, returning a value of (in this case) 15, which main then prints to the console. Simple enough, but here's my question:
What if I want to achieve this same optional arguments concept without having to send the function the number of optional arguments it will be accepting. For example, the printf() function takes an optional number of arguments, and nowhere there do you have to specify an extra argument that represents the number of additional optional arguments being passed (unless maybe the number of formatting specifiers in the first argument determines this number). Can this be done? Does anyone have any input here? Thanks in advance.Hi Tron -
I looked over my first response again, and it needs to be corrected. Fortunately Bob and Hansz straightened everything out nicely, but I still need to fix my post:
RayNewbie wrote:
Yes, the macros are designed to walk a list of args when neither the number of args or their type is known.
The above should have said. "The macros are designed to walk a list of args when neither the number of args or their type is known _at compile time_".
If I may both paraphrase and focus your original question, I think you wanted to know if there was any way the function could run without knowing the number of args to expect. The answer to this question is "No". In fact at runtime, the function must know both the number of args and the type of each.
Tron55555 wrote:
... the printf() function takes an optional number of arguments, and nowhere there do you have to specify an extra argument that represents the number of additional optional arguments being passed (unless maybe the number of formatting specifiers in the first argument determines this number).
As both Bob and Hansz have explained, the underlined statement is correct. Similarly, the example from the manual gives the number and types of the args in the first string arg.
Hansz also included an alternative to an explicit count or format string, which is to terminate the arg list with some pre-specified value (this is sometimes called a "sentinel" value. However when using a sentinel, the called function must know the data types. For example, you could never simply terminate the args with a sentinel and then pass a double followed by an int. The combined length of these args is 8 + 4 => 12 bytes, so unless the function knew which type was first at compile time, it wouldn't be possible to determine whether the list was 4+8 or 8+4 at runtime.
If you're interested in knowing why a variable arg function is limited in this way, or in fact how any C function finds its args, its parameters, and how to return to the calling function, you might want to do some reading about the "stack frame". You can learn the concept without getting into any assembler code. Here's an article that might be good to start with: [http://en.citizendium.org/wiki/Stack_frame].
After you have some familiarity with the stack frame, take a look at the expansions of the stdarg macros and see if you can figure out how they work, especially how va_arg walks down the stack, and what info is required for a successful trip. Actually, I don't think you can find these expansions in the stdarg.h file for Darwin; it looks like the #defines point to built-in implementations, so here are some typical, but simplified defs:
// these macros aren't usable; necessary type casts have been removed for clarity
typedef va_list char*;
#define va_start(ap,arg1) ap = &arg1 + sizeof(arg1)
#define va_arg(ap,type) *(ap += sizeof(type))
#define va_end(ap) 0
Note that I"m trusting you not to start asking questions about the stack or the above macros until you've studied how a stack works and how the C stack frame works in particular.
- Ray -
Formula variable of type replacement path not working
Hi Folks,
I have created formula variable of type replacement path and replaces with characteristic key.I wanted to use charecteristic infoobjects in coluns so that i have created formula variable for that.But when excecuting the query in web it is not displaying values for that formula.
Can anyone plz solve this,if u come accross this situation before.
Thanks and Regards,
Ravikiran
Edited by: MRK@SAPBI on Jun 11, 2011 1:13 PMThanks vineet, for your quick reply.
yes,i have used the characteristic in a row and it is a number.
Still it is not displyaing values.But i need to calculate the couter for the same formula created on that charateristic and need to put condition in the query.
thanks,
Ravikiran -
A formula with a formula variable with a replacement path delivers X
A formula with a formula variable with a replacement path delivers X as a result if the characteristic of the replacement is not in the drilldown
I have Created on ( date ) on which I have a Formula variable . I have used that Formula Variable in my calculated Key figure .
Now the Problem is If I use Created on in ROW , The calculated key figure works . But if I don't use in Row , The calculated Key figure shows X . Situation is Users don't want to see Created on in ROW .
If I use in row and hide also , then number of Records will be same .
Pls guide me what shoud I do .
Is this problem related to support pack .hi
i would like to know how to create the replacement path and authorisation variables.
what are the steps we need to follow in rsa1.
Edited by: vasu reddy on Apr 9, 2008 11:28 AM
Maybe you are looking for
-
We have a publishing website in SharePoint 2010. There are total 4 environments - Development, Test, Stage and Production. For some enhancements, we had to create some new lists and libraries. When we moved changes from Development to Test environmen
-
No spool list available in SP01.
Hi All, We have one background job running everyday in production. The jobi sgetting finished and when we check the job log in SM 37, it gives one spool request no. But when we check the sppol no in SP01, it says 'No list available'. Can anyone pls p
-
Hi Experts, Good day! i ineserted the query in report designer and would like to the execute the report i am following these steps.iam executing the after the dataprovider option in menu bar in report designer is it correct or i need to go for portal
-
How to convert iDocs in flat format to Xml
Hi, I'm getting iDocs in my .NET application using the SAP .NET Connector. But SAP Connector I receive the iDocs in flat format that is very difficult to read, it would be much easier if I had them in xml format. Do you know an easy way for transform
-
So, I don't know the cause of this (the point of this post is to find out the cause), but I was using my iPod Touch at the time it occurred, so I'm going to start by asking here. I was using iTunes Tuesday night to upgrade my iPod Touch from OS 2.2 t