如何使用 pl/sql 循环接受用户输入?

Posted

技术标签:

【中文标题】如何使用 pl/sql 循环接受用户输入?【英文标题】:how to loop accepting user input with pl/sql? 【发布时间】:2009-12-08 23:40:43 【问题描述】:

我希望能够根据用户输入将可变数量的行插入到表中?例如。

Please enter value, enter "done" when no more values: value 1
Please enter value, enter "done" when no more values: value 2
Please enter value, enter "done" when no more values: done

2 Rows inserted successfully.

我不确定如何临时存储行,也不确定如何多次要求用户插入数据。 pl/sql有数组吗?

谢谢

【问题讨论】:

您真的需要定义值的能力吗?或者你可以为 FOR 循环设置一个限制吗? 询问用户他们希望循环执行的次数?或者有固定的次数? 【参考方案1】:

正如其他人所说,仅 PL/SQL 并不适合这项任务,您需要一个 UI 来与最终用户进行交互。但是,如果您确实需要在 SQL Plus 中执行此操作,则可以使用我在 this SO question 中描述的技术。

您需要创建 2 个 SQL Plus 脚本:

1) 执行单次插入的脚本,这里称为 script_insert.sql:

insert into t1 values ('&1.');
@main

2) 一个控制进程的脚本,这里称为main.sql:

accept selection prompt "Please enter value, enter 'done' when no more values: "

set term off verify off

column script new_value v_script

select case '&selection.'
       when 'done' then ''
       else '@script_insert &selection.'
       end as script
from dual;

set term on

@&v_script.

现在在 SQL Plus 中,您可以像这样运行它:

SQL> select * from t1;

no rows selected

SQL> @main
Please enter value, enter 'done' when no more values: 1
Please enter value, enter 'done' when no more values: 2
Please enter value, enter 'done' when no more values: 3
Please enter value, enter 'done' when no more values: done
SQL> select * from t1;

        N1
----------
         1
         2
         3

让我重申,这表明它是可以做到的,我不会声称它是实现需求的好方法 - 除非它只是供 DBA 或开发人员使用的临时工具。我永远不会给最终用户 SQL Plus 作为 UI!

【讨论】:

我宁愿不必使用 SQLPlus 作为 UI,但它是整个过程的一个条件。这很有趣,如果我有时间,我会看看类似的东西是否对我有用。再次感谢,在过去的几天里,您提供了很大的帮助。 Kyle,你必须有 something 才能连接到 Oracle DB,就像你需要一个网络浏览器来连接到一个网络服务器一样。你必须有一个客户。 AFAICT,这几乎是你能得到的最低限度。也许您也可以使用 Oracle SQL Developer 或 Toad,因为它们是 SQL 客户端。您可以将其包装在 .bat 或 .sh 文件中并在命令行中执行。以这种方式,任何人的母亲都可以使用这个应用程序。【参考方案2】:

我认为你是在用螺丝刀敲钉子。

使用 Python 脚本、php 页面、Perl 脚本、Java 程序或任何其他可以访问 Oracle 的环境,您将获得更大的灵活性。

【讨论】:

投掷更多您可能需要或不需要安装/学习的技术色彩会增加更多复杂性和层次。扩展你已经完成的事情是很好的。举个例子,看看那些疯狂的 javascripters 现在用 Javascript 构建服务器,而这些服务器曾经只存在于表示层。【参考方案3】:

很可能,你不能,至少不能不编写某种客户端应用程序(不是SQL*Plus 脚本)。 PL/SQL 在服务器上运行,没有任何东西可以接受用户输入。 SQL*Plus 在客户端上运行,但它没有循环结构。您不能将两者混合使用,因此您不能有一个重复发生的 PL/SQL 循环提示用户输入并根据传入的值执行 INSERT。

最常见的是,人们通过使用您最喜欢的脚本语言编写一个小型前端脚本来解决此问题,该脚本收集输入,然后发出适当的 INSERT 语句。

如果你真的真的很想完成SQL*Plus的任务,那可能是有可能的,但相当痛苦。您基本上必须构造一个无限循环,然后抛出一个错误以逃避。例如

定义一个脚本a.sql(我碰巧将我的存储在c:\temp)

whenever sqlerror exit;
accept x_val number prompt "Enter a value for x or -1 to stop  ";
INSERT INTO x( col1 ) values( :x_val );
BEGIN
    IF( &x_val = -1 )
    THEN
      commit;
      RAISE_APPLICATION_ERROR( -20001, 'Done' );
    END IF;
END;
/

@c:\temp\a.sql

然后在SQL*Plus

SQL> variable x_val number;
SQL> crate table x( col1 number );
SQL> truncate table x;

Table truncated.

SQL> @c:\temp\a.sql
Enter a value for x or -1 to stop  3

1 row created.

old   2:        IF( &x_val = -1 )
new   2:        IF(          3 = -1 )

PL/SQL procedure successfully completed.

Enter a value for x or -1 to stop  4

1 row created.

old   2:        IF( &x_val = -1 )
new   2:        IF(          4 = -1 )

PL/SQL procedure successfully completed.

Enter a value for x or -1 to stop  5

1 row created.

old   2:        IF( &x_val = -1 )
new   2:        IF(          5 = -1 )

PL/SQL procedure successfully completed.

Enter a value for x or -1 to stop  -1

1 row created.

old   2:        IF( &x_val = -1 )
new   2:        IF(         -1 = -1 )
BEGIN
*
ERROR at line 1:
ORA-20001: Done
ORA-06512: at line 4

当然,丑得可怕,但对于“作品”的某些定义来说,它“有效”

【讨论】:

有趣,我从没想过捕获异常来处理输入的结束。 不过,正如我所说,这是处理此类问题的一种非常笨拙的方法。一个接受输入并发出 INSERT 语句的漂亮的 shell 脚本/批处理文件会干净得多。 我对此也很满意。现在让我们构建一些端到端的 plsql 应用程序!【参考方案4】:

也许您可以让您的用户输入一个逗号分隔的值列表?

请输入值:1,2,3,4,5

然后处理 plsql 块中的字符串。

【讨论】:

有趣,这可能更符合我的水平。【参考方案5】:

我推荐 Oracle Application Express。它是免费的,而且非常容易快速构建简单的应用程序。

当然,对于您在这里的极其简单的要求来说,这可能有点矫枉过正,但很可能有人会在您知道之前说“我喜欢您的小型 SQL*Plus 脚本 - 您能否为其添加更多功能”如果你正在建造一座带有棚屋地基的摩天大楼。

【讨论】:

以上是关于如何使用 pl/sql 循环接受用户输入?的主要内容,如果未能解决你的问题,请参考以下文章

尝试创建一个在 pl/sql 中接受用户输入的过程 [重复]

我想在 PL SQL 中接受用户输入并将其传递给程序,给我看一个简单的程序吗?

#Oracle#PL/SQL:多个输入的替换变量

如何在PL SQL过程中提示用户输入

PL/SQL:如何从表中选择数据并输入到包接受数组类型?

使用 SQL developer 在 PL/SQL 中输出用户输入