pl/sql程序,Oracle作用域问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pl/sql程序,Oracle作用域问题相关的知识,希望对你有一定的参考价值。

<<f_block>>
declare
a number(7, 2) := 0;
b varchar2(30) default 'Hello World';
begin
a := 1 + 6;
dbms_output.put_line('test begin...');
dbms_output.put_line('1+6=' || a);
dbms_output.put_line('b=' || b);
<<s_block>>
declare
b varchar2(30);
begin
b := 'My first pl/sql...';
dbms_output.put_line('b=' || b);
dbms_output.put_line('b=' || f_block.b);
end;
dbms_output.put_line('test end...');
exception
when others then
dbms_output.put_line('exceptions!');
end;

在pl/sql的命令窗口执行报错。
ORA-06550: line 5, column 0:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_
LIKE4_ LIKEC_ between || multiset member SUBMULTISET_

参考技术A 最外边再套个begin end,哪有吧PL/SQL代码写在declare之外的:
begin
<<F_BLOCK>>
declare
A number(7, 2) := 0;
B varchar2(30) default 'Hello World';
begin
A := 1 + 6;
DBMS_OUTPUT.PUT_LINE('test begin...');
DBMS_OUTPUT.PUT_LINE('1+6=' || A);
DBMS_OUTPUT.PUT_LINE('b=' || B);
<<S_BLOCK>>
declare
B varchar2(30);
begin
B := 'My first pl/sql...';
DBMS_OUTPUT.PUT_LINE('b=' || B);
DBMS_OUTPUT.PUT_LINE('b=' || F_BLOCK.B);
end;
DBMS_OUTPUT.PUT_LINE('test end...');
exception
when others then
DBMS_OUTPUT.PUT_LINE('exceptions!');
end;
end;本回答被提问者和网友采纳

PL/SQL oracle 过程不返回任何值

【中文标题】PL/SQL oracle 过程不返回任何值【英文标题】:PL/SQL oracle procedure dose not returen any value 【发布时间】:2021-06-14 11:08:18 【问题描述】:

我让这个 oracle 程序读取带有 varchar 值的参数,当我在程序中使用这个参数值时不起作用。一切都会在下面解释

CREATE OR REPLACE procedure test_pro(read_batch in varchar2 )

as
v_read_batches varchar2(500);
begin

v_read_batches := '''' || replace(read_batch, ',', ''',''') || '''';

--v_read_batches VALUE IS '100','1000','11','9200'

SELECT CODE,BANK_NAME_ARABIC,BANK_CODE,to_number(BATCH_ID)BATCH_ID FROM (select 1 CODE,PB.BANK_NAME_ARABIC ,to_char(PB.BANK_CODE)BANK_CODE,
CASE PB.BANK_CODE
    WHEN 1000
    THEN 1000 
    WHEN 100
    THEN 100  
    ELSE 9200 
  END batch_id
from BANKS PB 
WHERE PB.BANK_CODE IN (1000,100,11200)

union
SELECT 2 CODE,'Other Banks' other_banks,listagg(PB.BANK_CODE , ', ')
within group(order by  PB.BANK_CODE ) as BANK_CODE, 11 batch_id
 FROM BANKS  PB 
WHERE PB.BANK_CODE NOT IN (1000,100,9200))

WHERE to_char(BATCH_ID) IN (v_read_batches)                                                                            
   
end test_pro;

问题是当我将 v_read_batches 放入 sql 条件时它没有返回任何值,当我执行时 下面的 sql 单独在 v_read_batches 变量中具有相同的值,它可以工作并返回值!

SELECT CODE,BANK_NAME_ARABIC,BANK_CODE,to_number(BATCH_ID)BATCH_ID FROM(选择 1 个代码,PB.BANK_NAME_ARABIC ,to_char(PB.BANK_CODE)BANK_CODE, CASE PB.BANK_CODE 当 1000 那么 1000 当 100 然后 100 ELSE 9200 END batch_id from BANKS PB WHERE PB.BANK_CODE IN (1000,100,11200)

union SELECT 2 CODE,'其他银行' other_banks,listagg(PB.BANK_CODE , ', ') 组内(按 PB.BANK_CODE 排序)为 BANK_CODE, 11 batch_id 从银行 PB 那里 PB.BANK_CODE 不在 (1000,100,9200))

WHERE to_char(BATCH_ID) IN ('100','1000','11','9200')

【问题讨论】:

【参考方案1】:

您不能构建这样的字符串并希望在 IN 语句中使用它。 IN 子句中的元素是静态的,即,如果您编写代码

col in ('123,456')

然后我们正在寻找 COL 来匹配字符串 '123,456' 而不是元素 123 和 456。

您可以通过一些 SQL 将输入字符串转换为行,例如

create table t as select '123,456,789' acct from dual

select distinct (instr(acct||',',',',1,level)) loc
from t
connect by level <= length(acct)- length(replace(acct,','))+1

完成此操作后,您可以更改您的程序,以便您的

WHERE batch_id in (read_batch) 

变成

WHERE batch_id in (select distinct (instr(:batch||',',',',1,level)) loc
    from t
    connect by level <= length(:batch)- length(replace(:batch,','))+1
) 

一般意义上,永远不要让来自外部世界的输入直接折叠到 SQL 语句中。您会产生“SQL 注入”的风险,这是人们被黑客入侵的最常见方式。

这里有关于字符串到行技术的完整视频演示:

https://youtu.be/cjvpXL3H64c?list=PLJMaoEWvHwFIUwMrF4HLnRksF0H8DHGtt

【讨论】:

以上是关于pl/sql程序,Oracle作用域问题的主要内容,如果未能解决你的问题,请参考以下文章

oracle pl/sql 编程啥工具好用

PL/SQL连接oracle提示无监听程序

如何配置pl/sql 连接远程oracle服务器

oracle 10g ,PL/SQL问题:ORA-12520:TNS:监听程序无法为请求的服务类型找到可用的处理程序,怎么办?如图

oracle 10g ,PL/SQL问题:ORA-12520:TNS:监听程序无法为请求的服务类型找到可用的处理程序,怎么办?如图

为啥这个 PL/SQL 不起作用?