问题是关于在脚本中使用变量对我来说意味着它将在 SQL*Plus 中使用。
问题是您错过了引号,Oracle 无法将值解析为数字。
SQL> DEFINE num = 2018
SQL> SELECT &num AS your_num FROM dual;
old 1: SELECT &num AS your_num FROM dual
new 1: SELECT 2018 AS your_num FROM dual
YOUR_NUM
----------
2018
Elapsed: 00:00:00.01
由于自动类型转换(或其他名称),此示例运行良好。
如果您在 SQL*Plus 中键入 DEFINE 进行检查,它将显示 num 变量是 CHAR。
SQL>define
DEFINE NUM = "2018" (CHAR)
在这种情况下这不是问题,因为如果字符串是有效数字,Oracle 可以处理将字符串解析为数字。
当字符串无法解析为数字时,Oracle 无法处理。
SQL> DEFINE num = 'Doh'
SQL> SELECT &num AS your_num FROM dual;
old 1: SELECT &num AS your_num FROM dual
new 1: SELECT Doh AS your_num FROM dual
SELECT Doh AS your_num FROM dual
*
ERROR at line 1:
ORA-00904: "DOH": invalid identifier
带引号,所以不要强迫Oracle解析为数字,就可以了:
17:31:00 SQL> SELECT '&num' AS your_num FROM dual;
old 1: SELECT '&num' AS your_num FROM dual
new 1: SELECT 'Doh' AS your_num FROM dual
YOU
---
Doh
所以,要回答最初的问题,应该像这个示例一样:
SQL> DEFINE stupidvar = 'X'
SQL>
SQL> SELECT 'print stupidvar:' || '&stupidvar'
2 FROM dual
3 WHERE dummy = '&stupidvar';
old 1: SELECT 'print stupidvar:' || '&stupidvar'
new 1: SELECT 'print stupidvar:' || 'X'
old 3: WHERE dummy = '&stupidvar'
new 3: WHERE dummy = 'X'
'PRINTSTUPIDVAR:'
-----------------
print stupidvar:X
Elapsed: 00:00:00.00
还有另一种方法可以使用 查询列值 在 SQL*Plus 中存储变量。
COL[UMN] 具有 new_value 选项,可按字段名称存储来自查询的值。
SQL> COLUMN stupid_column_name new_value stupid_var noprint
SQL> SELECT dummy || '.log' AS stupid_column_name
2 FROM dual;
Elapsed: 00:00:00.00
SQL> SPOOL &stupid_var.
SQL> SELECT '&stupid_var' FROM DUAL;
old 1: SELECT '&stupid_var' FROM DUAL
new 1: SELECT 'X.log' FROM DUAL
X.LOG
-----
X.log
Elapsed: 00:00:00.00
SQL>SPOOL OFF;
如您所见,X.log 的值被设置到 stupid_var 变量中,因此我们可以在当前目录中找到一个 X.log 文件,其中包含一些日志。