0

我尝试了几种不同的方法(来自这里和其他地方),但都没有成功,我希望你们自己更有经验的人之一能够提供帮助。

这是我的 shell 脚本

read -p 'What is the ID? ' asnid
    if [ -z "$asnid" ]
        then 
            echo "ID is Empty"
            exit
        else 
            echo "ID, continuing to Date"
    fi
read -p 'What is the Arrival Date? (Answer in DD-MM-YY format please!) ' date

        if [[ $date =~ ^[0-9]{2}-[0-9]{2}-[0-9]{2}$ ]]
            
            then echo "Date $date is in valid format (DD-MM-YY)"

                cd /go/to/path
                sqlplus data/base@srvc @./sql.sql $asnid $date

            else echo "Date $date is in an invalid format (not DD-MM-YY)"
            exit

        fi

然后是我的 .sql 语句

    define asnid = &asnid 
    define date = &date

    update table
    set date = '&date'
        where asnid = '&asnid';
            COMMIT;
            exit;

但是,这会再次要求我提供变量.. 例如;

Enter value for asnid:

我知道这很简单,但是什么!!

Oracle 11g,Bash 是 RHEL 6

4

1 回答 1

1

您正在传递位置参数,因此将它们称为&1&2。如果您想在查询正文中使用更友好的名称,那么只需更改这些名称的定义:

define asnid = &1
define date = "to_date('&2', 'DD-MM-RR')"

我已经包括 (a) 将第二个参数括在引号中,因为它需要被视为一个字符串,以及 (b) 将该字符串转换为实际日期。因为它有一个逗号,所以整个表达式也必须用双引号引起来。因此,您不需要 SQL 语句中的引号:

update table
set date = &date
where asnid = &asnid;

然后整个to_date(...)表达式将被替换到您的查询中,并嵌入传入的值;如果你,你会看到这种情况发生set verify on,但你可能希望它关闭,除了测试。开启后,脚本显示:

What is the ID? 42
ID, continuing to Date
What is the Arrival Date? (Answer in DD-MM-YY format please!) 01-09-21 Date 01-09-21 is in valid format (DD-MM-YY)

SQL*Plus: Release 12.1.0.2.0 Production on Wed Aug 25 18:12:50 2021

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Wed Aug 25 2021 18:11:54 +01:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Advanced Analytics, Real Application Testing and Unified Auditing options


old   2: set some_date = &date
new   2: set some_date = to_date('01-09-21', 'DD-MM-RR')
old   3: where asnid = &asnid
new   3: where asnid = 42

1 row updated.


Commit complete.


Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Advanced Analytics, Real Application Testing and Unified Auditing options

(您可能还想在调用中添加-s和可能-l标志sqlplus,以抑制横幅并使其在凭据错误时立即退出。)

或者,您可以保持define简单,并to_date()在语句中应用:

define asnid = &1
define date = &2

update some_table
set some_date = to_date('&date', 'DD-MM-RR') where asnid = &asnid;

然后输出显示为:

old   2: set some_date = to_date('&date', 'DD-MM-RR')
new   2: set some_date = to_date('01-09-21', 'DD-MM-RR')
old   3: where asnid = &asnid
new   3: where asnid = 42

但如果你这样做,你不妨跳过并直接在语句中define引用and 。&1&2

在这两种情况下,我都&1假设这将是一个数字。如果这实际上是一个字符串,那么也将其括在引号中,无论是在语句中还是在定义中。

如果您可以选择,您可能应该提示输入 4 位数年份的日期;可能是 ISO 格式 - 并且在to_date().


您还可以通过让 SQL*Plus 提示输入值来跳过(或最小化)shell 脚本accept

accept asnid number format 99999999 prompt "What is the ID? "
accept date date format 'DD-MM-RR' prompt "What is the Arrival Date? (Answer in DD-MM-YY format please!) "

update some_table
set some_date = to_date('&date', 'DD-MM-RR')
where asnid = &asnid;

然后不带参数调用它:

sqlplus data/base@srvc @/go/to/path/sql.sql

你会看到类似这样的东西,我使用了一些非值和无效值来演示:

SQL*Plus: Release 12.1.0.2.0 Production on Wed Aug 25 18:24:28 2021

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Wed Aug 25 2021 18:24:02 +01:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Advanced Analytics, Real Application Testing and Unified Auditing options

What is the ID?
SP2-0598: "" does not match input format "99999999"
What is the ID? 42
What is the Arrival Date? (Answer in DD-MM-YY format please!)
SP2-0685: The date "" is invalid or format mismatched "DD-MM-RR"
What is the Arrival Date? (Answer in DD-MM-YY format please!) 31-09-21
SP2-0685: The date "31-09-21" is invalid or format mismatched "DD-MM-RR"
What is the Arrival Date? (Answer in DD-MM-YY format please!) 30-09-21

old   2: set some_date = to_date('&date', 'DD-MM-RR')
new   2: set some_date = to_date('30-09-21', 'DD-MM-RR')
old   3: where asnid = &asnid
new   3: where asnid =         42

1 row updated.


Commit complete.


Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Advanced Analytics, Real Application Testing and Unified Auditing options

这将允许 Oracle 愿意使用该格式掩码转换的日期字符串,因此它允许您输入“01-Sep-21”。如果您不希望这样,请制作格式掩码'FXDD-MM-RR'。(但是,再次考虑使用 4 位数的年份和明确的格式......)

于 2021-08-25T16:48:53.207 回答