今天在写一个简单的SQL语句并执行时抛出了如下图所示的一个错误提示信息!
恩,此异常信息很明显,在SQL语句中标示符的长度过长了,简短一些就应该没问题了,我查看了一下我的SQL语句发现是我的查询字段的列别名过长,实际测试的结果为列字段别名的最大长度为30个字节!
注意:我的测试数据库是ORACLE 11.2.0.4.0(如下图所示)
ok,问题搞定了,对应的更多的错误信息及解决方案,也可以从ORACLE的错误信息手册中查询比如(针对此问题):
Error: ORA-00972: identifier is too long
Cause: You tried to reference a table, cluster, view, index, synonym, tablespace, or username with a value that was longer than 30 characters.
Action: The options to resolve this Oracle error are: Names for tables, clusters, views, indexes, synonyms, tablespaces, and usernames must be 30 characters or less. You must shorten the name to no more than 30 characters for these objects.
以上内容是我分析和解决我的SQL语句中,查询时列的别名过长问题的过程,也是我分享这篇小博文的引子! 下面是我针对别名的一个小结(注意:我的测试数据库是ORACLE 11.2.0.4.0 字符集是AMERICAN_AMERICA.AL32UTF8) 一:使用别名的好处 1)简化SQL语句的书写,特别是多表关联查询且表名较长时 2)增强SQL语句的可读性,特别是当查询出来的列字段较为复杂时效果更为明显
二:测试小结 1)测试时使用的简单表结构
CREATE TABLESALES.STUDENT
(
ID NUMBER,
NAME VARCHAR2(20BYTE),
SEX CHAR(1BYTE),
BIRTHDAY DATE,
HOBBY VARCHAR2(20 CHAR)
)
2)测试使用的若干条测试数据
3)列名的最大长度为30个字节
SELECT ID ABCDEABCDEABCDEABCDEABCDEABCDE--30个英文大写字符,正常执行
FROMSTUDENT
SELECT ID ABCDEABCDEABCDEABCDEABCDEABCDE1--多加另一个1就会报ORA-00972:identifier is to long
FROMSTUDENT
SELECT ID 我们学校的好学生学号--10个中文汉字字符,正常执行
FROMSTUDENT
SELECT ID 我们学校的好学生学号1--多加另一个1就会报ORA-00972:identifier is to long
FROM STUDENT
4)可以使用AS关键字定义列名,也可以不适用AS,列名后直接指定别名,以空格分开即可
SELECT ID AS 学号 FROMSTUDENT
--使用AS的情况,正常执行
SELECT ID 学号 FROM STUDENT
--不使用AS也可以正常执行,而且代码更简洁,建议使用方式
5)以数字开头的别名必须使用双引号括起来
SELECT ID 123学号 FROMSTUDENT
--执行时报"ORA-00923: FROM keyword not found where expected"
SELECT ID "123学号"--正常执行
6)别名可以使用双引号和不使用任何引号。(注意:全是英文的单引或双引符号)
中文别名可以使用双引号和不使用任何引号的
但是使用单引符号时报错(任何列别名不能用单引号)
SELECT ID 学号 FROMSTUDENT
--正常执行
SELECT ID "学号" FROMSTUDENT
--正常执行
SELECT ID '学号' FROMSTUDENT
--执行时报"ORA-00923: FROM keyword not found where expected"
SELECT ID StudentId FROMSTUDENT
--正常执行
SELECT ID "StudentId" FROMSTUDENT
--正常执行
SELECT ID 'StudentId' FROM STUDENT
--执行时报"ORA-00923: FROM keyword not found where expected"
7)别名中使用了其他的特殊符号比如:别名中包含空格或者小括号(),则必须使用双引号括起来(注意:其他的特殊符号可能类似,这里以小括号为例做了测试,其他情况如果感兴趣可以自己动手试试)
SELECT ID AS (学号) FROMSTUDENT
--英文小括号且使用AS的情形,执行时报"ORA-00923: FROM keyword not found where expected"
SELECT ID (学号) FROMSTUDENT
--英文小括号,执行时报"ORA-00904: "ID": invalid identifier"
SELECT ID AS "(学号)" FROMSTUDENT
--正常执行
SELECT ID AS(学号)FROMSTUDENT
--中文小括号且使用AS的情形,执行时报"ORA-00923: FROM keyword not found where expected"
SELECT ID(学号)FROMSTUDENT
--中文小括号,执行时报"ORA-00904: "ID": invalid identifier"
SELECT ID "(学号)" FROM STUDENT
--正常执行
SELECT ID 学 号--执行时报"ORA-00923: FROM keyword not found where expected"
FROMSTUDENT
SELECT ID "学 号"--正常执行
FROMSTUDENT
SELECT ID XUE HAO--执行时报"ORA-00923: FROM keyword not found where expected"
FROMSTUDENT
SELECT ID "XUE HAO"--正常执行
FROM STUDENT
8)是否可以保留别名中的空格——可以,但必须使用双引号括起来,如果指定的别名带有双引号,则子句中使用别名的时候必须带双引号,保持一致
SELECT ID "学 号" FROMSTUDENT ORDER BY "学 号" DESC
--正常执行
9)使用别名时因SQL语句各子句的执行顺序引起的问题
ORACLE中的SQL语句,
1.WHERE/GROUP BY/HAVING子句中只能直接使用栏位或者常量,而不能使用栏位的别名,除非这个别名来自子查询之中,如:SELECT .... FROM (SELECT COLUMN_NAME C FROM TABLE_NAME) WHERE C > 1 2.而ORDER BY 则可以直接使用别名,如SELECT COLUMN_NAME C FROM TABLE_NAME ORDER BY C
这和SQL的执行顺序是有关的,SQL语句的执行顺序大致如下所示:
1. FROM语句
2. WHERE语句(结合条件)
3. START WITH语句
4. CONNECT BY语句
5. WHERE语句
6. GROUP BY语句
7. HAVING语句
8. MODEL语句
9. SELECT语句
10. UNION、MINUS、INTERSECT等集合演算演算
11. ORDER BY语句
我们可以看到SELECT子句是在WHERE子句执行后才执行的,当SELECT子句执行时查询列的别名才生成,所以在WHERE子句中根本看不到列的别名,当然,自然也就无法引用列的别名了。 所以字段、表达式的别名在WHERE子句和GROUP BY子句都是不能使用的,而在ORDER BY中不仅可以使用别名,甚至可以直接使用栏位的下标来进行排序,如:ORDER BY ID或者ORDER BY 1
SELECTID ID_
FROMSTUDENT
WHERE ID_=11--执行时报"ORA-00904: "ID_": invalid identifier"
SELECTID ID_
FROMSTUDENT
WHERE ID=11--正常执行
SELECTID ID_
FROMSTUDENT
WHERE ID='11'--正常执行,注意:ID是NUMBER类型的数据
SELECTID ID_
FROMSTUDENT
WHERE ID="11"--执行时报"ORA-00904: "11": invalid identifier",注意:ID是NUMBER类型的数据
SELECT ID,COUNT(*) C
FROMSTUDENT
GROUP BYID
HAVING C>0--执行时报"ORA-00904: "C": invalid identifier"
SELECT ID,COUNT(*) C
FROMSTUDENT
GROUP BYID
HAVING Count(*)>0--正常执行
SELECT ID,COUNT(*)C
FROMSTUDENT
GROUP BYID
HAVING COUNT(*)>0
ORDER BY C--正常执行
SELECTID ID_
FROMSTUDENT
ORDER BY ID_--正常执行
SELECTID ID_
FROMSTUDENT
ORDER BY 1--正常执行
10)别名是否区分大小写——区分大小写(注意:当不用双引号括起来的时候英文字符大小写不敏感)
SELECTXUEHAO
FROM (SELECT ID XUEHAO FROMSTUDENT)
WHERE XUEHAO > 1--正常执行
SELECTXUEHAO
FROM (SELECT ID xuehao FROMSTUDENT)
WHERE XUEHAO > 1--正常执行
SELECTXUEHAO
FROM (SELECT ID "XUEHAO" FROMSTUDENT)
WHERE XUEHAO > 1--正常执行
SELECTXUEHAO
FROM (SELECT ID "xuehao" FROMSTUDENT)
WHERE XUEHAO > 1--执行时报"ORA-00904: "XUEHAO": invalid identifier"
SELECTXUEHAO
FROM (SELECT ID "xuehao" FROMSTUDENT)
WHERE xuehao > 1--执行时报"ORA-00904: "XUEHAO": invalid identifier"
SELECTXUEHAO
FROM (SELECT ID "xuehao" FROMSTUDENT)
WHERE "xuehao" > 1--执行时报"ORA-00904: "XUEHAO": invalid identifier"
SELECT"xuehao"
FROM (SELECT ID "xuehao" FROMSTUDENT)
WHERE "xuehao" > 1--正常执行
这个小例子也可以看到SQL语句是先执行WHERE子句然后才执行SELECT子句的!
ORACLE 在WHERE子句中引用列别名的问题
SQL> select sal,comm from emp
2 where sal<2000;
SAL COMM
--------- ----------
800
1600 300
1250 500
1250 1400
1500 0
1100
950
1300
8 rows selected.
SQL> select sal as salary,comm as commission from emp
2 where salary<2000;
where salary<2000
*
ERROR at line 2:
ORA-00904: "SALARY": invalid identifier
SQL> select * from
2 (
3 select sal as salary,comm as commission from emp
4 ) x
5 where salary<2000;
SALARY COMMISSION
---------- ----------
800
1600 300
1250 500
1250 1400
1500 0
1100
950
1300
8 rows selected.
将取别名的查询作为内联视图,便可以在外部查询中引用其中的别名列。为什么要这么做呢?WHERE子句是在SELECT之前进行处理的,这样,在处理求解“问题”查询的WHERE子句之前,SALARY和COMMISSION并不存在,要到WHERE子句处理完成之后,别名才生效。然而,FROM子句是在WHERE之前处理的。将原查询放在FROM子句中,那么,在最外层的WHERE子句之前,以及最外层的WHERE子句“看到”别名之前,就已经生成了查询结果。
oracle 连接运算符,连接字符串,||双竖线,在列别名上使用双引号,使用带有特殊字符的列别名
在列别名上使用双引号
输入并执行查询:
1.SELECT ename AS "Name", sal*12+5000 AS "年度工资(加年终奖)" FROM emp;
1.SELECT ename AS "Name", sal*12+5000 AS "年度工资(加年终奖)" FROM emp;
显示结果为:
1.Name 年度工资(加年终奖)
2. --------------- ----------------------------
3. SMITH 14600
4. ALLEN 24200
1.Name 年度工资(加年终奖)
2. --------------- ----------------------------
3. SMITH 14600
4. ALLEN 24200
说明:其中别名“Name”有大小写的区别,别名“年度工资(加年终奖) ”中出现括号,属于特殊符号,所以都需要使用双引号将别名引起。
连接运算符
sql语句可以使用包含数值运算的计算列,显示结果也是数值型的。我们也可以使用字符型的计算列,方法是在查询中使用连接运算。连接运算符是双竖线“||”。通过连接运算可以将两个字符串连接在一起。
在查询中使用连接运算。
输入并执行查询:
1.SELECT ename||job AS "雇员和职务表" FROM emp;
1.SELECT ename||job AS "雇员和职务表" FROM emp;
输出结果为:
1.雇员和职务表
2. -------------------
3. SMITHCLERK
4. ALLENSALESMAN
1.雇员和职务表
2. -------------------
3. SMITHCLERK
4. ALLENSALESMAN
说明:在本例中,雇员名称和职务列被连接成为一个列显示。
在查询中可以使用字符和日期的常量,表示固定的字符串或固定日期。字符和日期的常量需要用单引号引起。下一个训练是作为上一个训练的改进。
在查询中使用字符串常量。
输入并执行查询:
1.SELECT ename|| ' IS '||job AS "雇员和职务表" FROM emp;
1.SELECT ename|| ' IS '||job AS "雇员和职务表" FROM emp;
输出结果为:
1.雇员和职务表
2. -----------------------
3. SMITH IS CLERK
4. ALLEN IS SALESMAN
1.雇员和职务表
2. -----------------------
3. SMITH IS CLERK
4. ALLEN IS SALESMAN
说明:本练习中将雇员名称、字符串常量“ IS ”和雇员职务3个部分连接在一起。