标签: plsql

Oracle PL/SQL - NO_DATA_FOUND异常对存储过程性能有害吗?

我正在编写一个存储过程,需要在其中进行大量调整.根据C#.NET编码的一般知识,异常会损害性能,我总是避免在PL/SQL中使用它们.我在这个存储过程中的条件主要围绕是否存在记录,我可以用两种方法之一:

SELECT COUNT(*) INTO var WHERE condition;
IF var > 0 THEN
   SELECT NEEDED_FIELD INTO otherVar WHERE condition;
....
Run Code Online (Sandbox Code Playgroud)

-要么-

SELECT NEEDED_FIELD INTO var WHERE condition;
EXCEPTION
WHEN NO_DATA_FOUND
....
Run Code Online (Sandbox Code Playgroud)

第二种情况对我来说似乎更优雅,因为那时我可以使用NEEDED_FIELD,我必须在第一种情况下的条件之后的第一个语句中选择.更少的代码.但是如果存储过程使用COUNT(*)运行得更快,那么我不介意再输入一点来弥补处理速度.

任何提示?我错过了另一种可能吗?

编辑 我应该提到这已经嵌套在FOR LOOP中了.不确定这是否与使用游标有所不同,因为我认为我不能将光标作为FOR LOOP中的选择进行DECLARE.

sql oracle plsql exception

25
推荐指数
3
解决办法
11万
查看次数

Oracle PL/SQL:如何获取堆栈跟踪,包名称和过程名称

有时异常返回类似于:"ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小".

它不是那么可读,因为它既没有报告表,也没有报告它试图写的值.

在异常发生或被捕获时获取当前过程名称会很有用.

我怎么能得到它?

oracle plsql exception-handling stack-trace

25
推荐指数
4
解决办法
7万
查看次数

解决方案"无法在查询中执行DML操作"?

我正在使用数据分析工具,我的要求是接受用户的值,将其作为参数传递并将其存储在表中.非常直截了当所以我坐下来写这个

create or replace
procedure complex(datainput in VARCHAR2)
is
begin
insert into dumtab values (datainput);
end complex;
Run Code Online (Sandbox Code Playgroud)

我使用以下语句在SQL Developer中执行了此操作

begin
complex('SomeValue');  
end;
Run Code Online (Sandbox Code Playgroud)

它工作正常,并将值插入表中.但是,数据分析工具不支持上述语句,因此我使用了函数.以下是函数的代码,它编译.

create or replace
function supercomplex(datainput in VARCHAR2)
return varchar2
is
begin
insert into dumtab values (datainput);
return 'done';
end supercomplex;   
Run Code Online (Sandbox Code Playgroud)

我再一次尝试在SQL Developer中执行它,但是我在执行以下代码时无法在查询中执行DML操作

select supercomplex('somevalue') from dual;
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 我需要一个可以在SQL Developer中运行上述函数的语句,或者 - 一个可以执行我正在寻找的函数的函数,可以由select语句执行. - 如果我不能做我要问的事情,我想要一个理由,所以我可以告诉我的经理,因为我很新(就像一周大了?)到PL/SQL,所以我不知道规则和语法.

