Oracle中insert into select和select into的用法(异常0RA-00905:missing keyword的解决)

本文详细介绍了在Oracle和SqlServer中使用SQL语句进行数据拷贝的方法,并着重指出Oracle中selectinto语句的错误使用可能导致的异常。通过提供测试代码,文章演示了如何正确使用insertinto和createtableselect来实现数据迁移。


两张表进行数据的拷贝,最常用的拷贝语句是:

insert into select  和 select into from

但是请绝对的注意:

在Oracle中select into from不可以使用-----原因很简单:select into是PL/SQL language 的赋值语句!如果使用则Oracle会抛出0RA-00905:missing keyword的异常!

但是可以用create table select代替该功能!!!具体参考下面测试代码!

但是在Sql Server中可以正常使用。

先做个小测试:

-- 建表
create table test1(
id number primary key,
testname varchar2(20),
createtime date,
falg varchar2(10)
);

create table test2(
id number primary key,
testname varchar2(20),
createtime date,
falg varchar2(10)
);

-- 插入测试数据
insert into test1 values(1,'测试数据1....1',sysdate-2,'N');
insert into test1 values(2,'测试数据1....2',sysdate-2,'N');
insert into test1 values(3,'测试数据1....3',sysdate-2,'N');
commit;
-- 使用insert into select 拷贝数据(注意红色部分,可以自动生成id序列值)
insert into test2(id,testname,createtime,falg)
   select seq_test.nextval,t1.testname,t1.createtime,t1.falg from test1 t1;
-- 使用 create table select 创建被拷贝数据(注意要删除test2表先)
create table test2 as select t1.id,t1.testname,t1.createtime,t1.falg from test1 t1;

-- select into from 不可以,抛异常
select t1.id,t1.testname,t1.createtime,t1.falg into test2(id,testname,createtime,falg) 
   from test1 t1;

-- PL/SQL language 中select into赋值语句的测试使用
create or replace procedure test1_prod
is
  aa varchar2(100);
begin
  select t1.testname into aa from test1 t1 where id=1;
  dbms_output.put_line('t1.testname= '|| aa);
end;

总结:

数据拷贝,建议使用insert  into  select

使用insert  into  select时如果对拷贝表生成id序列值,需要在select中以查询出的形式从sequence中查询出,再插入拷贝表;比如:

insert into test2(id,testname,createtime,falg)
   select seq_test.nextval,t1.testname,t1.createtime,t1.falg from test1 t1;

典型从test1表查询出数据插入test2表,test2要自动插入id,看上面代码,id要在select中先从sequence中查询出了!!

