user1874311
user1874311

Reputation: 943

Create Or Replace Function Error

I'm doing text mining using Oracle SQL Developer: ODMiner.. I imported the data "WEBLOG" into a table.. This weblog data consist of users activity, date, time, url, etc. The first step I took was to use a function to transform date and time that I have in the data table, into a number representing the 40 mins since 01-01-1990. I did this by dividing it by 2400 (seconds in 40 mins). The main purpose is to have a time frame for the sessions. I used the following code,

    CREATE OR REPLACE FUNCTION ssnDate(
    DATE IN VARCHAR2 DEFAULT 03-01-18,
    TIME IN VARCHAR2
    ) RETURN NUMBER
    AS
    BEGIN
       RETURN TRUNC((to_date(DATE||' '||TIME, 'DD-MM-YY HH:MM:SS')- to_date('01-JAN-    1990','DD-MON-YYYY')) * (86400/2400);
    END ssnDate;

This was what appeared in the log after running the statement,

FUNCTION ssnDate compiled
Warning: execution completed with warning

After this, I tried to create a VIEW to transform the DATE and TIME with the ssnDate that was created earlier on, and concatenate the CS_URI_STEM (which is the resource accessed), and CS_URI_QUERY (which is the the query, if any, the client was trying to perform)into a new field called WEB_LINK.

This is the code used,

    CREATE OR REPLACE VIEW WEBLOG_VIEWS("C_IP", "WEB_LINK", "CS_USER_AGENT", "SESSION")
    AS
    SELECT ssnDate(LOG_DATE, LOG_TIME) AS 'SESSION',
    C_IP,
    CS_USER_AGENT,
    (CS_URI_STEM||'?'||CS_URI_QUERY) AS WEB_LINK
    FROM WEBLOG;

Now from this I got the following error..

Error starting at line 1 in command:
CREATE OR REPLACE VIEW WEBLOG_VIEWS("C_IP", "WEB_LINK", "CS_USER_AGENT", "SESSION")
AS
SELECT ssnDate(LOG_DATE, LOG_TIME) AS 'SESSION',
C_IP,
CS_USER_AGENT,
(CS_URI_STEM||'?'||CS_URI_QUERY) AS WEB_LINK
FROM WEBLOG
Error at Command Line:3 Column:38
Error report:
SQL Error: ORA-00923: FROM keyword not found where expected
00923. 00000 - "FROM keyword not found where expected"
*Cause: 
*Action:

I don't get where I'm going wrong with this.. This is the data preparation stage which requires me to prep the data before applying modeling techniques or algorithms.. The next step would be grouping the data, based on the session time, ip and the user agent of each session along with the web_links fields visited by the user in that session.

I would really be grateful for any inputs on where I'm going wrong or for any kind of solutions!

Upvotes: 1

Views: 1337

Answers (2)

DazzaL
DazzaL

Reputation: 21973

you have numerous errors and inefficiencies in this small snippet of code.

firstly,

P_DATE IN VARCHAR2 DEFAULT 03-01-18

this default is nonsense. you're actually saying the default is minus 16 (3 minus 1 minnus 18!). it should be in single quotes

P_DATE IN VARCHAR2 DEFAULT '03-01-18'

Secondly, if the function is that simple, I would recommend you just put

TRUNC((to_date(DATE||' '||TIME, 'DD-MM-YY HH:MM:SS')- to_date('01-JAN-1990','DD-MON-YYYY')) * (86400/2400))

into the view itself to avoid the context (SQL->PLSQL) switching for every row returned. If you want to keep it as a function, then read up on scalar subquery caching. i.e. use the deterministic function (or in 11g go for result_cache) and put the function in a sub query too.

thirdly, your view definition columns don't line up with the actual columns used.

CREATE OR REPLACE VIEW WEBLOG_VIEWS("C_IP", "WEB_LINK", 
  "CS_USER_AGENT", "SESSION")
    AS
    SELECT ssnDate(LOG_DATE, LOG_TIME) AS 'SESSION',
    C_IP,
    CS_USER_AGENT,
    (CS_URI_STEM||'?'||CS_URI_QUERY) AS WEB_LINK

so C_IP is really "SESSION", WEB_LINK is really C_IP etc.

also don't use SQL reserved words (SESSION) in tables/views. you're just making a rod for your own back, as every time you select against this view, you need to type "SESSION" with quotes instead of just session.

finally, why are you storing a date and time as CHAR data instead of a native DATE? if you can change that, it will be much better in the long run. especially as you are storing dates using YY format which is an even worse sin than storing as YYYY!

so all that being said, if you want to keep the function, change it to something like this:

create or replace function ssndate(p_date in varchar2 default '03-01-18',
                                   p_time in varchar2)
return number
$if dbms_db_version.ver_le_10 $then
deterministic
$elsif dbms_db_version.ver_le_11 $then
result_cache
$end
as
begin
  return trunc((to_date(p_date||' '||p_time, 'dd-mm-yy hh24:mi:ss')
          - to_date('01-jan-1990','dd-mon-yyyy')) * (86400/2400));
end ssndate;
/

that $ code will just put RESULT_CACHE if you're on 11g and DETERMINISTIC otherwise.

and the view should contain this function as a subquery instead:

create or replace view weblog_views
as
select (select ssndate(log_date, log_time) from dual) as "SESSION",
       c_ip,
       cs_user_agent,
       (cs_uri_stem||'?'||cs_uri_query) as web_link
  from weblog;

Upvotes: 0

cha
cha

Reputation: 10411

use double quotes in this line:

SELECT ssnDate(LOG_DATE, LOG_TIME) AS "SESSION",

Upvotes: 1

Related Questions