这个问题是关于在脚本中使用变量,意味着它将在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文件。