我正在编写一个存储过程,需要在其中进行大量调整.根据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.
有时异常返回类似于:"ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小".
它不是那么可读,因为它既没有报告表,也没有报告它试图写的值.
在异常发生或被捕获时获取当前过程名称会很有用.
我怎么能得到它?
我正在使用数据分析工具,我的要求是接受用户的值,将其作为参数传递并将其存储在表中.非常直截了当所以我坐下来写这个
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 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?]
我有一个PL/SQL过程,它SUBSTR在VARCHAR2参数上做了很多.我想删除长度限制,所以我尝试将其更改为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) 如何将嵌套的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可能非常大.这样做的最佳解决方案是什么?
需要拆分功能,它将采用两个参数,字符串拆分和分隔符来拆分字符串并返回一个包含列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) 在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文本,而不是网格/电子表格

我执行了一个创建下表的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) 我想将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) oracle ×10
plsql ×10
sql ×5
function ×3
oracle11g ×2
clob ×1
dbms-output ×1
delimiter ×1
exception ×1
insert ×1
split ×1
sql-server ×1
stack-trace ×1
t-sql ×1
xml ×1
xml-parsing ×1