I have a new Crystal Report, starting from our company's standard template, which has two connections: one to get some header information and then the Oracle stored procedure. When I run the report, only data for the header shows. That means the connection is working.
When I do a Show SQL Query, I can see the second query is not sending any parameters to Oracle:
OraDB
SELECT *
FROM HeaderInfo RPT
WHERE RPT_NUM = 'RPT829'
OraDB
BEGIN "OraUser"."Proc_829"(:CRYSTAL_CURSOR, NULL, NULL, NULL); END ;
I've entered the parameters, but there is a linkage missing somewhere, because it's just NULLs here. Where do I set that?
I have tried re-creating the report, starting from the same template, and it does not work. I have started a new report, adding my parameter first and then the command for the header, and it does. It just works, and binding those variables isn't something that is normally done manually. But when the binding doesn't work, is there a way to force it?
In my field explorer, it has the following:
- Database Fields
.....+ Proc_829
.....+ Command
+ Formula Fields
- Parameter Fields
.....Divisions
.....StartDate
.....EndDate
When I refresh, it asks for those parameters, which match the parameters that the Proc_829 needs. But it shows no data (the proc runs in Oracle and returns data with those same parameters), and the Show SQL Query, as above, is sending nulls.
The standard is to avoid the use of a subreport, and start with this template. The template was changed recently, but I've used previous iterations and it has worked. The template has the Command and some header information already added, and common parameter fields, which happen to match what my procedure needs.
Edit Here is the opening (obfuscated) part of the procedure:
CREATE OR REPLACE PROCEDURE PROC_829 (
CRYSTAL_CURSOR IN OUT SYS_REFCURSOR
,Divisions IN VARCHAR2
,StartDate IN DATE
,EndDate IN DATE
) IS
-- bunch of stuff here, including
OPEN crystal_cursor FOR
-- my select stuff that returns data in Oracle
Related
I am currently working on a migration of oracle reports to another report engine. Therefore I need to know where all the data and parameters are coming from.
There is some "before report trigger" defined that, as far as I already found out, will be called before the data is fetched. Some placeholder columns are set by the function of this trigger. So I will also need to run this code in my migrated report.
The function definition looks like this:
function BeforeReport return boolean is
P_id NUMBER;
P_id2 NUMBER;
P_id3 NUMBER
My question now is: when the reporting engine calls this function before data will be fetched, how does it know what to put into the parameters? Where does this data come from or where is defined, what data will be used here?
I am using Report Builder 12.2.1.3.0
The way you put it, those are not "parameters" but locally declared variables (local to that trigger). Check code that follows; I presume that it might look like
select e.empno
into P_id
from emp e
where ...
or something like that.
I did search for a similar question, but if I overlooked an existing answer I am glad to be redirected there.
I am working to untangle an Oracle Stored Proceedure in a legacy system written by a long departed developer.
The focus of the proceedure is to upload user data into the existing table structure in a bulk collection and save keystroke time adding 1-x-1 records.
The procedure appears to work without error and the user group would like to expand it to allow additional data to load to separate but related tables.
The author is using the NEXTVAL and CURRVAL commands to add primary key information as new records are added using the CSV data.
But I am confused because my understanding of NEXTVAL/CURRVAL was that they required context and declaration to be used correctly.
For example the Proceedure has the following:
SELECT seq_site.nextval INTO v_curr
FROM DUAL;
UPDATE temp_table
SET site_id = seq_site.currval
However [SEQ_SITE] is not declared anywhere in the preceding lines of the Procedure.
Am I inferring correctly that the clause [SELECT seq_site.nextval INTO v_curr] is the declaration for [SEQ_Record_count]?
(...v_curr is declared an integer early in the procedure declarations btw...)
I have created a Function from Oralce DB and used it as input to Spotfire report. The reason why i used a function instead of view is because the parameters had some complex logic operations and i was not able to get that done in a view.
Coming to the report i have built. Currently i am using 2 parameters in the function and i am taking both the values from Spotfire text area in Data on Demand mode. So i have set up two 'Input Field' for getting the data. Issue is that unless i enter values for both parameters i wont get the output. My requirement is that i need to add few more parameters for the report which i can but i need to set up the function and the settings in Spotfire such that if 5 parameters are there , if users enters one value for just one parameter report should run for that parameter. I know that parameters set up with complex logis are there but also i need to add additional ones and make sure it works properly. I dont know about proc in case a solution is achievable using that.
I cannot go back to use a view since that wont give me the desired result. Need any ideas or suggestions to implement it. Let me know in case i need to post additional information.
This is how i implemented in oracle :
create or replace function Function_test(p1 varchar2='',p2 varchar2='',p3 varchar2)
return SYS_REFCURSOR as
my_cursor SYS_REFCURSOR;
begin
open my_cursor for
select distinct
x.c1
x.c2
x.c3
from x
where x.c1=p3
and (p1='' or x.c2=p1)
and (p2='' or x.c3=p2);
return my_cursor;
end;
Using a STORED PROCEDURE or a TABLE VALUED FUNCTION will achieve similar results here and you can probably use either one. I understand you can't use a VIEW because VIEWS can't have parameters. I prefer PROCEDURES over VIEWS anyway while working with SPOTFIRE because if you need to add a column or parameter to the PROCEDURE, your INFORMATION LINK on the PROCEDURE will in inherit these changes, whereas using an INFORMATION LINK on a VIEW, the change will not cascade down and you'll need to recreate the INFORMATION LINK all together.
For your case there are a couple of things I would suggest. Since you are trying to make some of the parameters optional, you need to code your FUNCTION or PROCEDURE to accept this. For example, assume one parameter is #param1 and this is accepting input from {$propertyControl1}. To make this optional, you need to instruct users to leave the property control blank if they don't want it to be used to limit the results. Meanwhile, in your FUNCTION or PROCEDURE you need to default it's value to ''. Here is what it could look like using SQL Server, but it should be similar for ORACLE
CREATE FUNCTION dbo.MyFunction (#param1 VARCHAR(256) = '') --default value is blank. Remember don't use NULL since your property control can't be NULL
RETURNS
#returnTBL TABLE(
Column1 datetime,
Column2 int,
Column3 varchar(16))
AS
BEGIN
INSERT INTO #returnTBL (Column1, Column2, Column3)
SELECT
c.C1
c.C2
c.C3
FROM Table2
WHERE #param1 = '' OR c.C3 = #param1 --this returns all rows if the user passes in blank, and filters on it if they pass in a value
RETURN
END
Or, similarly, here is the same logic using a STORED PROCEDURE in SQL Server
CREATE PROCEDURE dbo.MyProcedure(#param1 VARCHAR(256) = '') --default value is blank. Remember don't use NULL since your property control can't be NULL
AS
SELECT
c.C1
c.C2
c.C3
FROM Table2
WHERE #param1 = '' OR c.C3 = #param1 --this returns all rows if the user passes in blank, and filters on it if they pass in a value
GO
Lastly, since you have multiple parameters, I wouldn't have the data on demand automatically refresh. I will have the users click the refresh button to retrieve the data. This will prevent the FUNCTION from being executed each time an individual parameter is change. If a user needs to change 3 of the 5 parameters, you really only want it executed once, versus three times.
I have a security procedure that has to be called just before a select from source table. Without this procedure no rows are returned.
The problem is that I have checked several ways to call this procedure just before Source Qualifier:
Pre-sql into the Source Qualifier As a Stored procedure
Pre-load source
Put several sql sentences in the sql query propertie in Source Qualifier (added 2014-11-08)
Always seems that Powercenter opens a new oracle connection, where security procedure takes no effect.
What could be the correct way to put both process together and use the same Oracle session?
Note added 2014-11-08:
I have tried also to put 2 sentences in the SQL Query of the Source Qualifier:
call procedure('param');
SELECT field1, field2, field.... from VI_ETL...;
and I get error ORA-24333 Zero Interaction Count, perharps because first item is not a SELECT statement that returns rows?
Try using SQL Query on Source Qualifier to invoke a series of statements - the security Stored Procedure being the first one.
I have several reports, and on each one of them i have a few tables included.
Lets say 3 tables, tableA, tableB and tableC.
I want to use the following Oracle Function to filter the result set passing also a report parameter:
AND function(tableB.field1, tableB.field2, tableB.field3, {?report_parameter}) = 'S'
Facts to be aware of:
Oracle Functions can only be used on SQL Expressions and/or SQL Commands in Crystal Reports.
SQL Expressions cannot contain report parameters (so, not an option).
Crystal Reports lets you replace a report table with a SQL Command, but does not let you replace several tables to a single SQL Command.
We do not want to re-build all the reports all over again.
We do not want to replace a single table to a SQL Command because it affects performance in a high level since Crystal does not transform the tables and the SQL Command on a single query when executing the report.
This Oracle Function selects data from other tables and therefore can not be rewritten on a Report Custom Function.
The {?report_parameter} is an information that only the application knows. It is filled by the application before exporting the report to the user.
What could I do to work around this?
No knowing exactly why your function requires tables and parameter, I can only give you vague, untested options. None of the options are ideal:
rewrite your Oracle function as 'Custom Function' (CF); reference CF in record-selection formula; filter will be applied WhileReadingRecords (i.e. the function will not be sent to the database)
rewrite your function as a stored procedure that accepts one parameter, but returns a record set (the parameter will be recognized by Crystal Reports); join the other tables to the stored procedure. The stored procedure will need to be written in a manner that will support Crystal Reports' data needs (using result from a stored procedure with parameters as value for gauge chart - crystal reports in asp.net application)