Pass PL/SQL collection as function parameter over DBLink
Hi all,
I am trying to do the following;
---Remote database
--create SQL type
create type attributeidarray as table of varchar2(255);
--create a package specs
CREATE OR REPLACE PACKAGE testp
AS
TYPE ref_res IS REF CURSOR;
FUNCTION foo (i NUMBER)
RETURN NUMBER;
FUNCTION foo1 (i NUMBER, j attributeidarray)
RETURN NUMBER;
END;
--create package body
CREATE OR REPLACE PACKAGE BODY testp
IS
--Function does nothing other than return number
FUNCTION foo (i NUMBER)
RETURN NUMBER
IS
res ref_res;
a array_n;
BEGIN
OPEN res
FOR
SELECT *
FROM DUAL;
RETURN 1;
END;
--Function takes the collection as imput and does nothing with it. Function just returns number
FUNCTION foo1 (i NUMBER, j attributeidarray)
RETURN NUMBER
IS
res ref_res;
a array_n;
BEGIN
OPEN res
FOR
SELECT *
FROM DUAL;
RETURN 1;
END;
END;
--"Near" Database ..
--create a SQL type
--This is the exactly the same as in remote database
create type attributeidarray as table of varchar2(255);
--create a DBLink
create database link con_to_remote_db
connect to remotedbuser
identified by "swordfish"
using 'remotedb'
--call the remote functions and pass a collection object
SQL> DECLARE
2 a attributeidarray;
3 BEGIN
4 SELECT CAST (attributeidarray (1, 2) AS attributeidarray)
5 INTO a
6 FROM DUAL;
7
8 :b := testp.foo@con_to_remote_db (2);
9 END;
10 /
PL/SQL procedure successfully completed.
SQL> print b
B
1
SQL>
--so far so good...
SQL> DECLARE
2 a attributeidarray;
3 BEGIN
4 SELECT CAST (attributeidarray (1, 2) AS attributeidarray)
5 INTO a
6 FROM DUAL;
7
8 :b := testp.foo1@con_to_remote_db (2, a);
9 END;
10 /
:b := testp.foo1@con_to_remote_db (2, a);
ERROR at line 8:
ORA-06550: line 8, column 10:
PLS-00306: wrong number or types of arguments in call to 'FOO1'
ORA-06550: line 8, column 4:
PL/SQL: Statement ignored
--Oops...doesn't seem to recognize the collection type :( /b]
So I wish to know the following;
- Even though the definition for type is the same, why is the remote DB not recognizing my type?
- It would be helpful if any one can let me know the correct method to pass a collection type with a example.
I would appreciate any help in resolving this issue.
Thanks,
prashant
Not possible. For valid technical reasons.
Definitions are local to a database. You can define a SQL user type called TMyType in your database. I can define one in mine with the same name.
Can you now call my database, passing a collection of your TMyType to me? How do we (or Oracle) know that your definition and my definition is the same? Or if they were the same when you compiled your code (and your Oracle checked my Oracle to confirm), that they still are the same and that I did not in the meantime altered the type? Or even dropped it?
For types/collections to be transparently passed across to database links, we need something along the lines of:
a) global types
b) runtime checking of types
Both are problematic to implement and maintain. With (a) there is the issue of dependencies. The global type cannot be changed before all dependencies on all subscribers have been resolved. With (b) there is the issue of performance, checking the type definitions with every single call on the local & remote instances to compare.
It would be a nice feature to have... but it would fail to live up to expectation if not implemented in a robust and performant way.
Alternative. "Insert" data via a remote proc into a remote collection. This allows you to push data into a PGA memory structure on the remote side and when done, allows you to tell that remote proc to "flush" (forall insert/update/delete) the contents of that structure to disk.
Similar Messages
-
Passing pl/sql array to function
Hi,
I have a function which takes an array:
create or replace
FUNCTION execute_tests(
leg_keys IN type_leg_key_array)
RETURN BOOLEAN
IS
BEGIN
leg_key_array is this:
create or replace
TYPE type_leg_key_array AS TABLE OF NUMBER(6, 3);
I would like to test this funtion by passing it some array:
DECLARE
LEG_KEYS DEV_SWA30PRE.TYPE_LEG_KEY_ARRAY;
V_RETURN BOOLEAN;
BEGIN
-- LEG_KEYS := NULL;
v_Return := EXECUTE_TESTS(LEG_KEYS);
END;
What is wrong with the snippet above?
ThanksHi,
user610868 wrote:
Hi,
I have a function which takes an array:
create or replace
FUNCTION execute_tests(
leg_keys IN type_leg_key_array)
RETURN BOOLEAN
IS
BEGIN
leg_key_array is this:
create or replace
TYPE type_leg_key_array AS TABLE OF NUMBER(6, 3);
I would like to test this funtion by passing it some array:
DECLARE
LEG_KEYS DEV_SWA30PRE.TYPE_LEG_KEY_ARRAY;
V_RETURN BOOLEAN;
BEGIN
-- LEG_KEYS := NULL;
v_Return := EXECUTE_TESTS(LEG_KEYS);
END;
What is wrong with the snippet above?Why do you think anything is wrong? Are you getting an error message? Post the complete error message, including line numbers. Does the error occur when you create the type, when you create the function, when you call the function, or someplace else?
The only errors I see are probably due to how you chose to post it. For example, there is no RETURN or END statement in execute_tests.
Did you create the type before trying to use it in the function?
What is DEV_SWA30PRE? Is that a schema? Does that schema also contain the fucntion? Is that who is running the anonymous block? If there are other schemas involved, what are they? What are they doing? What privileges do they have on the type or the function?
Post a complete test script that people can run to re-create the problem and test their ideas. -
Is it possible to pass a SQL into a Function
DECLARE
f sys_refcursor;
RESULT NUMBER;
FUNCTION myfunction (r sys_refcursor)
RETURN NUMBER
IS
BEGIN
RETURN TO_NUMBER (TO_CHAR (r.dt, 'DD'));
END;
BEGIN
OPEN f FOR
SELECT SYSDATE dt
FROM DUAL;
RESULT := myfunction (f);
CLOSE f;
END;Yes you are allowed to pass ref cursor but they have to processed the way you processur cursor i.e. OPEN, FETCH, CLOSE.
See demonostration of working code:
SQL>DECLARE
2 f sys_refcursor;
3 RESULT NUMBER;
4
5 FUNCTION myfunction (r sys_refcursor)
6 RETURN NUMBER
7 IS
8 v_currDate DATE;
9
10 BEGIN
11 IF r%ISOPEN THEN
12 FETCH r INTO v_currDate;
13 END IF;
14
15 RETURN TO_NUMBER (TO_CHAR (v_currDate, 'DD'));
16 END;
17 BEGIN
18 OPEN f FOR
19 SELECT SYSDATE dt
20 FROM DUAL;
21
22 RESULT := myfunction (f);
23
24 DBMS_OUTPUT.PUT_LINE('Date : ' || RESULT );
25
26 CLOSE f;
27 END;
28 /
Date : 23
PL/SQL procedure successfully completed.
{code} -
Pass rowtype as function parameter, as a Object like type. How?
Hi.
I have the following question.
I have 3 tables:
TAB1
TAB2
TAB3
I declare 3 rowtypes variables, one for each table:
v_tab1 TAB1%ROWTYPE;
v_tab2 TAB2%ROWTYPE;
v_tab3 TAB3%ROWTYPE;
I want to pass a rowtype as a function parameter, but i want the function to allow any rowtype to be passed as parameter, and then inside the function convert that "object" to the correct rowtype.
Is that possible?
In another language like C# for example, i would pass the rowtype as a object type, and then cast it to the correct data type.
I hope you can help me.
Cheers.To do this they would have to be object types, and have a common supertype.Alternatively unrelated object types could be abstracted away with ANYDATA.
There is no such functionality exposed / documented for records - although the signatures of several built-in packages suggest that a mechanism for passing ADTs as formal parameters does actually exist. -
Pass TestStand error type directly into function parameter
Hi,
I am using TestStand 4 and Labwindows CVI 8.5.
I wonder if it is possible to pass Standard Step error type into CVI function parameters.
I think it would be more simple to pass one parameter instead of passing Error code, Error occurred state and Error message into function prototype.
I tried to use tsErrorDataType struct defined into tsutil.h into my function prototype.
In TestStand, I pass Step error type into function parameter but it does not work.
TestStand displays an error meaning parameters does not match function prototype.
Thank you for your help.Hi Tartempion,
In order to pass the TestStand Error Container as one parameter to a function in a CVI DLL, you must use a struct that is typedef'ed and create an .fp file that is included as a type library for the DLL. When you create a .fp file to add to a DLL, the DLL will not build unless all structs/enums are typedef'ed. Thus, I wouldn't advise using the tsutil.h because you would have to go through and typedef every single struct and enum in the header file.
Instead, you can simply create a typedef'ed struct in your projects header file and create an .fp file with the struct specified as a data type. Then in TestStand, when you call the function you would need to ensure that the parameter is of Category "C Struct", and type "Error". The attached zip file contains a CVI 8.5 project that demonstrates this along with a TestStand 4.0 sequence file that demonstrates how to pass the parameter to the function by reference. In case you run into trouble creating the .fp file please refer to the following KnowledgeBase. The instructions are for enums but easily correspond to structs as well:
TestStand and LabWindows/CVI Enumeration Data Types
Hope this helps!
Manooch H.
National Instruments
Attachments:
PassTSError.zip 19 KB -
Can I pass a table function parameter like this?
This works. Notice I am passing the required table function parameter using the declared variable.
DECLARE @Date DATE = '2014-02-21'
SELECT
h.*, i.SomeColumn
FROM SomeTable h
LEFT OUTER JOIN SomeTableFunction(@Date) I ON i.ID = h.ID
WHERE h.SomeDate = @Date
But I guess you can't do this?... because I'm getting an error saying h.SomeDate cannot be bound. Notice in this one, I am attempting to pass in the table function parameter from the SomeTable it is joined to by ID.
DECLARE @Date DATE = '2014-02-21'
SELECT
h.*, i.SomeColumn
FROM SomeTable h
LEFT OUTER JOIN SomeTableFunction(h.SomeDate) I ON i.ID = h.ID
WHERE h.SomeDate = @DateHi
NO you cant pass a table function parameter like this?
As When you declare @date assign value to it and pass as a parameter it will return table which you can use for join as you did it in first code
But when you pass date from some other table for generating table from your funtion it doesnt have date as it is not available there
Ref :
http://www.codeproject.com/Articles/167399/Using-Table-Valued-Functions-in-SQL-Server
http://technet.microsoft.com/en-us/library/aa214485(v=sql.80).aspx
http://msdn.microsoft.com/en-us/library/ms186755.aspx
https://www.simple-talk.com/sql/t-sql-programming/sql-server-functions-the-basics/
http://www.sqlteam.com/article/intro-to-user-defined-functions-updated
Mark
as answer if you find it useful
Shridhar J Joshi Thanks a lot -
Pass multiple values as single input parameter into pipelined function
Hi all,
My need is to pass multiple values as single input parameter into pipelined function.
For example - "2" and "3" are values of input parameter "t":
with data as (
select 1 as t from dual union all
select 2 as t from dual union all
select 3 as t from dual union all
select 4 as t from dual union all
select 5 as t from dual
select * from data where t in (2,3)Is it possible at all?Not exactly sure, but usually 'multiple values'+'pipelined function' = some IN-LIST related approach?
See:
SQL> create table data as
2 select 1 as t from dual union all
3 select 2 as t from dual union all
4 select 3 as t from dual union all
5 select 4 as t from dual union all
6 select 5 as t from dual;
Table created.
SQL> --
SQL> CREATE OR REPLACE FUNCTION in_list (p_in_list IN VARCHAR2)
2 RETURN sys.odcivarchar2list PIPELINED
3 AS
4 l_text VARCHAR2(32767) := p_in_list || ',';
5 l_idx NUMBER;
6 BEGIN
7 LOOP
8 l_idx := INSTR(l_text, ',');
9 EXIT WHEN NVL(l_idx, 0) = 0;
10 PIPE ROW (TRIM(SUBSTR(l_text, 1, l_idx - 1)));
11 l_text := SUBSTR(l_text, l_idx + 1);
12 END LOOP;
13
14 RETURN;
15 END;
16 /
Function created.
SQL> --
SQL> select *
2 from data
3 where t in ( select *
4 from table(in_list('1,2'))
5 );
T
1
2
2 rows selected.http://www.oracle-base.com/articles/misc/dynamic-in-lists.php
or
http://tkyte.blogspot.nl/2006/06/varying-in-lists.html -
Can't we pass java.sql.Connection as parameter toDatum() method
I am in mid of java 1.3 to 1.4 migration, now I am getting the below error.can't we pass java.sql.Connection as a param to toDatum(), but I did the same before for another module and it worked fine, now I am getting the error.
any changes need to be done?
[b]toDatum(oracle.jdbc.driver.OracleConnection,java.lang.String) in oracle.jpub.runtime.MutableArray cannot be applied to (java.sql.Connection,java.lang.String)
return array.toDatum(c, SQL_NAME);
^
1 error
I changed to use
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
instead of
import oracle.sql.CustomDatum;
import oracle.sql.CustomDatumFactory;In general, it's bad practice to be that "open" with regards to parameters to methods, especially when using remote invocations. However, if you really, really, really, really need to - and I doubt you do - you can use Serializable for the type of parameter. But that's still inelegant and, well, raises all sorts of issues, starting with your design...
-
Passing PL/SQL Record back to VB5 as Parameter
Can anyone please help with this code.
I am passing pl/sql record back to VB 5 app as parameter and having no joy.
MY code
Package TEST_PKG
IS
TYPE Brian_Test IS RECORD(
First_answer Number :=0,
Second_answer Number := 0
-- Brian_Record Brian_test;
END; -- Package Specification TEST_PKG
Procedure ADD_NUMBER ( NUMBER1 IN NUMBER, NUMBER2 IN NUMBER, ANSWER OUT test_pkg.Brian_test, status OUT VARCHAR)
IS
-- Person Date Comments
-- Timothy Adetunji 05/02/2001 Test Procedure for Brian May to verify how to execute procedures from VB
-- variable_name datatype;
-- Declare program variables as shown above
BEGIN
answer.first_answer := nvl(number1,0) + nvl(Number2,0);
answer.second_answer := nvl(number1,0) - nvl(Number2,0);
status := 'Ok';
EXCEPTION
WHEN others THEN
status := 'Bad';
END; -- Procedure ADD_NUMBER
VB doesn't seem to understand records as parameter. I am able to pass individual variable but not in a reecord.
My production codes requires me to pass 25 variables and it will be senseless to pass them individually.
ThanksHi
This shld be the way to write
Package TEST_PKG AS TYPE Brian_Test AS RECORD(
First_answer Number :=0,
Second_answer Number := 0);
TYPE RCT1 IS REF CURSOR RETURN Brian_Test;
END;
Procedure ADD_NUMBER (
NUMBER1 IN NUMBER,
NUMBER2 IN NUMBER,
status OUT VARCHAR2,
RC1 IN OUT TEST_PKG.RCT1) AS
BEGIN
OPEN RC1 FOR
SELECT nvl(number1,0) + nvl(Number2,0),
nvl(number1,0) - nvl(Number2,0)
FROM DUAL;
status := 'Ok';
RETURN;
EXCEPTION
WHEN others THEN
OPEN RC1 FOR
SELECT nvl(number1,0) + nvl(Number2,0),
nvl(number1,0) - nvl(Number2,0)
FROM DUAL;
status := 'Bad';
RETURN;
END; -- Procedure ADD_NUMBER
Compile this and try
Have Fun!
r@m@ -
How to pass select-option filed to Function Module Exporting Parameter
Hi,
How to pass select-option filed to Function Module Exporting Parameter.
ThanksHi,
DATA: BEGIN OF ITAB5_WRK OCCURS 0,
KUNNR TYPE KNKK-KUNNR, "CUSTOMER #
SBGRP TYPE KNKK-SBGRP, "CREDIT REP
KLIMK TYPE KNKK-KLIMK, "CREDIT LIMIT
NAME1 TYPE KNA1-NAME1, "CUSTOMER NAME
SKFOR TYPE KNKK-SKFOR, "TOTAL A/R
AMT1 TYPE KNKK-SKFOR, "CURRENT
AMT2 TYPE KNKK-SKFOR, "01-30
AMT3 TYPE KNKK-SKFOR, "31-60
AMT4 TYPE KNKK-SKFOR, "61-90
AMT5 TYPE KNKK-SKFOR, "91-120
AMT6 TYPE KNKK-SKFOR, "OVR 120
BZIRK TYPE KNVV-BZIRK,
END OF ITAB5_WRK.
SELECT-OPTIONS P_COMP FOR T001-BUKRS
SELECT KUNNR SBGRP FROM KNKK
INTO TABLE ITAB5_WRK
WHERE SBGRP IN P_REP
AND KUNNR GE '0001000000'
AND SKFOR NE 0.
LOOP AT ITAB5_WRK.
DELETE ADJACENT DUPLICATES FROM ITAB5_WRK COMPARING KUNNR.
ENDLOOP.
PERFORM GET_CREDIT_LIMITS.
*=======================================================================
IF P_DIST NE SPACE.
LOOP AT ITAB5_WRK.
SELECT SINGLE * FROM KNVV WHERE KUNNR EQ ITAB5_WRK-KUNNR
AND VKORG EQ P_COMP
AND VTWEG EQ '20'
AND SPART EQ '10'
AND BZIRK IN P_DIST.
IF SY-SUBRC EQ 0.
MOVE KNVV-BZIRK TO ITAB5_WRK-BZIRK.
MODIFY ITAB5_WRK.
ELSE.
DELETE ITAB5_WRK.
ENDIF.
ENDLOOP.
ENDIF.
*==============================================================
LOOP AT ITAB5_WRK.
MOVE: 'F/S' TO WRK-KKBER,
ITAB5_WRK-KUNNR TO WRK-KUNNR.
PERFORM AGING.
ADD: W_SNFAE TO ITAB5_WRK-AMT1,
W_SFAE1 TO ITAB5_WRK-AMT2,
W_SFAE2 TO ITAB5_WRK-AMT3,
W_SFAE3 TO ITAB5_WRK-AMT4,
W_SFAE4 TO ITAB5_WRK-AMT5,
W_SFAE5 TO ITAB5_WRK-AMT6,
W_SFAEL TO ITAB5_WRK-SKFOR,
W_SNFAE TO ITAB5_WRK-SKFOR.
MOVE: 'SPEC' TO WRK-KKBER,
ITAB5_WRK-KUNNR TO WRK-KUNNR.
*PERFORM AGING.*
ADD: W_SNFAE TO ITAB5_WRK-AMT1,
W_SFAE1 TO ITAB5_WRK-AMT2,
W_SFAE2 TO ITAB5_WRK-AMT3,
W_SFAE3 TO ITAB5_WRK-AMT4,
W_SFAE4 TO ITAB5_WRK-AMT5,
W_SFAE5 TO ITAB5_WRK-AMT6,
W_SFAEL TO ITAB5_WRK-SKFOR,
W_SNFAE TO ITAB5_WRK-SKFOR.
MODIFY ITAB5_WRK.
ENDLOOP.
FORM AGING.
*CALL FUNCTION 'CUSTOMER_DUE_DATE_ANALYSIS'*
EXPORTING
BUKRS = P_COMP
KKBER = WRK-KKBER
KUNNR = WRK-KUNNR
RASID = 'FEND'
KLIMP = 'X'
IMPORTING
SFAE1 = W_SFAE1
SFAE2 = W_SFAE2
SFAE3 = W_SFAE3
SFAE4 = W_SFAE4
SFAE5 = W_SFAE5
SFAE6 = W_SFAE6
SFAEL = W_SFAEL
SNFA1 = W_SNFA1
SNFA2 = W_SNFA2
SNFA3 = W_SNFA3
SNFA4 = W_SNFA4
SNFA5 = W_SNFA5
SNFA6 = W_SNFA6
SNFAE = W_SNFAE
EXCEPTIONS
NO-AGING_SCHEDULE = 1
NO_TABLE_INPUT = 2.
CASE SY-SUBRC.
WHEN 1.
MESSAGE E999 WITH 'PLEASE ENTER AGING SCHEDULE'.
WHEN 2.
MESSAGE E999 WITH 'DO NOTHING ??'.
ENDCASE.
ENDFORM. "AGING
Thanks -
How to pass "EnterpriseManagementObject" Type as Function parameter?
Hello, dear Colleagues.
I'm trying to pass "EnterpriseManagementObject" as Function parameter.
Here is the piece of code:
$SCSM = 'SERVER_NAME'
function Add-Comment {
param (
[parameter(Mandatory=$true,Position=0)][Alias('Id')][String]$pSRId,
[parameter(Mandatory=$true,Position=1)][Alias('Comment')][String]$pComment,
[parameter(Mandatory=$true,Position=2)][Alias('EnteredBy')][String]$pEnteredBy,
[parameter(Mandatory=$true,Position=3)][Alias('IsAnalyst')][Bool]$AnalystComment,
[parameter(Mandatory=$true,Position=4)][Alias('IRObject')][EnterpriseManagementObject]$IRObject
if ($IRObject) {
$NewGUID = ([guid]::NewGuid()).ToString()
if ($AnalystComment)
$Projection = @{__CLASS = "System.WorkItem.Incident";
__SEED = $IRObject;
AnalystComments = @{__CLASS = "System.WorkItem.TroubleTicket.AnalystCommentLog";
__OBJECT = @{"Id" = $NewGUID;
Comment = $pComment;
DisplayName = $NewGUID;
EnteredBy = $pEnteredBy;
EnteredDate = (Get-Date).ToUniversalTime();
IsPrivate = $false
New-SCSMObjectProjection -Type System.WorkItem.IncidentPortalProjection -Projection $Projection -ComputerName $SCSM -ErrorAction stop
} else {
Write-Host $pSRId "could not be found"
$IncidentClass = Get-SCSMClass -name System.WorkItem.Incident$ -ComputerName $SCSM
$Incident = Get-SCSMObject -Class $IncidentClass -Filter "name -eq $c" -ComputerName $SCSM
Add-Comment -Id $c -Comment $text -EnteredBy $name -IsAnalyst $False -IRObject $Incident -ErrorAction stop
With GetType() I watched $Incident is "EnterpriseManagementObject":
IsPublic IsSerial Name BaseType
True True EnterpriseManagementObject Microsoft.EnterpriseManagement.Common.EnterpriseManagementObjectBaseWithProperties
But PS script returns error TypeNotFound:
Add-Comment : Unable to find type [EnterpriseManagementObject]. Make sure that the assembly that contains this type is loaded.
At C:\script.ps1:146 char:13
+ Add-Comment -Id $c -Comment $text -EnteredBy $name -IsAnalyst $True ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (EnterpriseManagementObject:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
Is there a way to pass "EnterpriseManagementObject" as Function parameter?
Thanks.First of all the error indicates that you haven't loaded the assembly which contains the class you're trying to load.
Try loading the assembly by running:
[Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.Core") | Out-Null
Secondly if you want to use type based parameters restrictions you should use full type name, which can be found with the command:
$SomeObject.GetType().FullName
You should end up with: Microsoft.EnterpriseManagement.Common.EnterpriseManagementObject -
Missing Data in Table passed as Function Parameter
I am running a JCO server & in my handleRequest(), I am trying to get the data from the tables paased as function parameters from the SAP system.
Somehow I am not able to see any data in the tables, though the SAP system has put some data in the tables before sending.
The no. of rows in the table is 0 always on the JCO side. I tried to dunp the content of the Function & Table with writeHTML() & it shows no data too.
I am able to pass simple strings & integers, but the tables doesn't work. Can anyone tell me where might be the problem.Hi,
I am bit confused, You are not getting the data in the Function module when you make a call from Java or the data returned by the function module is not reaching the Java side. If you are not getting the data which you pass from java in the function module then I have faced this problem before.
In that case the problem was when you pass data as table parameters to the function module you have to check the size of table parameter I was using INITIAL to check if there is any data in the table parameter. If this is the same problem may be by checking the size of the table will solve your problem.
Regards,
Sesh -
Parameter passing in sql statement
hello..
i want to execute a value insertion query in jdbc..where the values are all parameterized string variables.but it failed to execute the query...
and generating a sql exception "too few parameter.."
but it succesfully executes with a direct string like'hello'....
heres my sample code for this...
public void settablevalue(String pn,String pid,String time)
try
Statement s1=con.createStatement();
System.out.println(pn+" "+pid+" "+time);
char []pname=new char[50];
char []prcsid=new char[50];
char []timecrtn=new char[100];
pname=pn.toCharArray();
prcsid=pid.toCharArray();
timecrtn=time.toCharArray();
s1.execute("insert into ProcessEvent values(pname[],prcsid[],timecrtn[])");
System.out.println("Executed");
s1.close();
catch (Exception err)
System.out.println("ERROR: " + err);
now do i insert string values in the table...
pls help...thnx in advanceYou should use a PreparedStatement. Read the JavaDoc of PreparedStatement.
Usually you prepare a statmenet like this: "insert into ProcessEvent values (?, ?, ?)" and then use setString(), setDate(), ... to set the concrete values.
Additionally ('though this doesn't have to do anything with your problem): You don't need to create char-arrays, and even if you do, you don't have to initialize them (using "char[]pname=new char[50]") if you later assign a new value (using "pname=pn.toCharArray()"). -
Nameless Nested Classes passed in Function Parameter?
I am trying to get my head around the following code example:
javax.swing.SwingUtilities.invokeLater( new Runnable() { public void run() { createAndShowGUI(); }});What is actually getting passed to the SwingUtilities.invokeLater() function?
Can anyone explain all of the parts and pieces of :
new Runnable() { public void run() { createAndShowGUI(); }} ?
Here is my best guess:
1) { public void run() { createAndShowGUI(); }} is an unnamed nested class that is instantiated using the Runnable() interface.
2) this class has one method called run() that executes createAndShowGUI();
Is my best guess even close to what is really going on?richard.broersma wrote:
1) { public void run() { createAndShowGUI(); }} is an unnamed nested class that is instantiated using the Runnable() interface.Yes, that's essentially correct. It's called an anonymous inner class.
This is similar to doing
// a non-anonymous inner class
private class MyClass implements Runnable
public void run()
createAndShowGUI();
MyClass myclass = new MyClass();
javax.swing.SwingUtilities.invokeLater(myclass);
2) this class has one method called run() that executes createAndShowGUI();Yes. It must have a parameterless public void run method since it implements the Runnable interface.
Is my best guess even close to what is really going on?Yes, you're catching on. -
Hi,
i try to distribute SQL data objects - stored in a SQL data type TABLE OF <object-Type> - to multiple (parallel) instances of a table function,
by passing a CURSOR(...) to the table function, which selects from the SQL TABLE OF storage via "select * from TABLE(CAST(<storage> as <storage-type>)".
But oracle always only uses a single table function instance :-(
whatever hints i provide or setting i use for the parallel table function (parallel_enable ...)
Could it be, that this is due to the fact, that my data are not
globally available, but only in the main thread data?
Can someone confirm, that it's not possible to start multiple parallel table functions
for selecting on SQL data type TABLE OF <object>storages?
Here's an example sqlplus program to show the issue:
-------------------- snip ---------------------------------------------
set serveroutput on;
drop table test_table;
drop type ton_t;
drop type test_list;
drop type test_obj;
create table test_table
a number(19,0),
b timestamp with time zone,
c varchar2(256)
create or replace type test_obj as object(
a number(19,0),
b timestamp with time zone,
c varchar2(256)
create or replace type test_list as table of test_obj;
create or replace type ton_t as table of number;
create or replace package test_pkg
as
type test_rec is record (
a number(19,0),
b timestamp with time zone,
c varchar2(256)
type test_tab is table of test_rec;
type test_cur is ref cursor return test_rec;
function TF(mycur test_cur)
return test_list pipelined
parallel_enable(partition mycur by hash(a));
end;
create or replace package body test_pkg
as
function TF(mycur test_cur)
return test_list pipelined
parallel_enable(partition mycur by hash(a))
is
sid number;
counter number(19,0) := 0;
myrec test_rec;
mytab test_tab;
mytab2 test_list := test_list();
begin
select userenv('SID') into sid from dual;
dbms_output.put_line('test_pkg.TF( sid => '''|| sid || ''' ): enter');
loop
fetch mycur into myRec;
exit when mycur%NOTFOUND;
mytab2.extend;
mytab2(mytab2.last) := test_obj(myRec.a, myRec.b, myRec.c);
end loop;
for i in mytab2.first..mytab2.last loop
-- attention: saves own SID in test_obj.a for indication to caller
-- how many sids have been involved
pipe row(test_obj(sid, mytab2(i).b, mytab2(i).c));
counter := counter + 1;
end loop;
dbms_output.put_line('test_pkg.TF( sid => '''|| sid || ''' ): exit, piped #' || counter || ' records');
end;
end;
declare
myList test_list := test_list();
myList2 test_list := test_list();
sids ton_t := ton_t();
begin
for i in 1..10000 loop
myList.extend; myList(myList.last) := test_obj(i, sysdate, to_char(i+2));
end loop;
-- save into the real table
insert into test_table select * from table(cast (myList as test_list));
dbms_output.put_line(chr(10) || 'copy ''mylist'' to ''mylist2'' by streaming via table function...');
select test_obj(a, b, c) bulk collect into myList2
from table(test_pkg.TF(CURSOR(select /*+ parallel(tab,10) */ * from table(cast (myList as test_list)) tab)));
dbms_output.put_line('... saved #' || myList2.count || ' records');
select distinct(tab.a) bulk collect into sids from table(cast (myList2 as test_list)) tab;
dbms_output.put_line('worker thread''s sid list:');
for i in sids.first..sids.last loop
dbms_output.put_line('sid #' || sids(i));
end loop;
dbms_output.put_line(chr(10) || 'copy physical ''test_table'' to ''mylist2'' by streaming via table function:');
select test_obj(a, b, c) bulk collect into myList2
from table(test_pkg.TF(CURSOR(select /*+ parallel(tab,10) */ * from test_table tab)));
dbms_output.put_line('... saved #' || myList2.count || ' records');
select distinct(tab.a) bulk collect into sids from table(cast (myList2 as test_list)) tab;
dbms_output.put_line('worker thread''s sid list:');
for i in sids.first..sids.last loop
dbms_output.put_line('sid #' || sids(i));
end loop;
end;
-------------------- snap ---------------------------------------------
Here's the output:
-------------------- snip ---------------------------------------------
copy 'mylist' to 'mylist2' by streaming via table function...
test_pkg.TF( sid => '98' ): enter
test_pkg.TF( sid => '98' ): exit, piped #10000 records
... saved #10000 records
worker thread's sid list:
sid #98 -- ONLY A SINGLE SID HERE!
copy physical 'test_table' to 'mylist2' by streaming via table function:
... saved #10000 records
worker thread's sid list:
sid #128 -- A LIST OF SIDS HERE!
sid #141
sid #85
sid #125
sid #254
sid #101
sid #124
sid #109
sid #142
sid #92
PL/SQL procedure successfully completed.
-------------------- snap ---------------------------------------------
I posted it to newsgroup comp.databases.oracle.server.
(summary: "10g: parallel pipelined table functions with cursor selecting from table(cast(SQL collection)) doesn't work ")
But i didn't get a response.
There i also wrote some background information about my application:
-------------------- snip ---------------------------------------------
My application has a #2 steps/stages data selection.
A 1st select for minimal context base data
- mainly to evaluate for due driving data records.
And a 2nd select for all the "real" data to process a context
(joining much more other tables here, which i don't want to do for non-due records).
So it's doing stage #1 select first, then stage #2 select - based on stage #1 results - next.
The first implementation of the application did the stage #1 select in the main session of the pl/sql code.
And for the stage #2 select there was done a dispatch to multiple parallel table functions (in multiple worker sessions) for the "real work".
That worked.
However there was a flaw:
Between records from stage #1 selection and records from stage #2 selection there is a 1:n relation (via key / foreign key relation).
Means, for #1 resulting record from stage #1 selection, there are #x records from stage #2 selection.
That forced me to use "cluster curStage2 by (theKey)".
Because the worker sessions need to evaluate the all-over status for a context of #1 record from stage #1 and #x records from stage #2
(so it needs to have #x records of stage #2 together).
This then resulted in delay for starting up the worker sessions (i didn't find a way to get rid of this).
So i wanted to shift the invocation of the worker sessions to the stage #1 selection.
Then i don't need the "cluster curStage2 by (theKey)" anymore!
But: i also need to do an update of the primary driving data!
So the stage #1 select is a 'select ... for update ...'.
But you can't use such in CURSOR for table functions (which i can understand, why it's not possible).
So i have to do my stage #1 selection in two steps:
1. 'select for update' by main session and collect result in SQL collection.
2. pass collected data to parallel table functions
And for 2. i recognized, that it doesn't start up multiple parallel table function instances.
As a work-around
- if it's just not possible to start multiple parallel pipelined table functions for dispatching from 'select * from TABLE(CAST(... as ...))' -
i need to select again on the base tables - driven by the SQL collection data.
But before i do so, i wanted to verify, if it's really not possible.
Maybe i just miss a special oracle hint or whatever you can get "out of another box" :-)
-------------------- snap ---------------------------------------------
- many thanks!
rgds,
FrankHi,
i try to distribute SQL data objects - stored in a SQL data type TABLE OF <object-Type> - to multiple (parallel) instances of a table function,
by passing a CURSOR(...) to the table function, which selects from the SQL TABLE OF storage via "select * from TABLE(CAST(<storage> as <storage-type>)".
But oracle always only uses a single table function instance :-(
whatever hints i provide or setting i use for the parallel table function (parallel_enable ...)
Could it be, that this is due to the fact, that my data are not
globally available, but only in the main thread data?
Can someone confirm, that it's not possible to start multiple parallel table functions
for selecting on SQL data type TABLE OF <object>storages?
Here's an example sqlplus program to show the issue:
-------------------- snip ---------------------------------------------
set serveroutput on;
drop table test_table;
drop type ton_t;
drop type test_list;
drop type test_obj;
create table test_table
a number(19,0),
b timestamp with time zone,
c varchar2(256)
create or replace type test_obj as object(
a number(19,0),
b timestamp with time zone,
c varchar2(256)
create or replace type test_list as table of test_obj;
create or replace type ton_t as table of number;
create or replace package test_pkg
as
type test_rec is record (
a number(19,0),
b timestamp with time zone,
c varchar2(256)
type test_tab is table of test_rec;
type test_cur is ref cursor return test_rec;
function TF(mycur test_cur)
return test_list pipelined
parallel_enable(partition mycur by hash(a));
end;
create or replace package body test_pkg
as
function TF(mycur test_cur)
return test_list pipelined
parallel_enable(partition mycur by hash(a))
is
sid number;
counter number(19,0) := 0;
myrec test_rec;
mytab test_tab;
mytab2 test_list := test_list();
begin
select userenv('SID') into sid from dual;
dbms_output.put_line('test_pkg.TF( sid => '''|| sid || ''' ): enter');
loop
fetch mycur into myRec;
exit when mycur%NOTFOUND;
mytab2.extend;
mytab2(mytab2.last) := test_obj(myRec.a, myRec.b, myRec.c);
end loop;
for i in mytab2.first..mytab2.last loop
-- attention: saves own SID in test_obj.a for indication to caller
-- how many sids have been involved
pipe row(test_obj(sid, mytab2(i).b, mytab2(i).c));
counter := counter + 1;
end loop;
dbms_output.put_line('test_pkg.TF( sid => '''|| sid || ''' ): exit, piped #' || counter || ' records');
end;
end;
declare
myList test_list := test_list();
myList2 test_list := test_list();
sids ton_t := ton_t();
begin
for i in 1..10000 loop
myList.extend; myList(myList.last) := test_obj(i, sysdate, to_char(i+2));
end loop;
-- save into the real table
insert into test_table select * from table(cast (myList as test_list));
dbms_output.put_line(chr(10) || 'copy ''mylist'' to ''mylist2'' by streaming via table function...');
select test_obj(a, b, c) bulk collect into myList2
from table(test_pkg.TF(CURSOR(select /*+ parallel(tab,10) */ * from table(cast (myList as test_list)) tab)));
dbms_output.put_line('... saved #' || myList2.count || ' records');
select distinct(tab.a) bulk collect into sids from table(cast (myList2 as test_list)) tab;
dbms_output.put_line('worker thread''s sid list:');
for i in sids.first..sids.last loop
dbms_output.put_line('sid #' || sids(i));
end loop;
dbms_output.put_line(chr(10) || 'copy physical ''test_table'' to ''mylist2'' by streaming via table function:');
select test_obj(a, b, c) bulk collect into myList2
from table(test_pkg.TF(CURSOR(select /*+ parallel(tab,10) */ * from test_table tab)));
dbms_output.put_line('... saved #' || myList2.count || ' records');
select distinct(tab.a) bulk collect into sids from table(cast (myList2 as test_list)) tab;
dbms_output.put_line('worker thread''s sid list:');
for i in sids.first..sids.last loop
dbms_output.put_line('sid #' || sids(i));
end loop;
end;
-------------------- snap ---------------------------------------------
Here's the output:
-------------------- snip ---------------------------------------------
copy 'mylist' to 'mylist2' by streaming via table function...
test_pkg.TF( sid => '98' ): enter
test_pkg.TF( sid => '98' ): exit, piped #10000 records
... saved #10000 records
worker thread's sid list:
sid #98 -- ONLY A SINGLE SID HERE!
copy physical 'test_table' to 'mylist2' by streaming via table function:
... saved #10000 records
worker thread's sid list:
sid #128 -- A LIST OF SIDS HERE!
sid #141
sid #85
sid #125
sid #254
sid #101
sid #124
sid #109
sid #142
sid #92
PL/SQL procedure successfully completed.
-------------------- snap ---------------------------------------------
I posted it to newsgroup comp.databases.oracle.server.
(summary: "10g: parallel pipelined table functions with cursor selecting from table(cast(SQL collection)) doesn't work ")
But i didn't get a response.
There i also wrote some background information about my application:
-------------------- snip ---------------------------------------------
My application has a #2 steps/stages data selection.
A 1st select for minimal context base data
- mainly to evaluate for due driving data records.
And a 2nd select for all the "real" data to process a context
(joining much more other tables here, which i don't want to do for non-due records).
So it's doing stage #1 select first, then stage #2 select - based on stage #1 results - next.
The first implementation of the application did the stage #1 select in the main session of the pl/sql code.
And for the stage #2 select there was done a dispatch to multiple parallel table functions (in multiple worker sessions) for the "real work".
That worked.
However there was a flaw:
Between records from stage #1 selection and records from stage #2 selection there is a 1:n relation (via key / foreign key relation).
Means, for #1 resulting record from stage #1 selection, there are #x records from stage #2 selection.
That forced me to use "cluster curStage2 by (theKey)".
Because the worker sessions need to evaluate the all-over status for a context of #1 record from stage #1 and #x records from stage #2
(so it needs to have #x records of stage #2 together).
This then resulted in delay for starting up the worker sessions (i didn't find a way to get rid of this).
So i wanted to shift the invocation of the worker sessions to the stage #1 selection.
Then i don't need the "cluster curStage2 by (theKey)" anymore!
But: i also need to do an update of the primary driving data!
So the stage #1 select is a 'select ... for update ...'.
But you can't use such in CURSOR for table functions (which i can understand, why it's not possible).
So i have to do my stage #1 selection in two steps:
1. 'select for update' by main session and collect result in SQL collection.
2. pass collected data to parallel table functions
And for 2. i recognized, that it doesn't start up multiple parallel table function instances.
As a work-around
- if it's just not possible to start multiple parallel pipelined table functions for dispatching from 'select * from TABLE(CAST(... as ...))' -
i need to select again on the base tables - driven by the SQL collection data.
But before i do so, i wanted to verify, if it's really not possible.
Maybe i just miss a special oracle hint or whatever you can get "out of another box" :-)
-------------------- snap ---------------------------------------------
- many thanks!
rgds,
Frank
Maybe you are looking for
-
What is the problem in installing 8.1.7 on Linux
Hi I have seen a lot of posts discussing about problem in installing 8.1.7 on rh Linux 7. Can anyone tell me what is the actual problem, and do I need to download any patches to resolve it ? pam
-
How can I tell what video card and how much video memory does my iMac have?
How or where can I find out: which video card does my iMac have and how much video memory does it have? I've tried looking in System profiler, but I did not see it there. Thank you.
-
Help in Setting Password Protection to a Page in DW MX2004
I need to add password protection to a page. How do I do this in DW MX2004? Any help would be appreciated. Dreawmweaver newbie.
-
Urgent issue related to condition type block
Dear expert I need your help on issue Example Sales Deal # 123456: If Sales Deal is opened with transaction VB22 (e.g. to add a condition record or to amend one), then all condition records appear first as released (blank in column u201CSu201D status
-
HI guys, I am getting the repeated values in my query, because, my scenario like this -- In One Collective Purchase order(CPO) i have multiple Purchase order. so for CPO against quantity is repeating multiple times in my DataProvider. Is it Possible