PS我多么希望这是C++甚至是Java :(

编辑

我需要在SQL Developer上运行该函数,因为在DMine(它是工具)中运行它之前,为了测试它是否有效.SQL中的任何无效内容在DMine中也是无效的,但不是相反.

感谢您的帮助,我了解情况以及为什么它是非法的/不推荐的

sql oracle plsql stored-procedures function

25
推荐指数
2
解决办法
6万
查看次数

基本问题:基本的PL/SQL控制台输出?

我正在使用SQL Developer,并希望使用DBMS_OUTPUT.PUT_LINE()将变量的内容输出到控制台.我正在运行以下代码,添加数字1到5,但我没有看到任何输出.

SET SERVEROUTPUT ON;
DECLARE 
n_counter NUMBER := 5; -- Substitute this variable
n_sum     NUMBER := 0;
BEGIN
  WHILE n_counter != 0
  LOOP
    n_sum := n_sum + n_counter;
    n_counter := n_counter -1;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE(n_sum);
END;
Run Code Online (Sandbox Code Playgroud)

此外,您是否知道比非常密集的Oracle PL/SQL文档更好的解决问题资源?[类似于Java SE7 API?]

sql oracle plsql oracle-sqldeveloper dbms-output

25
推荐指数
1
解决办法
6万
查看次数

SUBSTR在CLOB上的性能

我有一个PL/SQL过程,它SUBSTRVARCHAR2参数上做了很多.我想删除长度限制,所以我尝试将其更改为CLOB.

工作正常,但性能受损,所以我做了一些测试(基于2005 年的这些测试).


更新:我可以在具有不同Oracle版本和不同硬件的几个不同实例上重现这一点,dbms_lob.substr总是明显慢于substr(CLOB),并且慢很多SUBSTR(VARCHAR2).

鲍勃的结果和上面链接中的测试讲述了一个不同的故事.

任何人都可以解释这个,或者至少复制鲍勃或我的结果?谢谢!


检测结果:

+000000000 00:00:00 004000000(VARCHAR2)
+000000000 00:00:00.298000000(CLOB SUBSTR)
+000000000 00:00:00.356000000(DBMS_LOB.SUBSTR)

测试代码:

DECLARE
  l_text   VARCHAR2(30) := 'This is a test record';
  l_clob   CLOB := l_text;
  l_substr VARCHAR2(30);
  t TIMESTAMP;
BEGIN
  t := SYSTIMESTAMP;
  FOR i IN 1..100000 LOOP
    l_substr := SUBSTR(l_text,1,14);
  END LOOP;
  dbms_output.put_line( SYSTIMESTAMP - t || ' (VARCHAR2)');

  t := SYSTIMESTAMP;
  FOR i IN …
Run Code Online (Sandbox Code Playgroud)

sql oracle plsql clob oracle11g

25
推荐指数
1
解决办法
2万
查看次数

oracle plsql:如何解析XML并插入表中

如何将嵌套的xml文件加载到数据库表中?

<?xml version="1.0" ?> 
<person>
   <row>
       <name>Tom</name>
       <Address>
           <State>California</State>
           <City>Los angeles</City>
       </Address>
   </row>
   <row>
       <name>Jim</name>
       <Address>
           <State>California</State>
           <City>Los angeles</City>
       </Address>
   </row>
</person>       
Run Code Online (Sandbox Code Playgroud)

在这个xml中,person是表名,name是归档名,Tom是其归档值.地址是一个子表,状态和城市是地址内的两列.我想将person行插入到person表中,如果失败,请不要插入到地址表中.这个xml可能非常大.这样做的最佳解决方案是什么?

xml oracle plsql insert xml-parsing

25
推荐指数
3
解决办法
11万
查看次数

在oracle中拆分函数以逗号分隔值和自动序列

需要拆分功能,它将采用两个参数,字符串拆分和分隔符来拆分字符串并返回一个包含列Id和Data的表.如何调用Split函数,它将返回一个包含列Id和Data的表.Id列将包含序列,数据列将包含该字符串的数据.例如.

SELECT*FROM Split('A,B,C,D',',')
Run Code Online (Sandbox Code Playgroud)

结果应采用以下格式:

|Id | Data
 --   ----
|1  | A  |
|2  | B  |
|3  | C  |
|4  | D  |
Run Code Online (Sandbox Code Playgroud)

oracle plsql split function delimiter

25
推荐指数
3
解决办法
13万
查看次数

如何像在T-SQL中一样在PL/SQL中声明和使用变量?

在Sql Server中,经常在我测试存储过程的主体时,我将主体复制到SSMS中,将页面顶部的变量DECLARE,将它们设置为一些样本值,并按原样执行主体.

例如,如果我的proc是

CREATE PROC MySampleProc
    @Name   VARCHAR(20)
AS
    SELECT @Name
Run Code Online (Sandbox Code Playgroud)

然后我的测试SQL将是

DECLARE @Name VARCHAR(20)
SET     @Name = 'Tom'

    SELECT @Name
Run Code Online (Sandbox Code Playgroud)

什么是Oracle PL/SQL相当于此?

这是我提出的最接近的,但是我得到了"PLS-00428:在这个SELECT语句中需要一个INTO子句"

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     select myname from DUAL;
END;
Run Code Online (Sandbox Code Playgroud)

这是我真正想要做的更好的例子:

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     SELECT *
     FROM   Customers
     WHERE  Name = myname;
END;
Run Code Online (Sandbox Code Playgroud)

但是,当我真的只想要在屏幕上打印的记录而不是存储在另一个表格中时,它想要一个'INTO'.

解决:

感谢@Allan,我的工作得很好.Oracle SQL Developer显然会记住您提供的参数值.然而,PL/SQL Developer不想与此有任何关系....

在此输入图像描述

如果您"运行为脚本",它将遵循您的默认值,但它只会返回结果作为ASCI文本,而不是网格/电子表格

在此输入图像描述

t-sql sql-server oracle plsql oracle-sqldeveloper

24
推荐指数
2
解决办法
16万
查看次数

PLS-00201 - 必须声明标识符

我执行了一个创建下表的PL/SQL脚本

TABLE_NAME VARCHAR2(30) := 'B2BOWNER.SSC_Page_Map';
Run Code Online (Sandbox Code Playgroud)

我使用参数为这个表创建了一个insert函数

CREATE OR REPLACE FUNCTION F_SSC_Page_Map_Insert(
         p_page_id   IN B2BOWNER.SSC_Page_Map.Page_ID_NBR%TYPE, 
         p_page_type IN B2BOWNER.SSC_Page_Map.Page_Type%TYPE, 
         p_page_dcpn IN B2BOWNER.SSC_Page_Map.Page_Dcpn%TYPE)
Run Code Online (Sandbox Code Playgroud)

我被通知我必须B2BOWNER.SSC_Page_Map在它出现作为我的函数的参数之前声明.为什么我收到此错误?

编辑:实际错误

Warning: compiled but with compilation errors
Errors for FUNCTION F_SSC_PAGE_MAP_INSERT

LINE/COL ERROR                                                            
-------- -----------------------------------------------------------------
2/48     PLS-00201: identifier 'SSC_PAGE_MAP.PAGE_ID_NBR' must be declared
0/0      PL/SQL: Compilation unit analysis terminated 
Run Code Online (Sandbox Code Playgroud)

编辑:完整的PL/SQL函数

RETURN INTEGER
IS
   TABLE_DOES_NOT_EXIST exception;  
   PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942); -- ORA-00942

