有个sql语句在pl/sql里面可以执行,有数据集返回
可是放到存储过程里在pl/sql里面调试就返回不出数据集
简单来说就是一个
CREATE OR REPLACE PROCEDURE system."UP_INFACC" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
SELECT v_infacc1. 任务号,v_infacc1.工装号,件号,max(v_infacc1.制件数量) as 数量,v_infacc1.工装名称,v_infacc1.零件名称,ljfini, max (CASE WHEN 工序号=1 THEN 工序内容 END ) AS 工序1 ,max (CASE WHEN 工序号=1 THEN 单件定额 END ) AS 定额1 ,MAX(CASE WHEN 工序号=1 THEN gxfini END) AS gxfini1 , MAX(CASE WHEN 工序号=1 THEN sdt END) AS sdt1 , MAX(CASE WHEN 工序号=1 THEN edt END) AS edt1 ,MAX(CASE WHEN 工序号=1 THEN 任务分配表.finishnum END) AS finishnum1 ,MAX(CASE WHEN 工序号=1 THEN ww END) AS ww1 ,MAX(CASE WHEN 工序号=1 THEN wwgd END) AS wwgd1 ,
max (CASE WHEN 工序号=2 THEN 工序内容 END ) AS 工序2 ,max (CASE WHEN 工序号=2 THEN 单件定额 END ) AS 定额2 ,MAX(CASE WHEN 工序号=2 THEN gxfini END) AS gxfini2 , MAX(CASE WHEN 工序号=2 THEN sdt END) AS sdt2 , MAX(CASE WHEN 工序号=2 THEN edt END) AS edt2 ,MAX(CASE WHEN 工序号=2 THEN 任务分配表.finishnum END) AS finishnum2 ,MAX(CASE WHEN 工序号=2 THEN ww END) AS ww2 ,MAX(CASE WHEN 工序号=2 THEN wwgd END) AS wwgd2 ,
。。
。。
xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
FROM v_infacc1,任务分配表,xldjd
WHERE (v_infacc1.工装号 = workid) and
( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.任务号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号))))
and ( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.工装号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.taskid))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.workid))))
GROUP BY v_infacc1.任务号,v_infacc1.工装号,v_infacc1.工装名称,件号,零件名称,ljfini,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
ORDER BY v_infacc1.任务号,v_infacc1.工装号,件号,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt;commit;
exception
when others then
rollback ;
return ;
end;
为什么,这个查询返回可能超过了200列,是因为列太多了吗 还是其他原因 跟踪变量workid是存在值得
可是放到存储过程里在pl/sql里面调试就返回不出数据集
简单来说就是一个
CREATE OR REPLACE PROCEDURE system."UP_INFACC" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
SELECT v_infacc1. 任务号,v_infacc1.工装号,件号,max(v_infacc1.制件数量) as 数量,v_infacc1.工装名称,v_infacc1.零件名称,ljfini, max (CASE WHEN 工序号=1 THEN 工序内容 END ) AS 工序1 ,max (CASE WHEN 工序号=1 THEN 单件定额 END ) AS 定额1 ,MAX(CASE WHEN 工序号=1 THEN gxfini END) AS gxfini1 , MAX(CASE WHEN 工序号=1 THEN sdt END) AS sdt1 , MAX(CASE WHEN 工序号=1 THEN edt END) AS edt1 ,MAX(CASE WHEN 工序号=1 THEN 任务分配表.finishnum END) AS finishnum1 ,MAX(CASE WHEN 工序号=1 THEN ww END) AS ww1 ,MAX(CASE WHEN 工序号=1 THEN wwgd END) AS wwgd1 ,
max (CASE WHEN 工序号=2 THEN 工序内容 END ) AS 工序2 ,max (CASE WHEN 工序号=2 THEN 单件定额 END ) AS 定额2 ,MAX(CASE WHEN 工序号=2 THEN gxfini END) AS gxfini2 , MAX(CASE WHEN 工序号=2 THEN sdt END) AS sdt2 , MAX(CASE WHEN 工序号=2 THEN edt END) AS edt2 ,MAX(CASE WHEN 工序号=2 THEN 任务分配表.finishnum END) AS finishnum2 ,MAX(CASE WHEN 工序号=2 THEN ww END) AS ww2 ,MAX(CASE WHEN 工序号=2 THEN wwgd END) AS wwgd2 ,
。。
。。
xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
FROM v_infacc1,任务分配表,xldjd
WHERE (v_infacc1.工装号 = workid) and
( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.任务号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号))))
and ( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.工装号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.taskid))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.workid))))
GROUP BY v_infacc1.任务号,v_infacc1.工装号,v_infacc1.工装名称,件号,零件名称,ljfini,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
ORDER BY v_infacc1.任务号,v_infacc1.工装号,件号,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt;commit;
exception
when others then
rollback ;
return ;
end;
为什么,这个查询返回可能超过了200列,是因为列太多了吗 还是其他原因 跟踪变量workid是存在值得
解决方案 »
- exp两个用户下的数据,怎么imp数据库中
- 大数据量sql怎么优化
- oracle 10g 下使用SQL*PLUS出错!怎么回事?
- 触发器的问题
- 如何用C#对oracle中的数据进行增,删,和读取?只剩下10分了。
- 请问在oracle9下如何直接select和update xmltype型的字段的xml的某个节点的值?
- sql中代表两个表进行左连接如何写sql
- oracle登陆时提示stander包不能存取?是什么问题?
- 刚装完oracle8i,一用 sql-plus就出现:ERROR:ORA-12514: TNS: 监听进程不能解析在连接描述符中给出的 SERVICE_NAME
- win7安装Oracle 11g 第2版64位,遇到问题
- NVL 对sql性能的影响
- 结果按编号输出,不存在的补0。
--用动态拼接形式
CREATE OR REPLACE PROCEDURE system."UP_INFACC" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for --这里将查询语句用动态sql拼接
'SELECT v_infacc1. 任务号,v_infacc1.工装号,件号,max(v_infacc1.制件数量) as 数量,v_infacc1.工装名称,v_infacc1.零件名称,ljfini, max (CASE WHEN 工序号=1 THEN 工序内容 END ) AS 工序1 ,max (CASE WHEN 工序号=1 THEN 单件定额 END ) AS 定额1 ,MAX(CASE WHEN 工序号=1 THEN gxfini END) AS gxfini1 , MAX(CASE WHEN 工序号=1 THEN sdt END) AS sdt1 , MAX(CASE WHEN 工序号=1 THEN edt END) AS edt1 ,MAX(CASE WHEN 工序号=1 THEN 任务分配表.finishnum END) AS finishnum1 ,MAX(CASE WHEN 工序号=1 THEN ww END) AS ww1 ,MAX(CASE WHEN 工序号=1 THEN wwgd END) AS wwgd1 ,
max (CASE WHEN 工序号=2 THEN 工序内容 END ) AS 工序2 ,max (CASE WHEN 工序号=2 THEN 单件定额 END ) AS 定额2 ,MAX(CASE WHEN 工序号=2 THEN gxfini END) AS gxfini2 , MAX(CASE WHEN 工序号=2 THEN sdt END) AS sdt2 , MAX(CASE WHEN 工序号=2 THEN edt END) AS edt2 ,MAX(CASE WHEN 工序号=2 THEN 任务分配表.finishnum END) AS finishnum2 ,MAX(CASE WHEN 工序号=2 THEN ww END) AS ww2 ,MAX(CASE WHEN 工序号=2 THEN wwgd END) AS wwgd2 ,
。。
。。
xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
FROM v_infacc1,任务分配表,xldjd
WHERE (v_infacc1.工装号 = '||workid||') and --参数workid
( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.任务号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号))))
and ( rtrim(upper(TO_SINGLE_BYTE(v_infacc1.工装号)))= rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.任务号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.taskid))))
and ( rtrim(upper(TO_SINGLE_BYTE(任务分配表.工装号)))= rtrim(upper(TO_SINGLE_BYTE(xldjd.workid))))
GROUP BY v_infacc1.任务号,v_infacc1.工装号,v_infacc1.工装名称,件号,零件名称,ljfini,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt
ORDER BY v_infacc1.任务号,v_infacc1.工装号,件号,jhpx,xldjd.outtime , 任务分配表.pzrw , 任务分配表.pzdt';commit;
exception
when others then
rollback ;
return ;
end;
不过我看你result是一个 test_infacc.testresultset类型的 是什么啊?游标?
type testresultset is ref cursor;
end test_infacc;
就是一个程序包啊
既然是动态游标,就用我说的那样做!动态拼接你的SQL
open result for 'sql';
这里改成
WHERE (v_infacc1.工装号 = '''||workid||''') and --参数workid 就可以编译过去了 虚心求教2者的区别 还有
CREATE OR REPLACE PROCEDURE system."TEST" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
'SELECT * from 任务分配表 where 任务号= '''||workid||''' ';
commit;
exception
when others then
rollback ;
return ;
end;
与
CREATE OR REPLACE PROCEDURE system."TEST" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
SELECT * from 任务分配表 where 任务号= workid ';
commit;
exception
when others then
rollback ;
return ;
end;
的区别
WHERE (v_infacc1.工装号 = workid) and --参数workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
'SELECT * from 任务分配表 where 任务号= '''||workid||''' ';
commit;
exception
when others then
rollback ;
return ;
end;
与
CREATE OR REPLACE PROCEDURE system."TEST" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
SELECT * from 任务分配表 where 任务号= workid ;
commit;
exception
when others then
rollback ;
return ;
end;
的区别
与
WHERE (v_infacc1.工装号 = '''||workid||''') 的区别 我刚测试了 比方变量是wow
前者WHERE (v_infacc1.工装号 = wow)
后者WHERE (v_infacc1.工装号 = 'wow')这种区别
下面的
CREATE OR REPLACE PROCEDURE system."TEST" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
'SELECT * from 任务分配表 where 任务号= '''||workid||''' ';
commit;
exception
when others then
rollback ;
return ;
end;
与
CREATE OR REPLACE PROCEDURE system."TEST" (workid
varchar2,result out test_infacc.testresultset)
ASbegin
open result for
SELECT * from 任务分配表 where 任务号= workid ;
commit;
exception
when others then
rollback ;
return ;
end;
的区别有什么区别 为什么我换成动态的 数据集15秒就出来了 不动态的等几十分钟也不出来呢
普通sql oracle会自动把变量替换成相应值,比如你的变量值是wow,oracle在执行sql的时候就是 字段='wow'.动态sql是拼串,需要自己把单引号拼上去.
速度会有那么大差异?
max (CASE WHEN 工序号=1 THEN 工序内容 END ) AS 工序1 ,max (CASE WHEN 工序号=1 THEN 单件定额 END ) AS 定额1 ,MAX(CASE WHEN 工序号=1 THEN gxfini END) AS gxfini1 , MAX(CASE WHEN 工序号=1 THEN sdt END) AS sdt1 , MAX(CASE WHEN 工序号=1 THEN edt END) AS edt1 ,MAX(CASE WHEN 工序号=1 THEN 任务分配表.finishnum END) AS finishnum1 ,MAX(CASE WHEN 工序号=1 THEN ww END) AS ww1 ,MAX(CASE WHEN 工序号=1 THEN wwgd END) AS wwgd1 ,
max (CASE WHEN 工序号=2 THEN 工序内容 END ) AS 工序2 ,max (CASE WHEN 工序号=2 THEN 单件定额 END ) AS 定额2 ,MAX(CASE WHEN 工序号=2 THEN gxfini END) AS gxfini2 , MAX(CASE WHEN 工序号=2 THEN sdt END) AS sdt2 , MAX(CASE WHEN 工序号=2 THEN edt END) AS edt2 ,MAX(CASE WHEN 工序号=2 THEN 任务分配表.finishnum END) AS finishnum2 ,MAX(CASE WHEN 工序号=2 THEN ww END) AS ww2 ,MAX(CASE WHEN 工序号=2 THEN wwgd END) AS wwgd2 ,
这东西 一个执行完15秒就出来 一个执行完 我点那个返回数据集的...几十分钟都不出来
CREATE OR REPLACE FUNCTION system."IS_NUMERIC" (STR IN VARCHAR2
) RETURN NUMBER
AS
V_STR FLOAT;
begin
if str is null then
return 0;
else
begin
select to_number(str) into V_STR from dual;
exception
when others then
return 0 ;
end;
return V_STR;
end if ;
end IS_NUMERIC;
这是一个函数 SELECT a.no,
a.refno ,
a.gzh ,
a.type ,
a.refseq ,
a.jh ,
a.jhname ,
a.gxh ,
(select cast(max(system.is_numeric(c.gxh)) as varchar2(10)) from system.mom30100 c
where rtrim(upper(TO_SINGLE_BYTE(c.rwh)))= rtrim(upper(TO_SINGLE_BYTE(a.rwh)))and
rtrim(upper(TO_SINGLE_BYTE(a.gzh)))= rtrim(upper(TO_SINGLE_BYTE(c.gzh))) and
rtrim(upper(TO_SINGLE_BYTE(a.jh)))= rtrim(upper(TO_SINGLE_BYTE(c.jh)))
and system.is_numeric(c.gxh)<system.is_numeric(a.gxh) and type<>'2' ) as prior1,
(select cast(max(system.is_numeric(c.gxh)) as varchar2(10)) from system.mom30100 c
where rtrim(upper(TO_SINGLE_BYTE(c.rwh)))= rtrim(upper(TO_SINGLE_BYTE(a.rwh)))and
rtrim(upper(TO_SINGLE_BYTE(a.gzh)))= rtrim(upper(TO_SINGLE_BYTE(c.gzh))) and
rtrim(upper(TO_SINGLE_BYTE(a.jh)))= rtrim(upper(TO_SINGLE_BYTE(c.jh)))
and system.is_numeric(c.gxh)>system.is_numeric(a.gxh) and type<>'2' ) as next1,
a.gxdh ,
a.num ,
b.operator ,
b.operatorname ,
a.sj ,
a.rwh ,
a.usefix ,
a.usefixname ,degs,delx,planfinish
FROM system.mom30100 a,system.operatorlist b
WHERE a.no = b.no and
a. = '0' and a.operator like 'yg_075%' and
a.no not in (select no from system.mom30101); 执行这个要10分钟左右 system.mom30100这个表数据量在30万左右 ,而且system.mom30100这个表中gxh存在不能to_number()转化的值,这个语句时间太长了 有没有办法优化下 我把这个语句放到存储过程里面跟其他语句在一起 存储过程50多分钟都执行不完 这个也太慢了点
SELECT a.no,
a.gzh ,
a.gxh ,
(select cast(max(system.is_numeric(c.gxh)) as varchar2(10)) from system.mom30100 c
where rtrim(upper(TO_SINGLE_BYTE(c.rwh)))= rtrim(upper(TO_SINGLE_BYTE(a.rwh)))and
rtrim(upper(TO_SINGLE_BYTE(a.gzh)))= rtrim(upper(TO_SINGLE_BYTE(c.gzh))) and
rtrim(upper(TO_SINGLE_BYTE(a.jh)))= rtrim(upper(TO_SINGLE_BYTE(c.jh)))
and system.is_numeric(c.gxh)<system.is_numeric(a.gxh) and type<>'2' ) as prior1,
(select cast(max(system.is_numeric(c.gxh)) as varchar2(10)) from system.mom30100 c
where rtrim(upper(TO_SINGLE_BYTE(c.rwh)))= rtrim(upper(TO_SINGLE_BYTE(a.rwh)))and
rtrim(upper(TO_SINGLE_BYTE(a.gzh)))= rtrim(upper(TO_SINGLE_BYTE(c.gzh))) and
rtrim(upper(TO_SINGLE_BYTE(a.jh)))= rtrim(upper(TO_SINGLE_BYTE(c.jh)))
and system.is_numeric(c.gxh)>system.is_numeric(a.gxh) and type<>'2' ) as next1,
FROM system.mom30100 a,system.operatorlist b
WHERE a.no = b.no and
a. = '0' and a.operator like 'yg_075%' and
a.no not in (select no from system.mom30101); 把这个简化下就可以
我那些条件里存在大小写不同,存在右空格 存在半角全角的问题
sql server 2000这些问题全给忽略了 转到oracle里问题全体现出来了 不那么写两边数据就不一致,我现在正测试2边的存储过程数据是否一致呢
CREATE OR REPLACE PROCEDURE system."UP_INFACC" (workid varchar2)
return sys_refcursor AS()
这个在调试时也比较容易select up_infacc('11') from dual;返回游标为什么还要使用commit;你又没有做I/D/U操作即便有I/D/U操作exception
when others then
rollback ;
return ;
end;我觉得也不应该写,oracle会自动回滚的,这样写的话如果出现异常你在之前做的DML操作也会回滚
when others then
rollback ;
return ;
end;
写这个得目的就是为了 存储过程出问题 整个存储过程操作全取消 还有你说的
返回游标为什么不使用函数
CREATE OR REPLACE PROCEDURE system."UP_INFACC" (workid varchar2)
return sys_refcursor AS()
这个在调试时也比较容易
这个我不太懂 我接触oracle时间不长 返回数据集只会那么用
2.使用存储过程不能使用
exception
when others then
rollback;--替换为 null;
end;
因为oracle会自动回滚,照楼主的写法如下情况会出现问题1.insert into table;
2.exec system.UP_INFACC();
在步骤1之后如果没有commit而在执行步骤2时出现异常oracle会回滚到当前联接最后一次提交之后的savepoint
这个函数应该这样写CREATE OR REPLACE function system."UP_INFACC" (workid varchar2) return sys_refcursor AS(
..............
)
我写错了
其实上面的select 语句是在insert 语句后面接的
..............
)
这个函数里面该怎么写