Reputation: 877
I have an SQL stored procedure that I need to convert to Oracle. I'm having some trouble with the syntax.
The current error I get is:
Error(75,1): PLS-00103: Encountered the symbol "DROP" when expecting one of the following: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
I assume I have plenty more. Can someone help me figure out what I'm doing wrong?
Here is what I have:
create or replace PROCEDURE "PROCEDURE1"
(
IN_FEATURENAME IN NVARCHAR2
, OUT_O_RC OUT SYS_REFCURSOR
) AS
BEGIN
execute immediate 'CREATE TABLE t_name_match( ' ||
'KBID int NOT NULL, ' ||
'SYMBOLID int NOT NULL,' ||
'FEATURE_NAME varchar(30) NULL';
execute immediate 'CREATE TABLE t_compat_match( ' ||
'KBID int NOT NULL, ' ||
'SYMBOLID int NOT NULL,' ||
'FEATURE_NAME varchar(30) NULL';
/******************************************************************************* ***
** Name matches
******************************************************************************** ***/
/*
** Load matches to Name Table
*/
INSERT INTO t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT KBID, SYMBOLID, FEATURENAME
from FEATURE_MASTER
where FEATURENAME like IN_FEATURENAME;
/******************************************************************************* ***
** Compatibility Statement matches
******************************************************************************** ***/
/*
** Load matches to Compatibility table
*/
INSERT INTO t_compat_match (KBID, CHARID, SYMBOLID)
SELECT KBID, CHARID, SYMBOLID
from FEATURE_COMPAT
where INSTR(IN_FEATURENAME, LINE) > 0;
INSERT INTO t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT cm.KBID, cm.SYMBOLID, NULL
from (SELECT DISTINCT KBID, SYMBOLID
from t_compat_match) cm
where NOT EXISTS (SELECT 'X'
from t_name_match nm
where nm.KBID = cm.KBID
and nm.SYMBOLID = cm.SYMBOLID);
UPDATE t_name_match
SET FEATURE_NAME = (SELECT FEATURENAME
from FEATURE_MASTER
where nm.FEATURE_NAME IS NULL
and fm.KBID = nm.KBID
and fm.SYMBOLID = nm.SYMBOLID);
OPEN OUT_O_RC FOR
/******************************************************************************* ***
** Return result set
******************************************************************************** ***/
SELECT DISTINCT m.MODELNAME, m.VERSION, m.PLANTID, m.FROMDATE, m.TODATE,
m.BUILD, m.KBID, nm.SYMBOLID, nm.FEATURE_NAME as FEATURENAME
FROM t_name_match nm,
KB_MASTER m
WHERE m.KBID = nm.KBID
AND m.MODELGROUP = 'F'
ORDER BY m.MODELNAME, m.VERSION;
/*
** Clean up
*/
DROP TABLE #t_name_match
DROP TABLE #t_compat_match
RETURN 0;
END PROCEDURE1;
Here is the original SQL code:
** Create the stored procedure
*/
ALTER PROCEDURE [dbo].[fcs_feature_usage]
( @search_string varchar(50),
@debug_flag char(1) = 'N'
)
as
DECLARE @error int,
@search_string_like varchar(51)
SELECT @search_string_like = Upper(@search_string) + '%'
IF (@debug_flag = 'Y') OR (@debug_flag = 'X')
SELECT GetDate() as "fcs_feature_usage Started"
/*
** Store matching results in intermediate tables (required to avoid
** JOIN, DISTINCT, and SORT between two, 2 million row tables).
*/
CREATE TABLE #t_name_match
( KBID int NOT NULL,
SYMBOLID int NOT NULL,
FEATURE_NAME varchar(30) NULL
)
CREATE TABLE #t_compat_match
( KBID int NOT NULL,
CHARID int NOT NULL,
SYMBOLID int NOT NULL
)
/******************************************************************************* ***
** Name matches
******************************************************************************** ***/
/*
** Load matches to Name Table
*/
INSERT INTO #t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT KBID, SYMBOLID, FEATURE_NAME
from FCS..T_FEATURE_MASTER
where feature_name like @search_string_like
select @error = @@error
IF (@error <> 0)
BEGIN
GOTO error_routine
END
IF (@debug_flag = 'Y')
SELECT GetDate() as "#t_name_match Loaded"
/******************************************************************************* ***
** Compatibility Statement matches
******************************************************************************** ***/
/*
** Load matches to Compatibility table
*/
INSERT INTO #t_compat_match (KBID, CHARID, SYMBOLID)
SELECT KBID, CHARID, SYMBOLID
from FCS..T_FEATURE_COMPAT
where charindex(@search_string, LINE) > 0
select @error = @@error
IF (@error <> 0)
BEGIN
GOTO error_routine
END
IF (@debug_flag = 'Y')
SELECT GetDate() as "#t_compat_match Loaded"
/*
** Add to the name matches table a list of features which had
** the given string in one of their compatibility statements.
**
** The below join, results in a complete index scan, so broke into
** two statements (INSERT & UPDATE):
**
INSERT INTO #t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT cm.KBID, cm.SYMBOLID, fm.FEATURE_NAME
from FCDB..T_FEATURE_MASTER fm,
(SELECT DISTINCT KBID, SYMBOLID
from #t_compat_match) cm
where fm.KBID = cm.KBID
and fm.SYMBOLID = cm.SYMBOLID
and NOT EXISTS (SELECT 'X'
from #t_name_match nm
where nm.KBID = cm.KBID
and nm.SYMBOLID = cm.SYMBOLID)
*/
INSERT INTO #t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT cm.KBID, cm.SYMBOLID, NULL
from (SELECT DISTINCT KBID, SYMBOLID
from #t_compat_match) cm
where NOT EXISTS (SELECT 'X'
from #t_name_match nm
where nm.KBID = cm.KBID
and nm.SYMBOLID = cm.SYMBOLID)
select @error = @@error
IF (@error <> 0)
BEGIN
GOTO error_routine
END
UPDATE #t_name_match
set FEATURE_NAME = fm.FEATURE_NAME
from #t_name_match nm,
FCS..T_FEATURE_MASTER fm
where nm.FEATURE_NAME IS NULL
and fm.KBID = nm.KBID
and fm.SYMBOLID = nm.SYMBOLID
select @error = @@error
IF (@error <> 0)
BEGIN
GOTO error_routine
END
IF (@debug_flag = 'Y')
SELECT GetDate() as "Added #t_compat_match to #t_name_match"
/******************************************************************************* ***
** Return result set
******************************************************************************** ***/
SELECT DISTINCT m.Model_Name, m.Version, m.plant_id fac_cd, m.FROM_DATE, m.TO_DATE,
m.build, m.KBID, nm.SYMBOLID, left(nm.FEATURE_NAME,12) featureName
FROM #t_name_match nm,
T_MODEL_MASTER m
WHERE m.KBID = nm.KBID
AND m.Model_Group = 'F'
ORDER BY m.Model_Name, m.version
/*
** Clean up
*/
DROP TABLE #t_name_match
DROP TABLE #t_compat_match
IF (@debug_flag = 'Y') OR (@debug_flag = 'X')
SELECT GetDate() as "fcs_feature_usage Completed"
RETURN 0
/*********************************************************************
** Error Processing Routine.
**********************************************************************/
error_routine:
DROP TABLE #t_name_match
DROP TABLE #t_compat_match
RETURN @error
Upvotes: 0
Views: 130
Reputation: 231661
You almost certainly don't want create and drop tables in an Oracle procedure. Oracle temporary tables are very different than SQL Server temporary tables. In SQL Server, the definition of the temporary table is local to the session (assuming the table name is prefixed with a #
). Oracle has no concept of this sort of local temporary table. A temporary table in Oracle is global-- the definition is visible to all sessions, the data is visible only to the local session. This means that you would create the temporary tables once-- outside of your procedure at the same time that you are defining your permanent tables-- and that you wouldn't drop them in the procedure.
Something like
CREATE GLOBAL TEMPORARY TABLE t_name_match
( KBID int NOT NULL,
SYMBOLID int NOT NULL,
FEATURE_NAME varchar2(30) NULL
)
ON COMMIT DELETE ROWS;
CREATE GLOBAL TEMPORARY TABLE t_compat_match
( KBID int NOT NULL,
CHARID int NOT NULL,
SYMBOLID int NOT NULL
)
ON COMMIT DELETE ROWS;
create or replace PROCEDURE "PROCEDURE1"
(
IN_FEATURENAME IN NVARCHAR2
, OUT_O_RC OUT SYS_REFCURSOR
) AS
BEGIN
/******************************************************************************* ***
** Name matches
******************************************************************************** ***/
/*
** Load matches to Name Table
*/
INSERT INTO t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT KBID, SYMBOLID, FEATURENAME
from FEATURE_MASTER
where FEATURENAME like IN_FEATURENAME;
/******************************************************************************* ***
** Compatibility Statement matches
******************************************************************************** ***/
/*
** Load matches to Compatibility table
*/
INSERT INTO t_compat_match (KBID, CHARID, SYMBOLID)
SELECT KBID, CHARID, SYMBOLID
from FEATURE_COMPAT
where INSTR(IN_FEATURENAME, LINE) > 0;
INSERT INTO t_name_match (KBID, SYMBOLID, FEATURE_NAME)
SELECT cm.KBID, cm.SYMBOLID, NULL
from (SELECT DISTINCT KBID, SYMBOLID
from t_compat_match) cm
where NOT EXISTS (SELECT 'X'
from t_name_match nm
where nm.KBID = cm.KBID
and nm.SYMBOLID = cm.SYMBOLID);
UPDATE t_name_match
SET FEATURE_NAME = (SELECT FEATURENAME
from FEATURE_MASTER
where nm.FEATURE_NAME IS NULL
and fm.KBID = nm.KBID
and fm.SYMBOLID = nm.SYMBOLID);
OPEN OUT_O_RC FOR
/******************************************************************************* ***
** Return result set
******************************************************************************** ***/
SELECT DISTINCT m.MODELNAME, m.VERSION, m.PLANTID, m.FROMDATE, m.TODATE,
m.BUILD, m.KBID, nm.SYMBOLID, nm.FEATURE_NAME as FEATURENAME
FROM t_name_match nm,
KB_MASTER m
WHERE m.KBID = nm.KBID
AND m.MODELGROUP = 'F'
ORDER BY m.MODELNAME, m.VERSION;
END PROCEDURE1;
might work. The fact that you have the OPEN OUT_O_RC FOR
before the comment block and the SELECT
after it makes that piece of code somewhat difficult to follow. I also haven't looked for other syntax errors.
Of course, in Oracle, it's pretty uncommon to use temporary tables in the first place-- doing a straight port and using temporary tables in Oracle for every procedure that uses them in SQL Server is going to create some very non-idiomatic Oracle code that is likely to be less efficient than it could be. Ending up with hundreds or thousands of temporary tables in your system may also be annoying particularly if different SQL Server procedures create temporary tables with the same name and a different set of columns. You may be better served with a local collection or simply by not materializing the data first and just querying the underlying permanent tables directly. It depends on why you're using the temporary tables in SQL Server in the first place. See, for example, this thread on alternatives to temporary tables.
Upvotes: 5
Reputation: 1742
DROP is a DDL statement not valid in PL/SQL code.
Replace it using "execute immediate"
execute immediate "DROP TABLE t_name_match"
Upvotes: 3