BEGIN

   INSERT INTO 
       B2BOWNER.SSC_Page_Map VALUES(
           p_page_id, 
           p_page_type, 
           p_page_dcpn);

   RETURN 0;

   EXCEPTION
       WHEN TABLE_DOES_NOT_EXIST THEN
           RETURN -1; …
Run Code Online (Sandbox Code Playgroud)

oracle plsql function

24
推荐指数
2
解决办法
20万
查看次数

PLS-00428:此SELECT语句中需要一个INTO子句

我想将Rownum存储为变量,而不是使用昂贵的Join.我需要从Select语句中获取它,因为Rownum在各种环境中会有所不同,因此它不能是代码中的文字字符串.

对于上下文,此查询在Oracle Siebel CRM架构上执行,并检索某些特定类型和属性的产品.

我尝试在Toad和Oracle SQL Developer中使用以下SQL代码,但是我收到以下错误:

PLS-00428:此SELECT语句中需要一个INTO子句

这是代码

    DECLARE
    PROD_ROW_ID varchar(10) := NULL;
BEGIN
    SELECT ROW_ID INTO VIS_ROW_ID FROM SIEBEL.S_PROD_INT WHERE PART_NUM = 'S0146404';

    BEGIN
        SELECT rtrim(VIS.SERIAL_NUM) || ',' || rtrim(PLANID.DESC_TEXT) || ',' ||
               CASE
               WHEN PLANID.HIGH = 'TEST123'
               THEN
                   CASE
                   WHEN to_date(PROD.START_DATE) + 30 > sysdate
                   THEN 'Y'
                   ELSE 'N'
                   END
               ELSE 'N'
               END
               || ',' || 'GB' || ',' ||
               rtrim(to_char(PROD.START_DATE, 'YYYY-MM-DD'))
        FROM SIEBEL.S_LST_OF_VAL PLANID
            INNER JOIN SIEBEL.S_PROD_INT PROD
                ON PROD.PART_NUM = PLANID.VAL
            INNER JOIN SIEBEL.S_ASSET NETFLIX …
Run Code Online (Sandbox Code Playgroud)

sql oracle plsql oracle11g

24
推荐指数
1
解决办法
11万
查看次数