Stored Procedure,again
I AM NOW STUDYING A STORED PROCEDURE ,AND I ENCOUNTER SOME PROBLEM WITH
UPDATE AND DELETE SOME RECORD WHICH ONE IS UPDATED OR DELETED,
and what about this message :
FRM-40743 This operation with no base table requires
the LOCK-PROCEDURE trigger,
if you can,please write code for update or delete or
lock procedure,
THIS IS MY CODE:
PACKAGE table_of_array IS
type emp_rec is record(
empno emp.empno%type,
ename emp.ename%type,
sal emp.sal%type,
deptno emp.deptno%type
type arr is table of emp_rec
index by binary_integer;
procedure get_data(a in out table_of_array.arr);
procedure do_insert(a in out table_of_array.arr);
procedure do_update(a in out table_of_array.arr);
procedure do_delete(a in out table_of_array.arr);
END;
PACKAGE BODY table_of_array IS
procedure get_data(a in out table_of_array.arr)
is
i number:=0;
begin
for cur in (select empno,ename,sal,deptno from emp) loop
a(i):=cur;
i:=i+1;
end loop;
end;
procedure do_insert(a in out table_of_array.arr)
is
i number:=0;
cnt number:=a.count;
begin
for i in 1..cnt loop
insert into emp(empno,ename,sal,deptno)
values(a(i).empno,a(i).ename,a(i).sal,a(i).deptno);
end loop;
end;
procedure do_update(a in out table_of_array.arr)
is
begin
/* WHICH RECORD AND ITEM HAD BEEN UPDATED */
end;
procedure do_delete(a in out table_of_array.arr)
is
begin
/* WHICH RECORD HAD BEEN DELETED */
end;
END;
<pre>
1 create or replace procedure R_Leave_Balance ( aUserID in varchar2)
2 is
3 v_id varchar2(100);
4 v_LType number(2);
5 v_name varchar2(100);
6 v_LBalance number(3);
7 BEGIN
8 select b.vUserID,b.iLeaveType,t.vName,b.iLeaveBalance
9 INTO v_id,v_ltype,v_name,v_LBalance
10 from T_Leave_Balance b join T_Leave_Type t
11 on t.iID=b.iLeaveType where b.vUserID=aUserID;
12* END;
13 /
Warning: Procedure created with compilation errors.
SQL> show error;
Errors for PROCEDURE R_LEAVE_BALANCE:
LINE/COL ERROR
10/24 PLS-00103: Encountered the symbol "JOIN" when expecting one of
the following:
, ; for group having intersect minus order start union where connect
</pre>
Similar Messages
-
Failed to retrieve all the results. Try running the query or stored procedure again
I have a Product table in Azure SQL Database. I can't open data in Product table. I got an error message like this.."Failed to retrieve all the results. Try running the query or stored procedure again". In my Database
all tables showing their data expect Product table. Please let me know why only Product table showing error message. Thanks in Advance.Hi,
I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience
As this requires an expert advice, I suggest you to open a support case and our experts would be able to assist you further.
http://support2.microsoft.com/common/international.aspx?RDPATH=%2fdefault.aspx%3fid%3dfh%253ben-us%253bofferprophone
Girish Prajwal -
Hello
I'm hoping that someone here might be able to help or point me in the right direction. Apologies for the long post.
Just to set the scene, I am a SQL Server DBA and have very limited experience with System Centre so please go easy on me.
At the company I am currently working they are complaining about very poor performance when running reports (any).
Quick look at the database server and CPU utilisation being a constant 90-95%, meant that you dont have to be Sherlock Holmes to realise there is a problem. The instance consuming the majority of the CPU is the instance hosting the datawarehouse and in particular
a stored procedure in the DWStagingAndConfig database called Staging.GroomDwStagingData.
This stored procedure executes continually for 2 hours performing 500,000,000 reads per execution before "timing out". It is then executed again for another 2 hours etc etc.
After a bit of diagnosis it seems that the issue is either a bug or that there is something wrong with our data in that a stored procedure is stuck in an infinite loop
System Center 2012 SP1 CU2 (5.0.7804.1300)
Diagnosis details
SQL connection details
program name = SC DAL--GroomingWriteModule
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Store procedures executed
1. dbo.p_GetDwStagingGroomingConfig (executes immediately)
2. Staging.GroomDwStagingData (this is the procedure that executes in 2 hours before being cancelled)
The 1st stored procedure seems to return a table with the "xml" / required parameters to execute Staging.GroomDwStagingData
Sample xml below (cut right down)
<Config>
<Target>
<ModuleName>TransformActivityDim</ModuleName>
<WarehouseEntityName>ActivityDim</WarehouseEntityName>
<RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName>
<Watermark>2015-01-30T08:59:14.397</Watermark>
</Target>
<Target>
<ModuleName>TransformActivityDim</ModuleName>
<WarehouseEntityName>ActivityDim</WarehouseEntityName>
<RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName>
<ManagedTypeViewName>MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity</ManagedTypeViewName>
<Watermark>2015-01-30T08:59:14.397</Watermark>
</Target>
</Config>
If you look carefully you will see that the 1st <target> is missing the ManagedTypeViewName, which when "shredded" by the Staging.GroomDwStagingData returns the following result set
Example
DECLARE @Config xml
DECLARE @GroomingCriteria NVARCHAR(MAX)
SET @GroomingCriteria = '<Config><Target><ModuleName>TransformActivityDim</ModuleName><WarehouseEntityName>ActivityDim</WarehouseEntityName><RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName><Watermark>2015-01-30T08:59:14.397</Watermark></Target><Target><ModuleName>TransformActivityDim</ModuleName><WarehouseEntityName>ActivityDim</WarehouseEntityName><RequiredWarehouseEntityName>MTV_System$WorkItem$Activity</RequiredWarehouseEntityName><ManagedTypeViewName>MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity</ManagedTypeViewName><Watermark>2015-01-30T08:59:14.397</Watermark></Target></Config>'
SET @Config = CONVERT(xml, @GroomingCriteria)
SELECT
ModuleName = p.value(N'child::ModuleName[1]', N'nvarchar(255)')
,WarehouseEntityName = p.value(N'child::WarehouseEntityName[1]', N'nvarchar(255)')
,RequiredWarehouseEntityName =p.value(N'child::RequiredWarehouseEntityName[1]', N'nvarchar(255)')
,ManagedTypeViewName = p.value(N'child::ManagedTypeViewName[1]', N'nvarchar(255)')
,Watermark = p.value(N'child::Watermark[1]', N'datetime')
FROM @Config.nodes(N'/Config/*') Elem(p)
/* RESULTS - NOTE THE NULL VALUE FOR ManagedTypeViewName
ModuleName WarehouseEntityName RequiredWarehouseEntityName ManagedTypeViewName Watermark
TransformActivityDim ActivityDim MTV_System$WorkItem$Activity NULL 2015-01-30 08:59:14.397
TransformActivityDim ActivityDim MTV_System$WorkItem$Activity MTV_Microsoft$SystemCenter$Orchestrator$RunbookAutomationActivity 2015-01-30 08:59:14.397
When the procedure enters the loop to build its dynamic SQL to delete relevant rows from the inbound schema tables it concatenates various options / variables into an executable string. However when adding a NULL value to a string the entire string becomes
NULL which then gets executed.
Whilst executing "EXEC(NULL)" would cause SQL to throw an error and be caught, executing the following doesnt
DECLARE @null_string VARCHAR(100)
SET @null_string = 'hello world ' + NULL
EXEC(@null_string)
SELECT @null_string
So as it hasnt caused an error the next part of the procedure is to move to the next record and this is why its caught in an infinite loop
DELETE @items WHERE ManagedTypeViewName = @View
The value for the variable @View is the ManagedTypeViewName which is NULL, as ANSI_NULLS are set to ON in the connection and not overridded in the procedure then the above statement wont delete anything as it needs to handle NULL values differently (IS NULL),
so we are now stuck in an infinite loop executing NULL for 2 hours until cancelled.
I amended the stored procedure and added the following line before the loop statement which had the desired effect and "fixed" the performance issue for the time being
DELETE @items WHERE ManagedTypeViewName IS NULL
I also noticed that the following line in dbo.p_GetDwStagingGroomingConfig is commented out (no idea why as no notes in the procedure)
--AND COALESCE(i.ManagedTypeViewName, j.RelationshipTypeViewName) IS NOT NULL
There are obviously other ways to mitigate the dynamic SQL string being NULL, there's more than one way to skin a cat and thats not why I am asking this question, but what I am concerned about is that is there a reason that the xml / @GroomingCriteria is incomplete
and / or that the procedures dont handle potential NULL values.
I cant find any documentation, KBs, forum posts of anyone else having this issue which somewhat surprises me.
Would be grateful of any help / advice that anyone can provide or if someone can look at their 2 stored procedures on a later version to see if it has already been fixed. Or is it simply that we have orphaned data, this is the bit that concerns most as I dont
really want to be deleting / updating data when I have no idea what the knock on effect might be
Many many thanks
AndyFirst thing I would do is upgrade to 2012 R2 UR5. If you are running non-US dates you need the UR5 hotfix also.
Rob Ford scsmnz.net
Cireson www.cireson.com
For a free SCSM 2012 Notify Analyst app click
here -
How can I check a Remote Database is alive in a Stored Procedure
Hi
In a PL/SQL stored procedure, I do a select from a table on a remote database via the database link. There is a Loop around the select as it waits for a flag to be set on the remote table. However, on several occasions, while looping, the remote database has gone down and the procedure then fails with error:
'Details ORA-02068: following severe error from ORA-02068: following severe error from 'Remote Database ' ORA-01033: ORACLE initialization or shutdown in progress ORA-06512: at "Current Database.Stored Procedure", line'
Is it possible to trap this error and prevent the procedure from crashing?
My current code is like:-
LOOP
SELECT flag
INTO v_flag
FROM remote_table@remote_db;
IF v_flag= 'OK'
THEN
< Run Oracle Warehouse Builder Process Flow >
EXIT;
ELSE dbms_lock.sleep(600);
END IF;
END LOOP;
Any help with this would be appreciated.
Thanks
GBHi Bernd
Thanks for your help. If I do this, I think the procedure would continue onto the 'IF' statement. I am looking for a way of looping round and trying to run the select again before moving on.
If I did something like
LOOP --- Loop 1 ---
LOOP --- Loop 2---
BEGIN
SELECT flag
INTO v_flag
FROM remote_table@remote_db;
EXCEPTION WHEN OTHERS THEN NULL;
END;
-- Need to exit if no exception ---
END LOOP;
IF v_flag= 'OK'
THEN
< Run Oracle Warehouse Builder Process Flow >
EXIT;
ELSE dbms_lock.sleep(600);
END IF;
END LOOP;
Is there a way of going back to the start of Loop 2 if there was an exception, otherwise EXIT and continue onto the 'IF' statement. -
Retrieve a number from a stored procedure
I need to retrieve the number of rows returned from a query in a stored procedure. This is what I currently have:
PACKAGE PART_DATA AS
FUNCTION GetPartDataRowCount(Company IN PART_DATA.PART1_CO_SITE%TYPE) RETURN NUMBER;
END;
PACKAGE BODY PART_DATA AS
FUNCTION GetPartDataRowCount
Company IN PART_DATA.PART1_CO_SITE%TYPE
RETURN NUMBER
IS
RecordCount NUMBER;
BEGIN
SELECT COUNT(*)
INTO RecordCount
FROM PART_DATA
WHERE PART1_CO_SITE = Company;
RETURN RecordCount;
END GetPartDataRowCount;
END;
And the .NET part:
Public Function GetPartDataRowCount(ByVal Company As String) As Integer
Dim con As New OracleConnection(MyConnectionString)
'Open the connection
con.Open()
'Set the command text, type and connection
Dim cmd As New OracleCommand("PART_DATA.GetPartDataRowCount", con)
cmd.CommandType = CommandType.StoredProcedure
'Create parameter objects
Dim returnValue As New OracleParameter
returnValue.Direction = ParameterDirection.ReturnValue
returnValue.DbType = DbType.Int32
cmd.Parameters.Add(returnValue)
Dim pCompany As New OracleParameter
pCompany.Direction = ParameterDirection.Input
pCompany.DbType = DbType.AnsiStringFixedLength
pCompany.Value = Company
cmd.Parameters.Add(pCompany)
'Execute the query
cmd.ExecuteNonQuery()
'Capture the returned value
Dim rowCount As Integer = Convert.ToInt32(returnValue.Value)
'Return the returned value
Return rowCount
'Clean up objects
returnValue.Dispose()
cmd.Dispose()
con.Dispose()
End Function
I am using this as the SelectCountMethod on an ObjectDataSource for custom paging a GridView. Everything is working but because I'm new to Oracle I can't help thinking that there is a better way to achieve what I need, also I am confused as to whether I should be using a Function or a Procedure in my Package for this.
I would be grateful if someone could either confirm that what I am doing is the best/correct method or show me what I should be doing instead.
Any help much appreciated.Thanks Eric, that is a big help and has made things clearer for me. However I cannot get this to work using a Procedure instead of a Function. Just for the sake of completeness I would also like to make it work with a Procedure.
Here is what I have:
PACKAGE PART_DATA AS
PROCEDURE GetPartDataRowCount(mtmsCompany IN PART_DATA.PART1_CO_SITE%TYPE,rowCount OUT NUMBER);
END;
PACKAGE BODY PART_DATA AS
PROCEDURE GetPartDataRowCount
mtmsCompany IN PART_DATA.PART1_CO_SITE%TYPE,
rowCount OUT NUMBER
IS
BEGIN
SELECT COUNT(*)
INTO rowCount
FROM PART_DATA
WHERE PART1_CO_SITE = mtmsCompany;
END GetPartDataRowCount;
END;
And the .NET code:
Public Function GetPartDataRowCount(ByVal Company As String) As Integer
'Open the connection
con.Open()
'Set the command text and type
Dim cmd As New OracleCommand("PART_DATA.GetPartDataRowCount", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.BindByName = True
'Create parameter objects
Dim rowCount As New OracleParameter
rowCount.Direction = ParameterDirection.Output
rowCount.DbType = DbType.Int32
cmd.Parameters.Add(rowCount)
Dim mtmsCompany As New OracleParameter
mtmsCompany.Direction = ParameterDirection.Input
mtmsCompany.DbType = DbType.AnsiStringFixedLength
mtmsCompany.Value = Company
cmd.Parameters.Add(mtmsCompany)
(Exception handling is done in Global.asax hence no Try/Finally)
'Execute the query
cmd.ExecuteScalar()
'Capture the returned value
Dim returnValue As Integer = Convert.ToInt32(rowCount.Value)
'Return the returned value
Return returnValue
'Clean up objects
RowCount.Dispose()
cmd.Dispose()
con.Dispose()
End Function
The package compiles without errors, but when I run the app I get the following error:
Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 39: PLS-00103: Encountered the symbol ">" when expecting one of the following:
It then gives a long list of things it was expecting. Do I also need to return a Ref Cursor?
Once again any help much appreciated. -
Can you get values back from a stored procedure via OUTPUT parameters?
Can you get values back from calling a stored procedure via OUTPUT parameters/variables? I call the SP via a SQL statement from a script either in a WF or DF.
I thought I read some reference that DI could not get the values from OUTPUT parameters but I could not find it again (don't know if it is in any of the documentation or referred to in a forum.
I did try a couple of tests but it did not reutrn any values via OUTPUT. But before I give up I thought I'd see if you could and maybe I needed to change something.This isn't exactly an answer to your question, but I'll point out that, given that you're resorting to a SQL script in the first place, there's no reason you can't also turn the output parameters into a regular result or record set. (The following uses T-SQL, although I think it's pretty generic.)
declare @param1 int, param2 varchar(100), @return int;
exec @return = proc @param1 = @param1 output, @param2 = @param2 output;
select @param1 as param1, @param2 as param2;
That is, to get from output parameters to a "regular" output from the SQL script isn't much of a leap...
Jeff Prenevost
BI Consultant
Ann Arbor, MI -
Get returned value of a stored procedure
if a stored procedure ends with the following:
select "status"=1 or simply select 1 or return 1
how do I get the value in the call of the jsp page?
ThanksDO NEVER EVER CALL YOUR DATABASE FROM A JSP!
Have a servlet to call a class that gathers and
processes the data, and that gives you a value
object.
public class Row {
public final int key;
public final String status;
public final String name;
public final Date timestamp;
// ... and so forth.
Row(int i, string s, String n, Date t ...) {
}An instance of this immutably represents a row of
data. Return this to the servlet, have the servlet
add it to the session and retrieve it again in your
JSP:
<td>status: </td><td><%= myDataObject.status
%></td>
Right on. This is the most common malpractice I ahve come across. Accessing the database from with in a jsp is violation of seperation of concerns as well as MVC. Not only would I suggest using a servlet but I would add use the servlet as a controller and for rest use beans and model code. -
Report Using A Stored Procedure Is Caching Data
Post Author: springerc69
CA Forum: Data Connectivity and SQL
I converted a report from a view that worked fine to a stored procedure to try and improve the performance of the report, but when I publish the report it seems to cache the data. When you change the parameters you use to call the report or simply run the report again with the original parameters the report doesn't run the sproc and just shows the cached data from the original request. If I right click on the report and select refresh (web based crystal report), it prompts for the parameters. I just close out the prompt window, report window and click on the link for the report again it returns the correct results based on the new parameters or a refresh based on the original parameters. I've checked the cache time setting and set it to 0, and if you close the Internet Explorer window that originally called the report, open IE back up and request the report it will return the appropriate data. I have also verify that the report is not setup to save data with report. This is on Crystal XI Server.Post Author: synapsevampire
CA Forum: Data Connectivity and SQL
Which viewer are you using?
It might be that your IE settings are caching the report pages. because you're using an HTML viewer.
Try the Active-X viewer.
I've forgotten which icon it is that changes the viewer...it's under the preferences options, I think it's the one that looks like a hunk of cheese on the right upper side.
-k -
I select the shared datasource from the data source propeties dialog, test the connection and everything is good.
I add a dataset by selecting "use a dataset embedded in my report" option within the Dataset properties dialog.
I select the newly added data source, click the "Stored procedure" query type and drop down the list box and select my intended stored procedure.
the timeout for the dataset is "0" seconds.
I click the "OK" button and I'm presented with the parameters to the stored procedure.
I enter valid data for the parameters and click the "OK" button.
I then get the following error message after 30 seconds:
The problem is, all of the timeouts, that I'm aware of, have values of zero (no timeout) or high enough values that 30 seconds isn't even close to the timeout.
I think the smallest timeout we have is 120 seconds.
I have searched this site and many others and the solutions all involve altering the stored procedure to get the fields into report builder and then revert the stored procedure back to its original form.
To me, this is NOT a solution.
I have too many stored procedures that need to be brought into Report Builder.
I need a real solution.
Thank you for you time, Tim Caldwell.
Timothy E CaldwellI don't mean to be rude, but really, check to see if the stored procedure can return data rows???
Maybe I'm not being clear enough.
The stored procedure runs perfectly fine.
it runs perfectly fine in the production environment and the test environment.
I can access the stored procedure in several ways and have it return correct data.
I can even trick report builder into creating a dataset with parameters and run the stored procedure that way.
What I cannot do, is to get report builder to not timeout after 30 seconds on the initial creation of a dataset with a Query type of stored procedure.
I have seen this issues posted again and again and again on may different sites and the "solution" is to simplifiy the stored procedure by creating a stored procedure that has a create table and a select in the stored procedure and that's it. After
report builder creates the dataset the developer then has to replace the simplified stored procedure with the actual stored procedure and everything works fine after that.
HOWEVER, having to go through this process for 70 or more stored procedures is ridiculous.
It would appear that there is something within report builder itself that is causing this issue.
The SQL Script included is an example of a stored procedure that will not create fields create a dataset with fields and parameters in Report Builder 3.0:
USE [CRUM_IT]
GO
/****** Object: StoredProcedure [dbo].[COGNOS_Level5ScriptSP] Script Date: 11/17/2014 08:02:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[COGNOS_Level5ScriptSP]
@CompanyCode varchar(8) = null,
@GetSiblings varchar(1) = 'N'
as
Begin
-- get emergency contact info
select *
into #tmp_Contacts
from
(select
ConEEID,
con.connamelast as [Emer Contact Last Name],
con.connamefirst as [Emer Contact First Name],
con.connamemiddle as [Emer Contact Middle Initial/Name]--,
,ROW_NUMBER() over (Partition by ConEEID order by ConNameLast)as rn
,ISNULL(
case when con.conphonepreferred = 'H'
then '(' + substring(con.conphonehomenumber, 1, 3) + ')' + substring(con.conphonehomenumber, 4, 3) + '-' + substring(con.conphonehomenumber, 7, 4)
else '(' + substring(con.conphoneothernumber , 1, 3) + ')' + substring(con.conphoneothernumber , 4, 3) + '-' + substring(con.conphoneothernumber , 7, 4)
end,
) as [Emergency Phone]
from [ultiprosqlprod1].[ultipro_crum].dbo.Contacts con
where con.ConIsEmergencyContact='y'
and con.ConIsActive='y'
) A
where A.rn = 1
CREATE TABLE #tmp_CompanyCodes (CompanyCode varchar(8))
If @GetSiblings = 'Y'
Begin
INSERT INTO #tmp_CompanyCodes (CompanyCode)
EXEC [z_GetClientNumbers_For_ParentOrg_By_ClientNumber] @CompanyCode
End
INSERT INTO #tmp_CompanyCodes
values (@CompanyCode)
select *
into #tmp_Company
from [ultiprosqlprod1].[ultipro_crum].dbo.Company
where cmpcompanycode in (select CompanyCode from #tmp_CompanyCodes)
select distinct
cmpcompanycode as [Client ID],
CmpCompanyDBAName as [Client Name],
eec.eecEmplStatus AS [Employment Status],
eec.eecEmpNo AS [Employee Num],
rtrim(eep.eepNameLast) AS [Last Name],
rtrim(eep.eepNameFirst) AS [First Name],
isnull(rtrim(ltrim(eep.eepNameMiddle)), '') AS [Middle Initial/Name],
rtrim(eep.eepAddressLine1) AS [Address Line 1],
isnull(rtrim(eep.eepAddressLine2), '') AS [Address Line 2],
eep.eepAddressCity AS [City],
eep.eepAddressState AS [State],
CASE
WHEN len(eep.eepAddressZipCode) > 5 and charindex(eep.eepAddressZipCode, '-', 1) = 0
THEN substring(eep.eepAddressZipCode, 1, 5)
ELSE rtrim(eep.eepAddressZipCode)
END AS [Zip code],
CASE
WHEN len(eep.eepAddressZipCode) > 5 and charindex(eep.eepAddressZipCode, '-', 1) = 0
THEN substring(eep.eepAddressZipCode, 6, 4)
WHEN len(eep.eepAddressZipCode) > 5 and charindex(eep.eepAddressZipCode, '-', 1) > 0
THEN substring(eep.eepAddressZipCode, charindex(eep.eepAddressZipCode, '-', 1) + 1, 4)
WHEN len(eep.eepAddressZipCode) <= 5
THEN ''
END AS [ZIP + 4],
substring(eep.eepSSN, 1, 3) + '-' + substring(eep.eepSSN, 4, 2) + '-' + substring(eep.eepSSN, 6, 4) AS [SSN],
isnull(convert(VARCHAR(10), eep.eepDateOfBirth, 101), '') AS [Date Of Birth],
eetFED.TAXCODE AS [FED Tax Code],
eetFED.FILINGSTATUS AS [Fed Filing Status],
eetFED.EXEMPTIONS AS [Fed Exemption Allowance],
eetFED.ADDITIONAL AS [Additional Fed Withholding],
eetSIT.TAXCODE AS [SIT Tax Code],
eetSIT.FILINGSTATUS AS [State Filing Status],
eetSIT.EXEMPTIONS AS [State Exemption Allowance],
eetSIT.ADDITIONAL AS [Additional State Withholding],
isnull('(' + substring(eep.eepPhoneHomeNumber, 1, 3) + ')' + substring(eep.eepPhoneHomeNumber, 4, 3) + '-' + substring(eep.eepPhoneHomeNumber, 7, 4), '') AS [Home Phone],
isnull((SELECT cod.codDesc
FROM [ultiprosqlprod1].[ultipro_crum].dbo.Codes cod WITH (NOLOCK)
WHERE cod.codCode = eep.eepEthnicID
AND cod.codDosTable = 'ETHNICCODE'), '') AS [Race-Origin], --eep.eepEthnicID AS [Race-Origin],
eep.eepGender AS [Gender],
isnull(convert(VARCHAR(10), eec.eecDateOfOriginalHire, 101), '') AS [Original Hire Date],
isnull(convert(VARCHAR(10), eec.eecDateOfSeniority, 101), '') AS [Seniority Date],
isnull(convert(VARCHAR(10), eec.eecDateOfTermination, 101), '') AS [Termination Date],
isnull(eecTermType,'') as [Termination Type],
isnull(TchDesc, '') as [Termination Reason],
rtrim(eec.eecJobCode) AS [WC Code],
isnull(eec.eecJobTitle, '') AS [Job Title],
pgr.pgrPayFrequency AS [Pay Frequency],
eec.eecFullTimeOrPartTime AS [Full/Part Time],
eec.eecSalaryOrHourly AS [Pay Type],
isnull(convert(MONEY, eec.eecHourlyPayRate), 0.00) AS [Hourly Rate],
isnull(eec.eecAnnSalary, 0.00) AS [Annual Salary],
[YTD Hours],
isnull(eep.eepNameFormer, '') AS [Maiden Name],
eec.eecLocation AS [Location ID],
rtrim(eec.eecOrgLvl1) AS [Department ID],
eec.eecorglvl2 AS [Cost Item],
eec.eecorglvl3 as [Client Project],
eec.eecPayGroup as [Pay Group],
isnull(eepAddressEMail,' ') as [Email Address],
isNull(BankName1,' ') as PrimaryBank,
isNull(BankRoute1,' ') as PrimaryRouteNum,
isNull(Account1,' ') as PrimaryAccount,
isNull(AcctType1,' ') as PrimaryAcctType,
isNull(DepositRule1,' ') as PrimaryDepositRule,
isNull(BankName2,' ') as SecondaryBank,
isNull(BankRoute2,' ') as SecondaryRouteNum,
isNull(Account2,' ') as SecondaryAccount,
isNull(AcctType2,' ') as SecondaryAcctType,
isNull(DepositRule2,' ') as SecondaryDepositRule,
isNull(
CASE
WHEN DepositRule2 = 'D'
THEN '$' + convert(varchar, cast(EddAmtOrPct2 AS decimal(10,2)))
WHEN DepositRule2 = 'P'
THEN convert(varchar, cast((EddAmtOrPct2*100) AS decimal(10,0))) + '%'
ELSE null
END,' ') as SecondaryDepositAmount,
isNull(BankName3,' ') as ThirdBank,
isNull(BankRoute3,' ') as ThirdRouteNum,
isNull(Account3,' ') as ThirdAccount,
isNull(AcctType3,' ') as ThirdAcctType,
isNull(DepositRule3,' ') as ThirdDepositRule,
isNull(
CASE
WHEN DepositRule3 = 'D'
THEN '$' + convert(varchar, cast(EddAmtOrPct3 AS decimal(10,2)))
WHEN DepositRule3 = 'P'
THEN convert(varchar, cast((EddAmtOrPct3*100) AS decimal(10,0))) + '%'
ELSE null
END,' ') as ThirdDepositAmount,
Supervisor,
eec.eecEEID AS [Employee EEID],
eec.EecJobCode As [Job Code],
isnull(eec.EecTimeclockID,' ') As [Time Clock ID],
con.[Emer Contact Last Name],
con.[Emer Contact First Name],
con.[Emer Contact Middle Initial/Name],
con.[Emergency Phone]
from [ultiprosqlprod1].[ultipro_crum].dbo.empPers eep WITH (NOLOCK)
inner join [ultiprosqlprod1].[ultipro_crum].dbo.empComp eec WITH (NOLOCK)
ON eep.eepEEID = eec.eecEEID
inner join #tmp_Company cmp WITH (NOLOCK)
ON eec.eecCOID = cmp.cmpCOID
inner join [ultiprosqlprod1].[ultipro_crum].dbo.PayGroup pgr WITH (NOLOCK)
ON eec.eecPayGroup = pgr.pgrPayGroup
left outer join [ultiprosqlprod1].[ultipro_crum].dbo.TrmReasn
on tchCode = eecTermReason
left join (select CAST(sum(isnull(eee.eeeYTDHrs,0.00))AS DECIMAL(18,2)) as [YTD Hours],
eeeEEID,
eeeCOID
from [ultiprosqlprod1].[ultipro_crum].dbo.EmpEarn eee with (NOLOCK)
group by eeeCOID,eeeEEID)eee
on eec.eecEEID = eee.eeeEEID
and eec.eecCOID = eee.eeeCOID
left join (SELECT eetCOID AS COID,
eetEEID AS EEID,
eetTaxCode AS TAXCODE,
eetFilingStatus AS FILINGSTATUS,
eetExemptions AS EXEMPTIONS,
eetExtraTaxDollars AS ADDITIONAL
FROM [ultiprosqlprod1].[ultipro_crum].dbo.empTax WITH (NOLOCK)
WHERE eetTaxCode = 'USFIT'
)eetFED
ON eec.eecCOID = eetFED.COID
and eec.eecEEID = eetFED.EEID
left join (SELECT eetCOID AS COID,
eetEEID AS EEID,
eetTaxCode AS TAXCODE,
eetFilingStatus AS FILINGSTATUS,
eetExemptions AS EXEMPTIONS,
eetExtraTaxDollars AS ADDITIONAL
FROM [ultiprosqlprod1].[ultipro_crum].dbo.empTax WITH (NOLOCK)
WHERE eetTaxCode like '%SIT'
AND eetIsWorkInTaxCode = 'Y'
)eetSIT
ON eec.eecCOID = eetSIT.COID
and eec.eecEEID = eetSIT.EEID
left outer join (SELECT eddCOID,
eddEEID,
eddEEBankName BankName1,
eddEEBankRoute BankRoute1,
eddAcct Account1,
EddAcctType AcctType1,
EddDepositRule DepositRule1,
EddAmtOrPct EddAmtOrPct1
FROM [ultiprosqlprod1].[ultipro_crum].dbo.EmpDirDp WITH (NOLOCK)
WHERE eddSequence = '99')edd
ON eec.eecCOID = edd.eddCOID
and eec.eecEEID = edd.eddEEID
left outer join (SELECT eddCOID,
eddEEID,
eddEEBankName BankName2,
eddEEBankRoute BankRoute2,
eddAcct Account2,
EddAcctType AcctType2,
EddDepositRule DepositRule2,
EddAmtOrPct EddAmtOrPct2
FROM [ultiprosqlprod1].[ultipro_crum].dbo.EmpDirDp WITH (NOLOCK)
WHERE eddSequence = '01')edd2
ON eec.eecCOID = edd2.eddCOID
and eec.eecEEID = edd2.eddEEID
left outer join (SELECT eddCOID,
eddEEID,
eddEEBankName BankName3,
eddEEBankRoute BankRoute3,
eddAcct Account3,
EddAcctType AcctType3,
EddDepositRule DepositRule3,
EddAmtOrPct EddAmtOrPct3
FROM [ultiprosqlprod1].[ultipro_crum].dbo.EmpDirDp WITH (NOLOCK)
WHERE eddSequence = '02')edd3
ON eec.eecCOID = edd3.eddCOID
and eec.eecEEID = edd3.eddEEID
left outer join (SELECT eecCOID,
eecEEID,
rtrim(eepNameLast) + ', ' +
rtrim(eepNameFirst) + ' ' +
isnull(rtrim(ltrim(eepNameMiddle)), '') AS [Supervisor]
FROM [ultiprosqlprod1].[ultipro_crum].dbo.EmpComp WITH (NOLOCK)
join [ultiprosqlprod1].[ultipro_crum].dbo.EmpPers with (NoLock)
on eeceeid = eepeeid)eec2
ON eec.eecSupervisorID = eec2.eecEEID
left outer join #tmp_Contacts con
on eep.eepEEID = con.ConEEID
order by [Client ID],
[Last Name],
[First Name]
drop table #tmp_Contacts
END
Timothy E Caldwell -
Need help with BC4J/Struts application using a Stored Procedure
Hi,
I am doing a proof of concept for a new project using JDeveloper, Struts and BC4J. We want to reuse our Business logic that is currently residing in Oracle Stored Procedures. I previously created a BC4J Entity Object based on a stored procedure Using Oracle Stored Procedures but this stored procedure is a bit different in that it returns a ref cursor as one of the paramters. http://radio.weblogs.com/0118231/stories/2003/03/03/gettingAViewObjectsResultRowsFromARefCursor.html
I tried the above method, but I am having some trouble with it. I keep getting the error ORA-01008: not all variables are bound when I test it using the AppModule tester.
Here is the store procedure definition:
CREATE OR REPLACE PACKAGE pprs_test_wrappers IS
TYPE sn_srch_results IS REF CURSOR;
PROCEDURE sn_srch_main_test
(serial_num_in IN OUT VARCHAR2
,serial_coll_cd_in IN OUT NUMBER
,max_rows_allowed IN OUT NUMBER
,total_rows_selected IN OUT NUMBER
,message_cd_out IN OUT VARCHAR2
,query_results OUT sn_srch_results
END pprs_test_wrappers;
And here is my code:
package pprs;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import oracle.jbo.JboException;
import oracle.jbo.domain.Number;
import oracle.jbo.server.DBTransaction;
import oracle.jbo.server.ViewObjectImpl;
import oracle.jbo.server.ViewRowImpl;
import oracle.jbo.server.ViewRowSetImpl;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
// --- File generated by Oracle Business Components for Java.
public class LienCheckImpl extends ViewObjectImpl
* This is the PLSQL block that we will execute to retrieve the REF CURSOR
private static final String SQL =
"begin ? := pprs_test_wrappers.sn_srch_main_test(?, ?, ?, ?, ?, ?);end;";
public LienCheckImpl() {}
* Overridden framework method.
* Executed when the framework needs to issue the database query for
* the query collection based on this view object. One view object
* can produce many related result sets, each potentially the result
* of different bind variable values. If the rowset in query is involved
* in a framework-coordinated master/detail viewlink, then the params array
* will contain one or more framework-supplied bind parameters. If there
* are any user-supplied bind parameter values, they will PRECEED the
* framework-supplied bind variable values in the params array, and the
* number of user parameters will be indicated by the value of the
* numUserParams argument.
protected void executeQueryForCollection(Object qc,Object[] params,int numUserParams) {
* If there are where-clause params (for example due to a view link)
* they will be in the 'params' array.
* We assume that if some parameter is present, that it is a Deptno
* value to pass as an argument to the stored procedure.
* NOTE: Due to Bug#2828248 I have to cast to BigDecimal for now,
* ---- but this parameter value should be oracle.jbo.domain.Number type.
String serialNumIn = null;
BigDecimal serialCollCdIn = null;
BigDecimal maxRowsAllowed = null;
BigDecimal totalRowsSelected = null;
String messageCdOut = null;
if (params != null) {
serialNumIn = (String)params[0];
serialCollCdIn = (BigDecimal)params[1];
maxRowsAllowed = (BigDecimal)params[2];
totalRowsSelected = (BigDecimal)params[3];
messageCdOut = (String)params[4];
storeNewResultSet(qc,retrieveRefCursor(qc,serialNumIn,
serialCollCdIn,
maxRowsAllowed,
totalRowsSelected,
messageCdOut));
super.executeQueryForCollection(qc, params, numUserParams);
* Overridden framework method.
* Wipe out all traces of a built-in query for this VO
protected void create() {
getViewDef().setQuery(null);
getViewDef().setSelectClause(null);
setQuery(null);
* Overridden framework method.
* The role of this method is to "fetch", populate, and return a single row
* from the datasource by calling createNewRowForCollection() and populating
* its attributes using populateAttributeForRow().
protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet rs) {
* We ignore the JDBC ResultSet passed by the framework (null anyway) and
* use the resultset that we've stored in the query-collection-private
* user data storage
rs = getResultSet(qc);
* Create a new row to populate
ViewRowImpl r = createNewRowForCollection(qc);
try {
* Populate new row by attribute slot number for current row in Result Set
populateAttributeForRow(r,0, nullOrNewNumber(rs.getBigDecimal(1)));
populateAttributeForRow(r,1, nullOrNewNumber(rs.getBigDecimal(2)));
populateAttributeForRow(r,2, rs.getString(3));
populateAttributeForRow(r,3, rs.getString(4));
populateAttributeForRow(r,4, rs.getString(5));
catch (SQLException s) {
throw new JboException(s);
return r;
* Overridden framework method.
* Return true if the datasource has at least one more record to fetch.
protected boolean hasNextForCollection(Object qc) {
ResultSet rs = getResultSet(qc);
boolean nextOne = false;
try {
nextOne = rs.next();
* When were at the end of the result set, mark the query collection
* as "FetchComplete".
if (!nextOne) {
setFetchCompleteForCollection(qc, true);
* Close the result set, we're done with it
rs.close();
catch (SQLException s) {
throw new JboException(s);
return nextOne;
* Overridden framework method.
* The framework gives us a chance to clean up any resources related
* to the datasource when a query collection is done being used.
protected void releaseUserDataForCollection(Object qc, Object rs) {
* Ignore the ResultSet passed in since we've created our own.
* Fetch the ResultSet from the User-Data context instead
ResultSet userDataRS = getResultSet(qc);
if (userDataRS != null) {
try {
userDataRS.close();
catch (SQLException s) {
/* Ignore */
super.releaseUserDataForCollection(qc, rs);
* Return a JDBC ResultSet representing the REF CURSOR return
* value from our stored package function.
private ResultSet retrieveRefCursor(Object qc,
String serialNum,
BigDecimal serialColCd,
BigDecimal maxRows,
BigDecimal totalRows,
String messageCd ) {
CallableStatement st = null;
try {
st = getDBTransaction().createCallableStatement(SQL,DBTransaction.DEFAULT);
* Register the first bind parameter as our return value of type CURSOR
st.registerOutParameter(1,OracleTypes.CURSOR);
* Set the value of the 2nd bind variable to pass id as argument
if (serialNum == null) st.setNull(2,Types.CHAR);
else st.setString(2,serialNum);
if (serialColCd == null) st.setNull(3,Types.NUMERIC);
else st.setBigDecimal(3,serialColCd);
if (maxRows == null) st.setNull(4,Types.NUMERIC);
else st.setBigDecimal(4,maxRows);
if (totalRows == null) st.setNull(5,Types.NUMERIC);
else st.setBigDecimal(5,totalRows);
if (messageCd == null) st.setNull(6,Types.CHAR);
else st.setString(6,messageCd);
st.execute();
ResultSet rs = ((OracleCallableStatement)st).getCursor(1);
* Make this result set use the fetch size from our View Object settings
rs.setFetchSize(getFetchSize());
return rs ;
catch (SQLException s) {
throw new JboException(s);
finally {try {st.close();} catch (SQLException s) {}}
* Store a new result set in the query-collection-private user-data context
private void storeNewResultSet(Object qc, ResultSet rs) {
ResultSet existingRs = getResultSet(qc);
// If this query collection is getting reused, close out any previous rowset
if (existingRs != null) {
try {existingRs.close();} catch (SQLException s) {}
setUserDataForCollection(qc,rs);
hasNextForCollection(qc); // Prime the pump with the first row.
* Retrieve the result set wrapper from the query-collection user-data
private ResultSet getResultSet(Object qc) {
return (ResultSet)getUserDataForCollection(qc);
* Return either null or a new oracle.jbo.domain.Number
private static oracle.jbo.domain.Number nullOrNewNumber(BigDecimal b) {
try {
return b != null ? new oracle.jbo.domain.Number(b) : null;
catch (SQLException s) { }
return null;
I created the view object in expert mode so there is no entity object. Can someone help? I don't have much time left to finish this.
Also, could I have done this from the Entity object instead of the view object by registering the ref cursor OUT parameter in handleStoredProcInsert()?
Thanks
NatalieI was able to get the input parameter by putting the following in my struts actions class
vo.setWhereClauseParam(0,request.getParameter("row0_SerialNum"));
The full code is:
package mypackage2;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import oracle.jbo.html.BC4JContext;
import oracle.jbo.ViewObject;
import oracle.jbo.html.struts11.BC4JUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class LienCheckView1QueryAction extends Action
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
BC4JContext context = BC4JContext.getContext(request);
// Retrieve the view object instance to work with by name
ViewObject vo = context.getApplicationModule().findViewObject("LienCheckView1");
vo.setRangeSize(3);
vo.setIterMode(ViewObject.ITER_MODE_LAST_PAGE_PARTIAL);
// Do any additional VO setup here (e.g. setting bind parameter values)
vo.setWhereClauseParam(0,request.getParameter("row0_SerialNum"));
// default value for serialCollCd 1 is for Motor Vehicles
vo.setWhereClauseParam(1,new oracle.jbo.domain.Number(1));
// Default value for maxRows_allowed
vo.setWhereClauseParam(2,new oracle.jbo.domain.Number(20));
return BC4JUtils.getForwardFromContext(context, mapping);
This doesn't always work properly though. The first time I press the query button, the SerialNum parameter is still null, however if I re-execute the query by pressing the query button again. It will work, and return the rows. I always have to query twice. Also the SerialNum attribute is set to a String in my view object, it is a varchar column in the database, but some serial number I enter give a "Error Message: oracle.jbo.domain.Number ". This happens even though the underlying BC4J is returning values for the query. I also get a "500 Internal Server Error java.lang.ClassCastException: java.lang.String on my View object's code at line 65 which is
if (params.length>1) serialCollCdIn = (BigDecimal)params[1];
This is an input paramter to the oracle stored procedure that defaults to a Number value of 1.
Any idea what the problem is? Here is the full code for my view object:
package mypackage1;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import oracle.jbo.JboException;
import oracle.jbo.domain.Number;
import oracle.jbo.server.DBTransaction;
import oracle.jbo.server.ViewObjectImpl;
import oracle.jbo.server.ViewRowImpl;
import oracle.jbo.server.ViewRowSetImpl;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
// --- File generated by Oracle Business Components for Java.
public class LienCheckViewImpl extends ViewObjectImpl
* This is the PLSQL block that we will execute to retrieve the REF CURSOR
private static final String SQL =
"begin pprs_test_wrappers.sn_srch_main_test(?, ?, ?, ?, ?, ?);end;";
private BigDecimal totalRows = null;
private String messageCd = null;
private BigDecimal serialColCd = null;
private BigDecimal maxRows = null;
public LienCheckViewImpl() {}
* Overridden framework method.
* Executed when the framework needs to issue the database query for
* the query collection based on this view object. One view object
* can produce many related result sets, each potentially the result
* of different bind variable values. If the rowset in query is involved
* in a framework-coordinated master/detail viewlink, then the params array
* will contain one or more framework-supplied bind parameters. If there
* are any user-supplied bind parameter values, they will *PRECEED* the
* framework-supplied bind variable values in the params array, and the
* number of user parameters will be indicated by the value of the
* numUserParams argument.
protected void executeQueryForCollection(Object qc,Object[] params,int numUserParams) {
* If there are where-clause params (for example due to a view link)
* they will be in the 'params' array.
* We assume that if some parameter is present, that it is a Deptno
* value to pass as an argument to the stored procedure.
* NOTE: Due to Bug#2828248 I have to cast to BigDecimal for now,
* ---- but this parameter value should be oracle.jbo.domain.Number type.
String serialNumIn = null;
BigDecimal serialCollCdIn = null;
BigDecimal maxRowsAllowed = null;
BigDecimal totalRowsSelected = null;
String messageCdOut = null;
if (params != null) {
if (params.length>0) serialNumIn = (String)params[0];
if (params.length>1) serialCollCdIn = (BigDecimal)params[1];
if (params.length>2) maxRowsAllowed = (BigDecimal)params[2];
storeNewResultSet(qc,retrieveRefCursor(qc,serialNumIn,
serialCollCdIn,
maxRowsAllowed));
super.executeQueryForCollection(qc, params, numUserParams);
* Overridden framework method.
* Wipe out all traces of a built-in query for this VO
protected void create() {
getViewDef().setQuery(null);
getViewDef().setSelectClause(null);
setQuery(null);
* Overridden framework method.
* The role of this method is to "fetch", populate, and return a single row
* from the datasource by calling createNewRowForCollection() and populating
* its attributes using populateAttributeForRow().
protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet rs) {
* We ignore the JDBC ResultSet passed by the framework (null anyway) and
* use the resultset that we've stored in the query-collection-private
* user data storage
rs = getResultSet(qc);
* Create a new row to populate
ViewRowImpl r = createNewRowForCollection(qc);
try {
* Populate new row by attribute slot number for current row in Result Set
//AddedByRegisNum
populateAttributeForRow(r,0, nullOrNewNumber(rs.getBigDecimal(1)));
System.out.println("AddedByRegisNum :" + rs.getBigDecimal(1));
// OrigRegisNum
populateAttributeForRow(r,1, nullOrNewNumber(rs.getBigDecimal(2)));
System.out.println("OrigRegisNum :" + rs.getBigDecimal(2));
// SerialNum
populateAttributeForRow(r,2, rs.getString(3));
System.out.println("SerialNum :" + rs.getString(3));
// SerialNumDesc
populateAttributeForRow(r,3, rs.getString(4));
System.out.println("SerialNumDesc :" + rs.getString(4));
// FlagExactMatch
populateAttributeForRow(r,4, rs.getString(5));
System.out.println("FlagExactMatch :" + rs.getString(5));
// MessageCd
populateAttributeForRow(r,5, messageCd);
// TotalRows
populateAttributeForRow(r,6, totalRows);
catch (SQLException s) {
throw new JboException(s);
return r;
* Overridden framework method.
* Return true if the datasource has at least one more record to fetch.
protected boolean hasNextForCollection(Object qc) {
ResultSet rs = getResultSet(qc);
boolean nextOne = false;
try {
nextOne = rs.next();
* When were at the end of the result set, mark the query collection
* as "FetchComplete".
if (!nextOne) {
setFetchCompleteForCollection(qc, true);
* Close the result set, we're done with it
rs.close();
catch (SQLException s) {
throw new JboException(s);
return nextOne;
* Overridden framework method.
* The framework gives us a chance to clean up any resources related
* to the datasource when a query collection is done being used.
protected void releaseUserDataForCollection(Object qc, Object rs) {
* Ignore the ResultSet passed in since we've created our own.
* Fetch the ResultSet from the User-Data context instead
ResultSet userDataRS = getResultSet(qc);
if (userDataRS != null) {
try {
userDataRS.close();
catch (SQLException s) {
/* Ignore */
super.releaseUserDataForCollection(qc, rs);
* Overridden framework method
* Return the number of rows that would be returned by executing
* the query implied by the datasource. This gives the developer a
* chance to perform a fast count of the rows that would be retrieved
* if all rows were fetched from the database. In the default implementation
* the framework will perform a SELECT COUNT(*) FROM (...) wrapper query
* to let the database return the count. This count might only be an estimate
* depending on how resource-intensive it would be to actually count the rows.
public long getQueryHitCount(ViewRowSetImpl viewRowSet) {
Object[] params = viewRowSet.getParameters(true);
String serialNumIn = (String)params[0];
BigDecimal serialCollCdIn = (BigDecimal)params[1];
BigDecimal maxRowsAllowed = (BigDecimal)params[2];
CallableStatement st = null;
try {
st = getDBTransaction().createCallableStatement(SQL,DBTransaction.DEFAULT);
* Register the fourth bind parameter as our return value of type NUMERIC
st.registerOutParameter(4,Types.NUMERIC);
* Set the value of the 3 bind variables to pass as arguments
if (serialNumIn == null) st.setNull(1, Types.CHAR);
else st.setString(1,serialNumIn);
if (serialCollCdIn == null) st.setNull(2,Types.NUMERIC);
else st.setBigDecimal(2,serialCollCdIn);
if (maxRowsAllowed == null) st.setNull(3, Types.NUMERIC);
else st.setBigDecimal(3, maxRowsAllowed);
st.execute();
System.out.println("returning value of :" + st.getLong(4));
return st.getLong(4);
catch (SQLException s) {
throw new JboException(s);
finally {try {st.close();} catch (SQLException s) {}}
* Return a JDBC ResultSet representing the REF CURSOR return
* value from our stored package function.
private ResultSet retrieveRefCursor(Object qc,
String serialNum,
BigDecimal serialColCd,
BigDecimal maxRows) {
CallableStatement st = null;
try {
st = getDBTransaction().createCallableStatement(SQL,DBTransaction.DEFAULT);
* Set the value of the bind variables
System.out.println("SerialNumIn :" + serialNum);
if (serialNum == null) st.setNull(1,Types.CHAR);
else st.setString(1,serialNum);
if (serialColCd == null) st.setNull(2,Types.NUMERIC);
else st.setBigDecimal(2,serialColCd);
if (maxRows == null) st.setNull(3,Types.NUMERIC);
else st.setBigDecimal(3,maxRows);
st.registerOutParameter(1, Types.CHAR); // serialNum
st.registerOutParameter(2, Types.NUMERIC); // serialColCd
st.registerOutParameter(3, Types.NUMERIC); // maxRows
st.registerOutParameter(4, Types.NUMERIC); // totalRows
st.registerOutParameter(5, Types.CHAR); // messageCd
* Register the 6th bind parameter as our return value of type CURSOR
st.registerOutParameter(6,OracleTypes.CURSOR);
st.execute();
ResultSet rs = ((OracleCallableStatement)st).getCursor(6);
serialColCd = st.getBigDecimal(2);
System.out.println("SerialColCd= " + serialColCd);
maxRows = st.getBigDecimal(3);
System.out.println("maxRows= " + maxRows);
totalRows = st.getBigDecimal(4);
System.out.println("totalRows= " + totalRows);
messageCd = st.getString(5);
System.out.println("messageCd= " + messageCd);
* Make this result set use the fetch size from our View Object settings
rs.setFetchSize(getFetchSize());
return rs ;
catch (SQLException s) {
throw new JboException(s);
finally {try {st.close();} catch (SQLException s) {}}
* Store a new result set in the query-collection-private user-data context
private void storeNewResultSet(Object qc, ResultSet rs) {
ResultSet existingRs = getResultSet(qc);
// If this query collection is getting reused, close out any previous rowset
if (existingRs != null) {
try {existingRs.close();} catch (SQLException s) {}
setUserDataForCollection(qc,rs);
hasNextForCollection(qc); // Prime the pump with the first row.
* Retrieve the result set wrapper from the query-collection user-data
private ResultSet getResultSet(Object qc) {
return (ResultSet)getUserDataForCollection(qc);
* Return either null or a new oracle.jbo.domain.Number
private static oracle.jbo.domain.Number nullOrNewNumber(BigDecimal b) {
try {
return b != null ? new oracle.jbo.domain.Number(b) : null;
catch (SQLException s) { }
return null;
Natalie -
Can I use a stored procedure to validate a username and password?
We are using Discoverer on a standalone server but we have a database link to our reporting database.
Our standalone Discoverer is on a 10g database with a database link. Our reporting database is an 9i database using oracle applications. I have a stored procedure that i can call to validate username and password in the apps.
Is there anyway to call that stored procedure from Discoverer so that my users don't have to have 2 different passwords?
thanks
AngieMichael.
Let's rewind this discussion for a sec as I have not the faintest idea what you're referring to with the dblinks, query prediction, etc.
I didn't think that was the main thrust of the thread and thought it was if the user could validate a username and password. If they happen to use a dblink, that's another issue.
1. What I"m referring to as good design is the concept of the eul$ triggers that Discoverer offers (the link offered by the user before my response).
I like triggers in Forms, I like trigger in Reports - and I like them in Discoverer. I think they potentially have a great use - the problem is finding that use.
One use I can forsee is setting up an environment or table everytime one enters Discoverer. Or maybe some cleanup after Discoverer is exited (ie: delete that setup table).
2. You mentioned dblinks.
What do I think about 'em? Don't know ... don't care. Haven't had to work with them too much and until that point comes - I'm not worried about them either way.
3. You mention query prediction.
What do I think about it? IMO, turn the darn thing off. I don't really care what it's SUPPOSED to do according to Oracle - in 9 out of 10 client sites I go to ... it's not doing it. It's waste time, processing power, coffee time, whatever ... to come up with a bogus estimate that makes Discoverer looking like a toy.
For example:
prediction time: it takes 6 minutes to come up with an estimate
prediction: Query will take 364 days, 11 hours, 9 minutes, 18 seconds. Do you wish to continue?
me: Duh ... okay.
query runs for: 1 minute, 2 seconds
It's like a Vulcan in that it's incredible detailed on it's assessment on how long it will take. Unlike a Vulcan though, it's completely bogus. Sure it supposed to be better over time but again - in 9 out of 10 client sites I go to, it's a joke and once turned off ... the client couldn't be happier.
So again, let's rewind here. Maybe I'm missing something, but I had no idea this thread was angling to dblink and query prediction, but my views on what I thought we were talking about are above.
Russ
PS. And no I'm not PO'd ... just want to fix what appears to be cross-purposes. -
ERROR WHILE INSERTING BLOBS AS PARAMETERS OF EXISTING STORED PROCEDURE
I have 2 simple tables to keep large application data (as XMLDOCUMENT in one table and BLOB in another):
SQL> desc bindata_tbl;
Name Null? Type
BDATA_ID NOT NULL NUMBER(10)
BDATA NOT NULL BLOB
SQL> desc metadata_tbl;
Name Null? Type
MDATA_ID NOT NULL NUMBER(10)
MDATA NOT NULL SYS.XMLTYPE
and stored preocedure to input new data into those tables:
"SP_TEST_BIN_META_DATA"
i_MetaData in METADATA_TBL.MDATA%TYPE,
i_BinData in BINDATA_TBL.BDATA%TYPE
as
begin
if i_MetaData is not null then
insert into METADATA_TBL (MDATA_ID, MDATA)
values (METADATA_SEQ.nextval, i_MetaData);
end if;
if i_BinData is not null then
insert into BINDATA_TBL (BDATA_ID, BDATA)
values (BINDATA_SEQ.nextval, i_BinData);
end if;
COMMIT;
-- Handle exceptions
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
end;
I communicate with database from .Net application using "Oracle.DataAccess 10.1.0.200 (Runtime version v1.0.3705)" component.
Following procesure is a [simplified] examlple of the code I use, which demonstrates the errors while inserting XMLDOCUMENT and BLOB values simultaneously.
In my application those should be quite big objects (~200 K XML and ~5-25M binary image data), but following sample keeps failing even with very small-sized objects:
Line Number
1 private void PureTest()
2 {
3 OracleConnection conn = null;
4 OracleTransaction tx = null;
5 OracleCommand command = null;
6
7 try
8 {
9 // Open connection
10 string strConn = "Data Source=AthenaWf; User ID=AthenaWf; Password=Poseidon";
11 conn = new OracleConnection( strConn );
12 conn.Open();
13
14 // Begin transaction (not sure if really needed)
15 tx = conn.BeginTransaction();
16
17 // Create command
18 string strSql = "SP_TEST_BIN_META_DATA";
19 command = new OracleCommand();
20 command.Connection = conn;
21 command.CommandText = strSql;
22 command.CommandType = CommandType.StoredProcedure;
23
24 // Create parameters
25 // 1) XmlType parameter
26 string strXml = "<?xml version=\"1.0\"?><configuration testValue=\"123456789\"/>";
27 XmlDocument xmlDoc = new XmlDocument();
28 xmlDoc.LoadXml( strXml );
29 OracleXmlType oraXml = new OracleXmlType( conn, xmlDoc );
30 //oraXml = null;
31 //
32 OracleParameter xmlPrm = new OracleParameter();
33 xmlPrm.ParameterName = "i_MetaData";
34 xmlPrm.Direction = ParameterDirection.Input;
35 xmlPrm.OracleDbType = OracleDbType.XmlType;
36 xmlPrm.Value = oraXml;
37 command.Parameters.Add( xmlPrm );
38
39 // 2) Blob type
40 byte[] buf = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
41 OracleBlob oraBlob = new OracleBlob( conn, true );
42 //oraBlob.Write( buf, 0, buf.Length );
43 oraBlob = null;
44 //
45 OracleParameter blobPrm = new OracleParameter();
46 blobPrm.ParameterName = "i_BinData";
47 blobPrm.Direction = ParameterDirection.Input;
48 blobPrm.OracleDbType = OracleDbType.Blob;
49 blobPrm.Value = oraBlob;
50 command.Parameters.Add( blobPrm );
51
52
53 // Execute command finally
54 command.ExecuteNonQuery();
55 tx.Commit();
56 }
57 catch( Exception ex )
58 {
59 // Clean-up
60 if( command != null )
61 {
62 command.Dispose();
63 }
64 if( tx != null )
65 {
66 tx.Dispose();
67 }
68 if( conn != null )
69 {
70 conn.Dispose();
71 }
72
73 // Display error message
74 MessageBox.Show( ex.Message, "Error" );
75 }
76 }
If I try insert only XMLDOCUMENT object (lines 30, 42 are commented out, 43 IS NOT) - everything is OK.
If I try to insert only BLOB object (lines 30, 42 are NOT COMMENTED OUT, line 43 is commented out) - everything is OK again.
If I try to insert them both having some values (lines 30, 43 are commented out, 42 is not commented out) - it fails right on "command.ExecuteNonQuery();" (line 54)
with the following exception:
"ORA-21500: internal error code, arguments: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%]".
Even when I nullify oraBlob before assigning it to OracleParameter value (line 30 is commented out, line 42 and 43 are not) I have the same exception.
XMLDOCUMENT and DLOB data logically are very coupled objects (in my application), so I really want to insert them simultaneously in one stored procedure in transactional way.
Is it bug of drivers, server, .net environment, or I miss something in implementation?
PS. In some articles on Oracle web and in MSDN site I found a mention about necessity of wrapping all write/update operations in a transaction, while working with temporary LOBs. I use it here, but it does not look like changing anything.Hello,
I tested your code with the 10.1.0.4.0 ODP and 10.1.0.4.0 Client and it worked fine.
Can you please apply the 10.1.0.4.0 patches for both ODP and client to see if this resolves the issue for you.
Here is the output from the same execution of the ODP application you provided as a testcase. These rows were inserted at the same time when I executed the application and passed the data as parameters to the SP you provided.
Results of Testing with 10.1.0.4.0
==========================
SQL> select count(*) from BINDATA_TBL
2 ;
COUNT(*)
1
SQL> select count(*) from METADATA_TBL;
COUNT(*)
1
SQL> select dbms_lob.getlength(bdata) from BINDATA_TBL;
DBMS_LOB.GETLENGTH(BDATA)
10
SQL> select mdata from METADATA_TBL;
MDATA
<?xml version="1.0"?><configuration testValue="123456789" /> -
Error while invoking stored procedure from BPEL process
Hi Folks,
I am facing the below mentioned issue while invoking a stored procedure in BPEL process :
I am trying to invoke a stored procedure from a BPEL process. The process runs fine for the first/second time, but gives the below error after that whenever i try to run the process :
file:/oracle/orasoa/bpel/domains/default/tmp/.bpel_ProvisionOrderASAPReqABCSImpl_1.0_50dd1595129e9bbb00560e31e7c18cef.tmp/DB_CALL_GetPendingSubscriptionProc.wsdl [ DB_CALL_GetPendingSubscriptionProc_ptt::DB_CALL_GetPendingSubscriptionProc(InputParameters,OutputParameters) ] - WSIF JCA Execute of operation 'DB_CALL_GetPendingSubscriptionProc' failed due to: Error while trying to prepare and execute an API.
An error occurred while preparing and executing the PROC_GET_PENDING_SUBSCR API. Cause: java.sql.SQLException: Io exception: Connection reset [Caused by: Io exception: Connection reset]
; nested exception is:
ORABPEL-11811
Error while trying to prepare and execute an API.
An error occurred while preparing and executing the PROC_GET_PENDING_SUBSCR API. Cause: java.sql.SQLException: Io exception: Connection reset [Caused by: Io exception: Connection reset]
Check to ensure that the API is defined in the database and that the parameters match the signature of the API. Contact oracle support if error is not fixable.
I am not getting how the BPEL is referring to the DB wsdl from the tmp folder. To resolve this issue, we have to stop the SOA server, delete the tmp files, and restart the server.
Any pointers in this regard will be really helpful.First of all does this scenario occur again.
"Works first/second time. Later gives this error."
After you restart the SOA server are you able to reproduce this scenario?
As already pointed out and from the error message, database connection is reset.
If you find this error again, try this out.
em -> home / oc4j_soa -> Administration -> JDBC Resources
Use the "Test Connection" option for the Connection Pool that you are using for your database JNDI.
It comes back and say "Connection to "XYZCP" established successfully." it is good to use.
Run the BPEL process again and once you find the error, come back and test the connection.
If it comes back with Error, diagnose based on the error message received.
Cheers
Kalidass Mookkaiah
http://oraclebpelindepth.blogspot.com/ -
Error while invoking Stored Procedure.
Hi,
I am trying to invoke a stored procedure which has one input parameter and 3 output parameters. In the procedure, I am selecting 3 columns from a table based on the input parameter. I have generated a WSDL from database, along with wsdl an xsd has been created. I have used this WSDL in creating partner link on the target side. For source side partner link, I have created WSDL based on the xsd which is created from database. I have deployed this BPEL process and when I try to debug the flow it is failing while invoking the stored procedure I am getting below soap fault.
{color:#3366ff}<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="{color}{color:#3366ff}" xmlns:xsd="{color}{color:#3366ff}" xmlns:xsi="{color}{color:#3366ff}" xsi:schemaLocation="{color}{color:#3366ff} {color}{color:#3366ff}">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xmlns="">SOAP-ENV:Server</faultcode>
<faultstring xmlns="">BPCOR-6135:A fault was not handled in the process scope; Fault Name is {http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/ErrorHandling}systemFault; Fault Data is <?xml version="1.0&;quot; encoding="UTF-8"?><jbi:message xmlns:sxeh="http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/ErrorHandling" type="sxeh:faultMessage" version="1.0&;quot; xmlns:jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper"><jbi:part>Error occured while executing SQL.call GETRESULTS(?,?,?,?) Reason: Unable to convert normalized message content to Procedure, Error occured during populating Procedure.Reason: Parameter Type Conflict: sqlType=12 SQLState: null ErrorCode:17012</jbi:part></jbi:message>. Sending errors for the pending requests in the process scope before terminating the process instance</faultstring>
<faultactor xmlns="">sun-bpel-engine</faultactor>
<detail xmlns="">
<detailText>BPCOR-6135:A fault was not handled in the process scope; Fault Name is {http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/ErrorHandling}systemFault; Fault Data is <?xml version="1.0&;quot; encoding="UTF-8"?><jbi:message xmlns:sxeh="http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/ErrorHandling" type="sxeh:faultMessage" version="1.0&;quot; xmlns:jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper"><jbi:part>Error occured while executing SQL.call GETRESULTS(?,?,?,?) Reason: Unable to convert normalized message content to Procedure, Error occured during populating Procedure.Reason: Parameter Type Conflict: sqlType=12 SQLState: null ErrorCode:17012</jbi:part></jbi:message>. Sending errors for the pending requests in the process scope before terminating the process instance
Caused by: BPCOR-6131:An Error status was received while doing an invoke (partnerLink=StoreProc, portType={http://j2ee.netbeans.org/wsdl/Storedproc}jdbcPortType, operation=execute)
BPCOR-6129:Line Number is 30
BPCOR-6130:Activity Name is Invoke1
Caused by: Error occured while executing SQL.call GETRESULTS(?,?,?,?) Reason: Unable to convert normalized message content to Procedure, Error occured during populating Procedure.Reason: Parameter Type Conflict: sqlType=12 SQLState: null ErrorCode:17012
Caused by: Unable to convert normalized message content to Procedure, Error occured during populating Procedure.Reason: Parameter Type Conflict: sqlType=12 SQLState: null ErrorCode:17012
Caused by: Parameter Type Conflict: sqlType=12</detailText>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
{color:#000000}Plz help me to fix this issue.
Thanks,
Srinivas{color}{color}First of all does this scenario occur again.
"Works first/second time. Later gives this error."
After you restart the SOA server are you able to reproduce this scenario?
As already pointed out and from the error message, database connection is reset.
If you find this error again, try this out.
em -> home / oc4j_soa -> Administration -> JDBC Resources
Use the "Test Connection" option for the Connection Pool that you are using for your database JNDI.
It comes back and say "Connection to "XYZCP" established successfully." it is good to use.
Run the BPEL process again and once you find the error, come back and test the connection.
If it comes back with Error, diagnose based on the error message received.
Cheers
Kalidass Mookkaiah
http://oraclebpelindepth.blogspot.com/ -
Calling a Stored Procedure with output parameters from Query Templates
This is same problem which Shalaka Khandekar logged earlier. This new thread gives the complete description about our problem. Please go through this problem and suggest us a feasible solution.
We encountered a problem while calling a stored procedure from MII Query Template as follows-
1. Stored Procedure is defined in a package. Procedure takes the below inputs and outputs.
a) Input1 - CLOB
b) Input2 - CLOB
c) Input3 - CLOB
d) Output1 - CLOB
e) Output2 - CLOB
f) Output3 - Varchar2
2. There are two ways to get the output back.
a) Using a Stored Procedure by declaring necessary OUT parameters.
b) Using a Function which returns a single value.
3. Consider we are using method 2-a. To call a Stored Procedure with OUT parameters from the Query Template we need to declare variables of
corresponding types and pass them to the Stored Procedure along with the necessary input parameters.
4. This method is not a solution to get output because we cannot declare variables of some type(CLOB, Varchar2) in Query Template.
5. Even though we are successful (step 4) in declaring the OUT variables in Query Template and passed it successfully to the procedure, but our procedure contains outputs which are of type CLOB. It means we are going to get data which is more than VARCHAR2 length which query template cannot return(Limit is 32767
characters)
6. So the method 2-a is ruled out.
7. Now consider method 2-b. Function returns only one value, but we have 3 different OUT values. Assume that we have appended them using a separator. This value is going to be more than 32767 characters which is again a problem with the query template(refer to point 5). So option 2-b is also ruled out.
Apart from above mentioned methods there is a work around. It is to create a temporary table in the database with above 3 OUT parameters along with a session specific column. We insert the output which we got from the procedure to the temporary table and use it further. As soon the usage of the data is completed we delete the current session specific data. So indirectly we call the table as a Session Table. This solution increases unnecessary load on the database.
Thanks in Advance.
RajeshRajesh,
please check if this following proposal could serve you.
Define the Query with mode FixedQueryWithOutput. In the package define a ref cursor as IN OUT parameter. To get your 3 values back, open the cursor in your procedure like "Select val1, val2, val3 from dual". Then the values should get into your query.
Here is an example how this could be defined.
Package:
type return_cur IS ref CURSOR;
Procedure:
PROCEDURE myProc(myReturnCur IN OUT return_cur) ...
OPEN myReturnCur FOR SELECT val1, val2, val3 FROM dual;
Query:
DECLARE
MYRETURNCUR myPackage.return_cur;
BEGIN
myPackage.myProc(
MYRETURNCUR => ?
END;
Good luck.
Michael
Maybe you are looking for
-
I have two phones with one apple id i have lost most of my contacts from one of them
i have two phones with the same apple id but i have lost most of my contacts from one phone
-
Infopath form cannot open in browser?
Hi, In my senario i have wite code On button click event in infopath. After publiched in form library i try to open the form in Client browser it showed message as below "request for the permission of type 'microsoft.sharepoint.security.sharepointper
-
Using ARM 3.0 API with Tuxedo 7.1
Hi How to use the ARM 3.0 API to measure the transaction process in Tuxedo 7.1. Please suggest any sites, forums, white papers,articles that discussed this issue. Thanks in advance. Prakash
-
Unable to create a new listener from the EM Console
When I try to create a new listener from Enterprise Manager Console, it displays an error message: Error in getting data for creating new listener. Check if the listener.ora location "/u01/app/oracle/product/10.2.0/db_1/network/admin" is a valid one.
-
Configure IP SLA to generate syslog messages
Hi, I want to use IP SLA to perform simple up/down monitoring of an IP host and to generate a syslog alert if the host goes down. I have a 2650XM router running 12.4(23) IP Voice IOS. My basic IP SLA config is hown below: ip sla monitor 10 type echo