我的 Oracle 语法有什么问题?
What is wrong with my Oracle syntax?
我有一个 SQL 存储过程需要转换为 Oracle。我在语法上遇到了一些麻烦。
我得到的当前错误是:
Error(75,1): PLS-00103: 遇到符号 "DROP" 期望以下之一: ( 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
我想我还有很多。谁能帮我弄清楚我做错了什么?
这是我的资料:
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;
这里是原SQL代码:
** 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
DROP 是一个 DDL 语句,在 PL/SQL 代码中无效。
用"execute immediate"替换
execute immediate "DROP TABLE t_name_match"
您几乎肯定不想在 Oracle 过程中创建和删除 table。 Oracle 临时 table 与 SQL 服务器临时 table 非常不同。在 SQL 服务器中,临时 table 的定义在会话本地(假设 table 名称以 #
为前缀)。 Oracle 没有这种本地临时文件的概念 table。 Oracle 中的临时 table 是全局的——定义对所有会话可见,数据仅对本地会话可见。这意味着您将在定义永久 tables 的同时在您的过程之外创建一次临时 tables-- 并且您不会将它们丢弃在过程中.
类似
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;
可能有用。事实上,您在注释块之前有 OPEN OUT_O_RC FOR
并且在注释块之后有 SELECT
使得该段代码有点难以理解。我也没有寻找其他语法错误。
当然,在 Oracle 中,首先使用临时 tables 是非常不常见的——做一个直接的端口并在 Oracle 中为每个使用它们的过程使用临时 tables在 SQL 服务器中将创建一些非常非惯用的 Oracle 代码,这些代码的效率可能会低于预期。在您的系统中最终出现成百上千个临时 table 也可能很烦人,尤其是当不同的 SQL 服务器程序创建具有相同名称和不同列集的临时 table 时。使用本地集合或简单地不首先具体化数据并直接查询底层永久性 table 可能会更好地为您服务。这取决于您为什么首先在 SQL 服务器中使用临时 tables。例如,请参阅 alternatives to temporary tables.
上的此线程
我有一个 SQL 存储过程需要转换为 Oracle。我在语法上遇到了一些麻烦。
我得到的当前错误是:
Error(75,1): PLS-00103: 遇到符号 "DROP" 期望以下之一: ( 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
我想我还有很多。谁能帮我弄清楚我做错了什么?
这是我的资料:
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;
这里是原SQL代码:
** 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
DROP 是一个 DDL 语句,在 PL/SQL 代码中无效。
用"execute immediate"替换
execute immediate "DROP TABLE t_name_match"
您几乎肯定不想在 Oracle 过程中创建和删除 table。 Oracle 临时 table 与 SQL 服务器临时 table 非常不同。在 SQL 服务器中,临时 table 的定义在会话本地(假设 table 名称以 #
为前缀)。 Oracle 没有这种本地临时文件的概念 table。 Oracle 中的临时 table 是全局的——定义对所有会话可见,数据仅对本地会话可见。这意味着您将在定义永久 tables 的同时在您的过程之外创建一次临时 tables-- 并且您不会将它们丢弃在过程中.
类似
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;
可能有用。事实上,您在注释块之前有 OPEN OUT_O_RC FOR
并且在注释块之后有 SELECT
使得该段代码有点难以理解。我也没有寻找其他语法错误。
当然,在 Oracle 中,首先使用临时 tables 是非常不常见的——做一个直接的端口并在 Oracle 中为每个使用它们的过程使用临时 tables在 SQL 服务器中将创建一些非常非惯用的 Oracle 代码,这些代码的效率可能会低于预期。在您的系统中最终出现成百上千个临时 table 也可能很烦人,尤其是当不同的 SQL 服务器程序创建具有相同名称和不同列集的临时 table 时。使用本地集合或简单地不首先具体化数据并直接查询底层永久性 table 可能会更好地为您服务。这取决于您为什么首先在 SQL 服务器中使用临时 tables。例如,请参阅 alternatives to temporary tables.
上的此线程