在oracle中创建存储过程的语法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在oracle中创建存储过程的语法相关的知识,希望对你有一定的参考价值。
我以前只用过sql server ,是oracle新手
我想查从tbUsers表中查询userId=参数的记录
这样写怎么错了
create or replace procedure sp_get_users_byId(param1 in varchar2) is
begin
select * from scott.tbUsers where userId=param1;
end sp_get_users_byId;
你也可以用楼上的方法把数据写进另一张表,不过要记得每次调用时还把表删掉。
create or replace procedure sp_get_users_byId(param1 in varchar2)
is
s varchar2(2000);
begin
s:='drop table ls_table';
execute immediate s;
s:='create table ls_table as (
select * from scott.tbUsers where userId=param1)';
execute immediate s;
end sp_get_users_byId; 参考技术A 应该没有错误,你的param1跟userId的数据类型一致吗
这是创建存储过程的模板:
存储过程模板:
CREATE [OR REPLACE] PROCEDURE
[schema.]procedure_name[(argument [in|out|inout] type…)]
IS | AS
[本地变量声明]
BEGIN
执行语句部分
[EXCEPTION]
错误处理部分
END[procedure_name]; 参考技术B 是as 不是is
还有就是oracle中,存储过程中直接select语句是不行的,没用,执行这个过程是没有任何返回集的 参考技术C create or replace procedure sp_get_users_byId(param1 in varchar2,pr2 out sys_refcursor) is
begin
open pr2 for select * from scott.tbUsers where userId=param1;
end sp_get_users_byId; 参考技术D 过程里是不能直接查询的,好像是没有输出~~你用
create or replace procedure sp_get_users_byId(param1 in varchar2)
is
s varchar2(2000);
begin
s:='create table ls_table as (
select * from scott.tbUsers where userId=param1)';
execute immediate s;
end sp_get_users_byId;
这个看看可以不~~就是把你查询的结果建一个叫ls_table的表,你再查询这个表。 第5个回答 2010-02-01 create or replace test(param1 in varchar2)
Authid Current_User as
begin
execute immediate 'select * from scott.tbUsers
where userid = ' || param1
end;
在包 oracle 中创建存储过程
【中文标题】在包 oracle 中创建存储过程【英文标题】:Create a stored procedure in a package oracle 【发布时间】:2017-08-30 14:42:50 【问题描述】:我在 Oracle 中创建了以下包:
CREATE OR REPLACE PACKAGE PackageName AS
TYPE general_item
IS
RECORD
(
item_no item_t.item_no%TYPE ,
item_type item_t.item_type%TYPE,
item_state item_t.item_state%TYPE,
item_name item_t.item_name%TYPE,
prodname_no item_t.prodname_no%TYPE,
prod_name item_t.prod_name%TYPE,
prodname_no2 item_t.prodname_no2%TYPE,
prod_name2 item_t.prod_name2%TYPE,
prodtype_no item_t.prodtype_no%TYPE,
prodtype_name item_t.prodtype_name%TYPE,
designer_no item_t.designer_no%TYPE,
designer_name item_t.designer_name%TYPE,
req_assembly item_t.req_assembly%TYPE,
unit_name item_t.unit_name%TYPE,
valid_designer item_t.valid_designer%TYPE,
sale_start_date item_t.sale_start_date%TYPE,
sale_end_date item_t.sale_end_date%TYPE,
short_material_text item_t.short_material_text%TYPE,
imeas_ref_imp item_t.imeas_ref_imp%TYPE,
imeas_ref_met item_t.imeas_ref_met%TYPE,
valid_design_text item_t.valid_design_text%TYPE,
pe_no item_t.pe_no%TYPE,
hfb_no item_t.hfb_no%TYPE,
hfb_name item_t.hfb_name%TYPE,
pra_no item_t.pra_no%TYPE,
pra_name item_t.pra_name%TYPE,
pa_no item_t.pa_no%TYPE,
pa_name item_t.pa_name%TYPE,
rec_sales_price item_t.rec_sales_price%TYPE,
currency_code item_t.currency_code%TYPE,
base_item_no item_cty_spec_t.item_no%TYPE, --YB added 2014-05-01
comclass_name item_comclass_t.comclass_name%TYPE); --YB added 2014-05-01
PROCEDURE general_get_item(
p_item_no IN item_t.item_no%TYPE,
p_item_type IN item_t.item_type%TYPE,
p_item OUT general_item);
END PackageName;
这是我正在尝试创建的程序:
create or replace PACKAGE BODY PackageName
AS
PROCEDURE general_get_item(
p_item_no IN item_t.item_no%TYPE,
p_item_type IN item_t.item_type%TYPE,
p_item OUT general_item)
IS
BEGIN
OPEN p_item FOR SELECT it.item_no, it.item_type, it.item_state, it.item_name, it.prodname_no , it.prod_name, it.prodname_no2, it.prod_name2, it.prodtype_no, it.prodtype_name, it.designer_no, it.designer_name, it.req_assembly, it.unit_name, it.valid_designer, it.sale_start_date, it.sale_end_date, it.short_material_text, it.imeas_ref_imp, it.imeas_ref_met, it.valid_design_text, it.pe_no, it.hfb_no, it.hfb_name, it.pra_no, it.pra_name, it.pa_no, it.pa_name, it.rec_sales_price, it.currency_code, icst.item_no as base_item_no, ict.comclass_name
FROM item_t it, item_cty_spec_t icst,
(SELECT item_no, item_type, comclass_name FROM item_comclass_t
WHERE valid_from < SYSDATE AND valid_to >= SYSDATE) ict
WHERE it.item_no = icst.item_no_cty_spec (+) AND it.item_type = icst.item_type_cty_spec (+)
AND it.item_no = ict.item_no (+) AND it.item_type = ict.item_type (+)
AND it.item_no = p_item_no
AND it.item_type = p_item_type;
END general_get_item;
END PackageName;
当我尝试创建过程时,我收到以下消息:
错误(8,3):PL/SQL:SQL 语句被忽略错误(8,8):PLS-00456:项目 'P_ITEM' 不是游标
我不熟悉 Oracle 中的包和过程。
【问题讨论】:
错误信息很明显:general_item
是类型。您不能打开一个类型,也不能为该类型赋值。请解释一下您要使用 tis 代码解决什么问题?
如果我不得不猜测您要做什么,您希望将该 select 语句中的值加载到记录类型中。如果是这种情况,请查看 PL/SQL 中的 INTO
子句。
【参考方案1】:
您无法在 TYPE
RECORD
上打开光标。它必须是CURSOR
类型。所以,只需替换整个语句 -
TYPE general_item
IS
RECORD
(
item_no item_t.item_no%TYPE ,
item_type item_t.item_type%TYPE,
item_state i
.....
.....
comclass_name item_comclass_t.comclass_name%TYPE);
有
TYPE general_item IS REF CURSOR;
【讨论】:
【参考方案2】:您无法将游标(可能是多行)提取到 TYPE。 没有表结构很难想象这个字段是什么类型。 无论如何,如果光标返回一行,更简单的方法是使用 item_t%ROWTYPE。
【讨论】:
【参考方案3】:如果要在 Oracle 中返回结果,则不需要声明游标。 Oracle 已经将它作为 SYS_REFCURSOR 代表您。
所以你的代码可能看起来像 -
CREATE OR REPLACE PACKAGE PackageName AS
PROCEDURE general_get_item(
p_item_no IN item_t.item_no%TYPE,
p_item_type IN item_t.item_type%TYPE,
p_item OUT SYS_REFCURSOR);
END PackageName;
那么你的包体可能看起来像 -
create or replace PACKAGE BODY PackageName
AS
PROCEDURE general_get_item(
p_item_no IN item_t.item_no%TYPE,
p_item_type IN item_t.item_type%TYPE,
p_item OUT SYS_REFCURSOR)
IS
BEGIN
OPEN p_item FOR
SELECT it.item_no
,it.item_type
,it.item_state
,it.item_name
,it.prodname_no
,it.prod_name
,it.prodname_no2
,it.prod_name2
,it.prodtype_no
,it.prodtype_name
,it.designer_no
,it.designer_name
,it.req_assembly
,it.unit_name
,it.valid_designer
,it.sale_start_date
,it.sale_end_date
,it.short_material_text
,it.imeas_ref_imp
,it.imeas_ref_met
,it.valid_design_text
,it.pe_no
,it.hfb_no
,it.hfb_name
,it.pra_no
,it.pra_name
,it.pa_no
,it.pa_name
,it.rec_sales_price
,it.currency_code
,icst.item_no as base_item_no
,ict.comclass_name
FROM item_t it
LEFT JOIN item_cty_spec_t icst ON it.item_no = icst.item_no_cty_spec
AND it.item_type = icst.item_type_cty_spec
LEFT JOIN (SELECT item_no
,item_type
,comclass_name
FROM item_comclass_t
WHERE valid_from < SYSDATE AND valid_to >= SYSDATE) ict ON it.item_no = ict.item_no
AND it.item_type = ict.item_type
WHERE it.item_no = p_item_no
AND it.item_type = p_item_type;
END general_get_item;
END PackageName;
还始终使用正确的显式连接语法而不是 ANSI-92 语法。
【讨论】:
以上是关于在oracle中创建存储过程的语法的主要内容,如果未能解决你的问题,请参考以下文章
在 Oracle -17110 中创建存储过程 - 警告:执行完成并出现警告