Ssrs on Oracle date parameter - oracle

I am using SSRS 2005 to run against a Oracle data source. I used this simple query
SELECT order_number FROM apps.oe_order_headers_all
WHERE ordered_date >= :start
AND ordered_date < :end + 1
and rownum = 1
Firstly I got:
ORA-01745: invalid host/bind variable name
I ignore the error and click refresh (to let SSRS determine the columns returned and parameters used)
SSRS prompts me for the values of the parameters, I tried 01/01/2014, 01-JAN-2014, 01-01-2014 for both parameters but all got this error:
Cannot bind type System.String as Blob. (System.Data.OracleClient)
The order_number is NUNBER and ordered_date is DATE in oracle.
Not sure it's a pl sql thing or SSRS thing?

Not sure if the second error is just a follow-up to the initial one, but the first error is because start is a reserved word in Oracle; you'll get an ORA-01745 from this in SQL*Plus or SQL Developer too:
SQL> var start varchar2(10);
SQL> select :start from dual;
select :start from dual
*
ERROR at line 1:
ORA-01745: invalid host/bind variable name
end is allowed though. If you change the bind variable name to, say, :start_date - and add the explicit to_date(:start_date, 'YYYY-MM-DD') and to_date(:end_date, 'YYYY-MM-DD') that OracleUser suggested so you know what format to enter the variables in - that will go away.
I can only imagine that will resolve the second error too, which I guess is coming from the parameter being in an odd state at that point.

Related

How do you create an Oracle Automatic Workload Repository (AWR) report?

How do you create an Oracle Automatic Workload Repository (AWR) report?
To generate AWR report follow below steps :
Take begin snap id
set serveroutput on;
DECLARE
v_snap_id number ;
begin
v_snap_id := DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
dbms_output.put_line(v_snap_id);
end;
/
Run your batch or the program you want to monitor.
Take end snap id
set serveroutput on;
DECLARE
v_snap_id number ;
begin
v_snap_id := DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
dbms_output.put_line(v_snap_id);
end;
/
Go to oracle directory. e.g. in my case
cd C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin
go to sqlplus promt
sqlplus dbusername/dbpassword#host:port/dbenv
run #awrrpt command
It will ask for format of the report, default is html.
provide no of days, if you dont remember your snap id
enter begin snap
enter end snap
Give report name and press enter
Your report will be generated in "admin" e.g. in my case
C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin
sqlplus into to Oracle as the DBA users. Run the report sql. Answer the questions prompted by the report to narrow down the time period
sqlplus / as sysdba
#$ORACLE_HOME/rdbms/admin/awrrpt.sql
The script will ask you some questions so you get a report for the time period you are interested in.
You can use dbms_workload_repository package without the need to log into the server itself.
For a text report, use e.g.:
select output
from table(dbms_workload_repository.awr_report_text(1557521192, 1, 5390, 5392);
Or to get a HTML report, use awr_report_text() instead.
The first paramter is the DBID which can be obtained using:
select dbid from v$database
The second one is the instance number. Only relevant for a RAC environment.
And the last two parameters are the IDs of the start and end snapshot. The available snapshots can be obtained using:
select snap_id,
begin_interval_time
end_interval_time
from dba_hist_snapshot
order by begin_interval_time desc;
Especially for the HTML return - which returns a CLOB - you must configure your SQL client to properly display the output. In SQL*Plus you would use set long
conn / as sysdba
SQL> #$ORACLE_HOME/rdbms/admin/awrrpt.sql
Specify the Report Type
AWR reports can be generated in the following formats. Please enter the
name of the format at the prompt. Default value is 'html'.
'html' HTML format (default)
'text' Text format
'active-html' Includes Performance Hub active report
Enter value for report_type:
old 1: select 'Type Specified: ',lower(nvl('&&report_type','html')) report_type from dual
new 1: select 'Type Specified: ',lower(nvl('','html')) report_type from dual
Type Specified: html
old 1: select '&&report_type' report_type_def from dual
new 1: select 'html' report_type_def from dual
old 1: select '&&view_loc' view_loc_def from dual
new 1: select 'AWR_PDB' view_loc_def from dual
Current Instance
2. you can schedule report by email alert also.

In PL/SQL, how do I use a varaible in a SELECT *without* using an INTO?

I'm experimenting with queries in an Oracle database (Using Oracle SQl Developer and PL/SQL Developer)
If I run a simple query: (SELECT * FROM myTable WHERE id = 1234) the results display in a nice grid in a lower pane of the SQL tool.
Now, how do I rewrite that query, using a variable for the 1234, And STILL have the results spill out into the results pane. Everything I've tried either won't compile, or requires me to do a SELECT...INTO and then manually output the results.
I just want to do something along the lines of this, and have it work:
DECLARE p0 = 1234;
SELECT * FROM myTable WHERE id = p0;
UPDATE:
In the actual query I'm working on, the variables will be more like:
DECLARE p0 = to_date('1/15/2014 7:11:05 AM','MM/DD/YYYY HH:MI:SS PM');
p1 = p0 + .0007; -- one minute later.
So being able to write that in code is important.
In Toad (or sqlplus or SQL Developer) you would do:
define x='20140820';
select to_date(&x, 'YYYYMMDD') from dual;
And run as a Script (important).
In Toad, the Output grid would be:
old: select to_date(&x, 'YYYYMMDD') from dual
new: select to_date(20140820, 'YYYYMMDD') from dual
TO_DATE(20140820,'YYYYMMDD')
----------------------------
20-AUG-2014
1 row selected.
And Grid1 would just show the results in table grid format.
Note that you can suppress the old/new in output by doing:
set verify off
at top of script.
One thing you can try is to create a bind variable named cur, for example, of type REFCURSOR, use OPEN :cur FOR SELECT ... in your PL/SQL block and then PRINT the cursor out. Here's an example with a very simple query:
VARIABLE cur REFCURSOR
BEGIN
OPEN :cur FOR SELECT * FROM DUAL;
END;
/
PRINT cur
This works in SQL*Plus and SQL Developer, although in the latter it will only work if you use the 'Run Script (F5)' button, not the 'Run Statement (Ctrl+Enter)' button. Also, you don't get a table with the results in, just the query output in preformatted text. Also, it won't necessarily work in other tools, as VARIABLE and PRINT are not part of SQL nor PL/SQL - SQL*Plus and SQL Developer both understand them and can interpret them.
In PL/SQL Developer you can use a Test Window for this kind of thing. For example, enter into a Test Window a PL/SQL block such as
BEGIN
OPEN :cur FOR SELECT * FROM DUAL;
END;
Then, either add the variable cur of type 'Cursor' to the variables table at bottom of the window, (or choose Scan Variables from the context menu. Note that PL/SQL Developer won't necessarily get the type right; you may well still have to change the type. Once you run the block, the results from the cursor can be obtained in a separate window by clicking the '...' button in the row in the variables table for cur.
As a minor variation on Luke's excellent answer, you don't even need a ref cursor if you just want to display a variable's value. Put this in a Test window:
declare
p0 date := to_date('1/15/2014 7:11:05 AM', 'MM/DD/YYYY HH:MI:SS PM');
begin
:p1 := p0 + .0007;
end;
then set up the p1 bind variable in the lower panel. Executing it will display the value.

NLS_NUMERIC_CHARACTERS setting for decimal

I have one db setup in a test machine and second in production machine. When I run:
select to_number('100,12') from dual
Then it gives error in test machine. However, this statement works quite fine in production machine.
Now, when I check for NLS_NUMERIC_CHARACTERS then I see ',' (comma) in both machine. Is there anywhere else I should be looking for the decimal setting?
Cheers!
You can see your current session settings by querying nls_session_parameters:
select value
from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS';
VALUE
----------------------------------------
.,
That may differ from the database defaults, which you can see in nls_database_parameters.
In this session your query errors:
select to_number('100,12') from dual;
Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 - "invalid number"
I could alter my session, either directly with alter session or by ensuring my client is configured in a way that leads to the setting the string needs (it may be inherited from a operating system or Java locale, for example):
alter session set NLS_NUMERIC_CHARACTERS = ',.';
select to_number('100,12') from dual;
TO_NUMBER('100,12')
-------------------
100,12
In SQL Developer you can set your preferred value in Tool->Preferences->Database->NLS.
But I can also override that session setting as part of the query, with the optional third nlsparam parameter to to_number(); though that makes the optional second fmt parameter necessary as well, so you'd need to be able pick a suitable format:
alter session set NLS_NUMERIC_CHARACTERS = '.,';
select to_number('100,12', '99999D99', 'NLS_NUMERIC_CHARACTERS='',.''')
from dual;
TO_NUMBER('100,12','99999D99','NLS_NUMERIC_CHARACTERS='',.''')
--------------------------------------------------------------
100.12
By default the result is still displayed with my session settings, so the decimal separator is still a period.
Jaanna, the session parameters in Oracle SQL Developer are dependent on your client computer, while the NLS parameters on PL/SQL is from server.
For example the NLS_NUMERIC_CHARACTERS on client computer can be ',.' while it's '.,' on server.
So when you run script from PL/SQL and Oracle SQL Developer the decimal separator can be completely different for the same script, unless you alter session with your expected NLS_NUMERIC_CHARACTERS in the script.
One way to easily test your session parameter is to do:
select to_number(5/2) from dual;
To know SESSION decimal separator, you can use following SQL command:
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ', ';
select SUBSTR(value,1,1) as "SEPARATOR"
,'using NLS-PARAMETER' as "Explanation"
from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS'
UNION ALL
select SUBSTR(0.5,1,1) as "SEPARATOR"
,'using NUMBER IMPLICIT CASTING' as "Explanation"
from DUAL;
The first SELECT command find NLS Parameter defined in NLS_SESSION_PARAMETERS table. The decimal separator is the first character of the returned value.
The second SELECT command convert IMPLICITELY the 0.5 rational number into a String using (by default) NLS_NUMERIC_CHARACTERS defined at session level.
The both command return same value.
I have already tested the same SQL command in PL/SQL script and this is always the same value COMMA or POINT that is displayed. Decimal Separator displayed in PL/SQL script is equal to what is displayed in SQL.
To test what I say, I have used following SQL commands:
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ', ';
select 'DECIMAL-SEPARATOR on CLIENT: (' || TO_CHAR(.5,) || ')' from dual;
DECLARE
S VARCHAR2(10) := '?';
BEGIN
select .5 INTO S from dual;
DBMS_OUTPUT.PUT_LINE('DECIMAL-SEPARATOR in PL/SQL: (' || S || ')');
END;
/
The shorter command to know decimal separator is:
SELECT .5 FROM DUAL;
That return 0,5 if decimal separator is a COMMA and 0.5 if decimal separator is a POINT.
Best way is,
SELECT to_number(replace(:Str,',','')/100) --into num2
FROM dual;

How do I run procedure in oracle with some date manipulation sql in it

I have created a procedure in oracle as follows:
create or replace PROCEDURE SP_X_AVERAGE
(
profile out SYS_REFCURSOR,
rx out SYS_REFCURSOR,
)
as
BEGIN
open profile for
select
avg(to_number(profile_netassets)) AS netassets
from
fgp;
open rx for
select
avg(to_number(a_price)) as twr
from
r_x
where
gq_date <= add_months(to_date(sysdate, 'mm/dd/yyyy'), -12);
END SP_X_AVERAGE;
It doesn't run, giving the following error:
ORA-01843: not a valid month
If I remove the where condition in the second sql then it runs successfully.
Altering a session using an sql in the same procedure doesnot work too.
Please help.
I am running this procedure in sql-developer (ubuntu Oneiric 11)
SYSDATE is already a DATE so you don't need to apply TO_DATE() to it. However, more recent versions of Oracle are tolerant of such things and handle them gracefully.
So that leaves the matter of r_x.gq_date: what data type is that? If it is a string then the chances are you have values in there which will not cast to a date, or at last don't match your default NLS_FORMAT.
"we have to keep it as "VARCHAR2(40 BYTE)" it is having date in it like this : '1/2/2003'"
Bingo. Is that the same as your NLS_DATE_FORMAT? If not you will need to cast the column:
to_date(gq_date, 'mm/dd/yyyy') <= add_months(sysdate, -12);
This may not solve your problem if the column contains strings which aren't in that format. This is a common side-effect of using strings to hold things which aren't strings.

Pass a Crystal Report Command parameter to an Oracle function

I have an Oracle 10g function, named 'F_SMART_DATE()', that returns a scalar DATE. It accepts a single VARCHAR2 parameter that is either a date string (e.g. '2011-01-01', '3/29/1966') or a 'smart' date (e.g. 'm-1' (one month ago), 'yb-0' (beginning of the current year)).
When I execute the function in SQL Developer, it works as expected:
--return 28-JUL-11
SELECT F_SMART_DATE('M-1') SMART_DATE FROM DUAL;
If I create a Crystal Report with a Command object using the same syntax, it works as expected.
If I create a String parameter in the Command object (named 'AS_OF') and attempt to pass it to the function, trouble starts.
Command object's text:
--reference Oracle function
SELECT F_SMART_DATE({?AS_OF}) SMART_DATE FROM DUAL;
If I pass, M-1 (WITHOUT the single quotation marks), I get an error that reads: 'Failed to retrieve data from the database. Details: ORA-00904: "M": invalid identifier [Database Vendor Code: 904]'.
If I pass, 'M-1' (WITH the single quotation marks), the call works as expected.
Unfortunately, these syntactical variants don't work either:
SELECT F_SMART_DATE(''' || {?AS_OF} || ''') SMART_DATE FROM DUAL;
SELECT F_SMART_DATE(''({?AS_OF})'') SMART_DATE FROM DUAL;
Ideally, I would be able to remove the quotation marks from the parameter dialog.
Does this work:
SELECT F_SMART_DATE('{?AS_OF}') SMART_DATE FROM DUAL;
It's been a while since I've used Crystal Reports, but as I recall the parameters work more like macros than bind variables.

Resources