<think> 首先,用户的问题是关于Oracle 19c执行个SQL语句报错ORA-00905解决方案。具体语句是:SELECT count(0) into var2 from v$locked_object; 报错ORA-00905。 ORA-00905错误在Oracle中表示“缺失关键字”。这通常是由于SQL语句语法错误导致的。 我需要参考用户提供的引用,但这些引用似乎不直接相关: - 引用[1]讨论了热备份脚本检查错误邮件,没有提到ORA-00905- 引用[2]是关于关键字保留字的查询方法。 - 引用[3]涉及DG备库的错误ORA-00313等。 - 引用[4]是省略号,可能表示没有内容或不相关。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上次的问题你的回答。” 但我没有上下文关于上次的问题,因为这是新的对话。系统提示说“参考用户上次的问题你的回答”,但在这个对话中没有之前的交互。所以我应该专注于当前问题。 现在,分析错误:ORA-00905 "missing keyword"。SQL语句是SELECT count(0) into var2 from v$locked_object;。 在Oracle中,into var2 通常是PL/SQL的部分,用于将查询结果存储到变量中。但在SQL*Plus或纯SQL环境中,你不能直接使用INTO子句;它必须在PL/SQL块中使用。 所以,问题可能出在用户试图在SQL命令行中执行这个语句,而不是在PL/SQL块中。 可能的原因是: - 用户可能在SQL*Plus中直接运行这个语句,而没有放在BEGIN/END块中。 - var2 可能没有被声明。 正确的做法是将这个语句放在PL/SQL块中: ```sql DECLARE var2 NUMBER; BEGIN SELECT COUNT(0) INTO var2 FROM v$locked_object; DBMS_OUTPUT.PUT_LINE('Count: ' || var2); END; / ``` 或者,如果需要直接在SQL中运行,可以使用SELECT COUNT(0) FROM v$locked_object; 但这样不会存储到变量。 参考引用[2],它提到查询关键字保留字。ORA-00905可能与关键字冲突相关,但在这个语句中,count、selectfrom等都是标准关键字,应该没问题INTO 是有效的关键字。 在Oracle中,v$locked_object 是个动态性能视图,需要权限访问。用户可能没有权限,但错误是ORA-00905,不是权限错误(如ORA-00942)。 另外,count(0) 等同于 count(*),是有效的。 所以,核心问题INTO子句不能在纯SQL中使用;它必须在PL/SQL上下文中。 解决方案: 1. 确保语句在PL/SQL块中执行。 2. 如果没有PL/SQL,直接运行SELECT查询而不使用INTO。 3. 检查变量声明。 用户指定了Oracle 19c,所以版本不是问题。 生成相关问题- 系统指令要求“生成相关问题”,所以我需要添加相关问题部分。 回答结构: - 使用中文回答。 - 保持清晰,逐步解决问题- 添加引用标识,如[^1],但用户提供的引用可能不直接相关。我需要自然引用。用户说“参考站内引用”,但这些引用是给定的。我应该引用它们如果相关。 - 引用[2]是关于查询关键字的,我可以关联到检查是否INTO是保留字或类似。 - 但直接相关的是语法错误。 构建回答: 1. 解释错误原因:ORA-00905通常表示SQL语法错误,特别是在使用INTO子句时,必须在PL/SQL块中。 2. 提供解决方案:建议在PL/SQL中运行语句。 3. 示例代码。 4. 如果权限问题或其他,提示检查。 5. 添加相关问题。 相关问题: 1. 如何在Oracle PL/SQL中声明使用变量? 2. 如何检查用户权限访问v$视图? 3. 常见的Oracle SQL语法错误有哪些? 确保LaTeX格式:系统指令要求数学表达式用$...$,但这里可能不需要,因为是SQL问题。如果需要,例如在解释计数时,但可能没必要。 最后,添加引用:用户提供了引用,我可以参考它们。例如,引用[2]关于查询关键字,可以用来检查INTO是否是保留字,但其实它不是。 </think> ### Oracle 19c执行`SELECT count(0) into var2 from v$locked_object;`报错ORA-00905解决方案 ORA-00905错误表示“缺失关键字”(missing keyword),通常在Oracle中由SQL语法错误引发。您的语句`SELECT count(0) into var2 from v$locked_object;`试图直接在SQL环境中使用`INTO`子句,但`INTO`是PL/SQL特有的语法,不能在纯SQL语句中独立使用(例如在SQL*Plus或SQL Developer中直接执行)。以下是逐步分析解决方案: #### 错误原因分析 1. **语法上下文错误**: - `INTO`关键字用于将查询结果存储到变量中,但必须在PL/SQL块(如DECLARE/BEGIN/END)中运行。 - 在纯SQL环境中运行此语句会触发ORA-00905,因为Oracle解析器无法识别`INTO`作为SQL命令的部分。 - 引用[2]提到Oracle有严格的关键字规则,但`INTO`本身是有效的PL/SQL关键字,而非保留字问题[^2]。 2. **变量声明缺失**: - 变量`var2`必须在PL/SQL块中显式声明(如`DECLARE var2 NUMBER;`),否则Oracle无法识别它。 3. **权限或视图问题(次要可能)**: - `v$locked_object`是动态性能视图,需要`SELECT ANY DICTIONARY`或`SELECT_CATALOG_ROLE`权限。如果权限不足,会报ORA-00942错误,但您的错误是ORA-00905,因此权限问题不是主因。 - 引用[1][3]提到Oracle错误监控(如检查Email或DG日志),但ORA-00905是语法错误,无需深入性能诊断[^1][^3]。 #### 解决方案 以下是两种修复方法(以Oracle 19c为例): **方法1:在PL/SQL块中执行语句(推荐)** 将语句包裹在PL/SQL块中,正确声明变量: ```sql DECLARE var2 NUMBER; -- 显式声明变量 BEGIN SELECT COUNT(0) INTO var2 FROM v$locked_object; -- INTO在PL/SQL中有效 DBMS_OUTPUT.PUT_LINE('Locked objects count: ' || var2); -- 输出结果 END; / ``` - **执行步骤**: 1. 在SQL*Plus或SQL Developer中运行上述代码。 2. 确保启用输出:在运行前执行`SET SERVEROUTPUT ON;`(SQL*Plus)或配置输出窗口(SQL Developer)。 3. 如果结果输出为0,表示当前无锁对象;非0值表示有锁冲突。 **方法2:直接使用SQL查询(无需变量)** 如果不需要存储结果,简化语句为纯SQL: ```sql SELECT COUNT(0) AS locked_count FROM v$locked_object; ``` - 这会直接返回计数结果,避免语法错误。 #### 验证注意事项 - **权限检查**: 确保当前用户有权访问`v$locked_object`: ```sql SELECT * FROM v$reserved_words WHERE KEYWORD = 'INTO'; -- 验证INTO非保留字 (引用[2])[^2] GRANT SELECT ANY DICTIONARY TO your_user; -- 如果权限不足,需DBA授权 ``` - **错误预防**: - 始终在PL/SQL中使用`INTO`。 - 使用工具(如SQL Developer)时,确保在“PL/SQL窗口”而非“SQL窗口”执行含`INTO`的代码。 - **性能影响**: `v$locked_object`查询较轻量,但如果数据库锁频繁,引用[1]建议定期监控错误邮件[^1]。 #### 相关问题 如果您解决了ORA-00905问题,以下相关问题可能有助于深入理解: 1. 如何在Oracle PL/SQL中声明使用变量? 2. 如何监控解决Oracle数据库中的锁冲突(如使用`v$locked_object`)? 3. 常见的Oracle SQL语法错误(如ORA-00905)有哪些调试技巧? 4. Oracle动态性能视图(如`v$`系列)的访问权限如何管理? 通过上述方法,ORA-00905问题可以快速解决。如果错误仍存在,请检查PL/SQL块完整性或提供更多上下文进步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值