将 MySQL 存储过程移植到 Oracle
我正在尝试将存储过程从 MySQL 移植到 Oracle,但遇到了很多麻烦。我已经阅读了 Oracle 文档,但在执行非常基本的操作(例如正确声明变量)时遇到了困难。我希望有人能告诉我如何正确声明和设置变量。
我的存储过程用于将值添加到两个不同的表,并确保它正确映射并且外键不被违反。
这是我的 MySQL 代码:
CREATE DEFINER=root@% PROCEDURE proc_add_entry(IN theName vARCHAR(50), IN theKey VARCHAR(50), IN theOtherData VARCHAR(50), IN theOtherData2 INT, IN theStartDate DATE, IN theEndDate DaTE, IN theReferenceDate DaTE)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
declare theNameID int ;
declare theKeyID int ;
declare theOtherDataID int default null;
declare error bool default false;
declare continue handler for SQLEXCEPTION
set error = true;
set theKeyID = (select KeyID from map_alias ma where ma.alias = trim(theKey));
set theOtherDataID = (select theOtherDataID from map_otherdata mc where mc.otherdata = trim(theOtherData));
set theNameID = (select max(nameID) from inserttable);
set theNameID = theNameID + 1;
insert into inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate ,
theEndDate , theReferenceDate);
if error = true then
insert into errors_inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate ,
theEndDate , theReferenceDate);
end if;
set error = false;
insert into map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName);
if error = true then
insert into errors_map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName);
end if;
END
在 Oracle 中,我的最后一条语句被忽略(ORA-00922:缺少或无效选项)。它应该是一个局部变量,所以我不确定为什么会收到该特定错误。
我也在努力声明继续处理程序。我收到错误:
Error(16,27): PLS-00103: Encountered the symbol "FOR" when expecting one of the following: := . ( @ % ; not null range default character.
到目前为止,这是我的 Oracle 代码:
CREATE OR REPLACE PROCEDURE PROC_ADD_ENTRY
(
THENAME IN VARCHAR2
, THEKEY IN VARCHAR2
, THEOTHERDATA IN VARCHAR2
, THEOTHERDATA2 IN NUMBER
, THEFIRSTDATE IN DATE
, THELASTDATE IN DATE
, THEREFERENCEDATE IN DATE
) AS
THENAMEID INT;
THEKEYID INT;
THEOTHERDATAID int;
ERROR bool default false;
BEGIN
declare continue HANDLER FOR SQLEXCEPTION set error = true;
set THEKEYID = (select KEYID from map_INSERTTABLE mc where mc.Key = trim(THEKEY));
END PROC_ADD_ENTRY;
我确信这对于使用 Oracle 的人来说非常简单,但我正在阅读文档,并且发现有关在何处以及如何声明变量的信息存在冲突,继续处理程序,并将值分配给变量。 (是用 := 或 = 来赋值吗?我是在 begin 语句之后使用“declare”一词来声明变量,还是按照下面所示的方式进行操作?)
如果有人可以告诉我:
a) 在哪里声明本地变量变量
b) 如何为其赋值(即 1 为 int)
c) 如何从 DB 为变量赋值(set var = select number from table_number tn where tn.number = 1)
d) 如何正确声明继续处理程序
我真的很感激。
I'm trying to port a stored procedure from MySQL to Oracle, and I'm having a lot of trouble. I've gone through Oracle documentation, and I'm having trouble doing very basic things like declaring variables properly. I was hoping someone could show me how to properly declare and set variables.
My stored procedure is used to add values to two different tables and ensure that it's being mapped properly and the foreign keys aren't being violated.
Here is my MySQL Code:
CREATE DEFINER=root@% PROCEDURE proc_add_entry(IN theName vARCHAR(50), IN theKey VARCHAR(50), IN theOtherData VARCHAR(50), IN theOtherData2 INT, IN theStartDate DATE, IN theEndDate DaTE, IN theReferenceDate DaTE)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
declare theNameID int ;
declare theKeyID int ;
declare theOtherDataID int default null;
declare error bool default false;
declare continue handler for SQLEXCEPTION
set error = true;
set theKeyID = (select KeyID from map_alias ma where ma.alias = trim(theKey));
set theOtherDataID = (select theOtherDataID from map_otherdata mc where mc.otherdata = trim(theOtherData));
set theNameID = (select max(nameID) from inserttable);
set theNameID = theNameID + 1;
insert into inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate ,
theEndDate , theReferenceDate);
if error = true then
insert into errors_inserttable values (theNameID , theKeyID , theOtherDataID , theOtherData2, theStartDate ,
theEndDate , theReferenceDate);
end if;
set error = false;
insert into map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName);
if error = true then
insert into errors_map_inserttable (theNameID , datasourceid, theName) values (theNameID , 1, theName);
end if;
END
In Oracle, my last statement are being ignored (ORA-00922: Missing or invalid option). It should be a local variable, so I'm not sure why i'm getting that particular error.
I'm struggling to declare the continue handler as well. I'm getting the error:
Error(16,27): PLS-00103: Encountered the symbol "FOR" when expecting one of the following: := . ( @ % ; not null range default character.
Here is my oracle code so far:
CREATE OR REPLACE PROCEDURE PROC_ADD_ENTRY
(
THENAME IN VARCHAR2
, THEKEY IN VARCHAR2
, THEOTHERDATA IN VARCHAR2
, THEOTHERDATA2 IN NUMBER
, THEFIRSTDATE IN DATE
, THELASTDATE IN DATE
, THEREFERENCEDATE IN DATE
) AS
THENAMEID INT;
THEKEYID INT;
THEOTHERDATAID int;
ERROR bool default false;
BEGIN
declare continue HANDLER FOR SQLEXCEPTION set error = true;
set THEKEYID = (select KEYID from map_INSERTTABLE mc where mc.Key = trim(THEKEY));
END PROC_ADD_ENTRY;
I'm sure this is stupidly simple for someone that uses oracle, but I'm reading the documentation and I'm seeing conflicting information on where and how to declare variables, continue handlers, and assign values to variables. (is it := or = to assign values? Do i use the word declare after the begin statement to declare variables, or do I do it the way I show below?)
If someone could show me:
a) where to declare a local variable
b) how to assign a value to it (i.e. 1 to an int)
c) how to assign a value from the DB to a variable (set var = select number from table_number tn where tn.number = 1)
d) how to declare a continue handler properly
I would really appreciate it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的基本结构已经很好了。
为了解决您的具体问题:
我已在上面标记了此部分。
您可以使用
:=
进行赋值。例如。
thenameid := 1;
您想要的数据类型通常与 sql 数据类型相匹配(例如上述的
NUMBER
),尽管存在 PL/SQL 特定的数据类型,例如如PLS_INTEGER
。请参阅PL/SQL 数据类型文档了解更多详细信息。您可以将
into
关键字与本地定义的变量一起使用来存储价值例如如果我正确理解了您的代码,您希望每次 sql 语句出现问题时执行
set error = true
然后您希望继续执行的存储过程。异常处理就是您所追求的。您可以将任何您认为可能有错误的 SQL PL/SQL 语句包装在这样的异常块中,并根据需要提供尽可能多的异常情况(例如 NO_DATA_FOUND):
“其他”是包罗万象的。您可以只处理这种情况,但与任何错误处理一样,最好首先捕获特定情况。
为了完整起见,您的示例过程大致如下。我删除了错误代码标志,因为不需要它,并将
int
更改为number
:You've go the basic structure fine.
To address your specific questions:
I've marked this section up above.
You would use
:=
for assignment.eg.
thenameid := 1;
The data type you want will typically match the sql data types (eg.
NUMBER
for the above) though there are PL/SQL-specific data types such asPLS_INTEGER
. See the PL/SQL data types documentation for more details.You would use the
into
keyword with a locally defined variable to store the value in. eg.If I'm reading understanding your code correctly, you want
set error = true
to be executed every time there is a problem with an sql statement and then you want the stored procedure to carry on.Exception handling is what you are after. You would wrap any or SQL PL/SQL statements that you think may have errors in an exception block like this, with as many exception cases as needed (eg. NO_DATA_FOUND):
"other" is the catchall. You can have just this case handled but as with any error handling it is better practise to catch specific cases first.
For completion, here's roughly what your example procedure would look like. I've removed the error code flag as it is not needed and also changed the
int
s tonumber
s: