oracle 使用with insert插入数据的问题

本文解决了一个关于WITH子句后跟INSERT操作导致ORA-00928错误的问题。通过调整SQL语句结构,将INSERT语句移至WITH子句之前,成功避免了错误并实现了预期的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天有个写存储过程的朋友问我一个with a  as  。。。。insert 的存储过程为什么总是报错:ORA-00928: 缺失 SELECT 关键字


最后发现with后面只能直接跟select 不能跟insert,修改后解决问题


修改前:

with
 a as(SELECT T.StationId,U.Id AS UserId 
FROM Sys_Station_Info T 
JOIN  Sys_Organize O ON T.StationId=O.OrgCode
JOIN  Sys_UsersRelation R ON O.Id=R.Orgid
JOIN Sys_Users U ON U.Id=R.UserId
WHERE T.Use_Flag=1)


      INSERT INTO USEROFTENIP(StationCode,UserId,Ipaddress,Times,CreateTime)
       SELECT ba.StationId,a.UserId,L.IpAddress,COUNT(L.IpAddress) AS Times,Sysdate from .
a JOIN Sys_Log L ON a.UserId=L.UserId 
  where L.WriteTime>= sysdate-30
  GROUP BY a.StationId,a.UserId,L.IpAddress;


修改后:


       INSERT INTO USEROFTENIP(StationCode,UserId,Ipaddress,Times,CreateTime)

with
 a as(SELECT T.StationId,U.Id AS UserId 
FROM Sys_Station_Info T 
JOIN  Sys_Organize O ON T.StationId=O.OrgCode
JOIN  Sys_UsersRelation R ON O.Id=R.Orgid
JOIN Sys_Users U ON U.Id=R.UserId
WHERE T.Use_Flag=1)

       SELECT ba.StationId,a.UserId,L.IpAddress,COUNT(L.IpAddress) AS Times,Sysdate from .
a JOIN Sys_Log L ON a.UserId=L.UserId 
  where L.WriteTime>= sysdate-30
  GROUP BY a.StationId,a.UserId,L.IpAddress

### 在 Oracle 数据库中一次性插入多条数据Oracle 中,有多种方法可以实现一次性的插入多条记录。以下是几种常见的技术及其适用场景: #### 使用 `INSERT ALL` 语法 通过 `INSERT ALL` 可以在一个命令中向同一张表或多张表插入多行数据。这种方法适用于需要显式定义每一条要插入数据的情况。 ```sql INSERT ALL INTO your_table (column1, column2) VALUES ('value1', 'value2') INTO your_table (column1, column2) VALUES ('value3', 'value4') SELECT * FROM dual; ``` 上述代码展示了如何利用 `INSERT ALL` 向一张名为 `your_table` 的表中插入两条记录[^1]。 #### 单个 `INSERT INTO` 配合多个 `VALUES` 子句 自 Oracle 版本更新以来,支持一种更为简洁的方式——可以在单一的 `INSERT INTO` 声明之后跟随多个 `VALUES` 子句来完成多行数据的一次性插入操作。 ```sql INSERT INTO your_table (column1, column2) VALUES ('value1', 'value2'), ('value3', 'value4'); ``` 这种方式不仅简化了语法结构,还提高了可读性和执行效率[^2]。 #### 利用 `WITH` 子查询或虚拟表创建临时数据集并插入 如果待插入数据量较大或者存在某种规律,则可以通过 `WITH` 关键字先构造出这些数据作为中间结果再进行实际插入动作;另外也可以直接基于某些逻辑表达式的计算生成目标数据集合后再实施插入过程。 ```sql WITH temp_data AS ( SELECT LEVEL AS id, 'Row' || TO_CHAR(LEVEL) AS description FROM DUAL CONNECT BY LEVEL <= 5 ) INSERT INTO your_table (id_column, desc_column) SELECT id, description FROM temp_data; ``` 此例子说明了怎样借助伪列 `DUAL` 表以及层次化查询功能来自动生成一系列连续编号连同相应描述一同存入指定的目标字段之中. #### 结合 `MERGE` 和 `VALUES` 实现复杂条件下的批量导入 当面临既有新增又有更新需求的情形下,“UPSERT”模式就显得尤为重要。“UPSERT”的概念是指根据特定匹配规则决定某一行到底是应该被修改还是添加新的实例进去。而这种情况下就可以考虑采用 `MERGE` 加上动态产生的源数据来进行处理: ```sql MERGE INTO target_table tgt USING ( VALUES (101,'John Doe','Engineer'), -- New row to be inserted/updated. (102,'Jane Smith','Manager') ) src(id,name,title) ON (tgt.id = src.id) WHEN MATCHED THEN UPDATE SET tgt.name=src.name,tgt.title=src.title WHEN NOT MATCHED THEN INSERT (id,name,title) VALUES(src.id,src.name,src.title); ``` 这里演示了一个典型的 UPSERT 场景,在其中我们指定了两个可能的新员工信息,并告诉数据库对于已存在的ID则仅需调整其名字职称即可,而对于不存在于当前表格里的那些身份标识符关联的信息就要当作全新项加入到系统里去. ### 总结 以上介绍了四种主要途径用于解决在Oracle环境下高效地将大量离散型个体单元快速载入至持久存储介质上的难题。无论是简单重复的任务亦或是涉及业务判断更加复杂的混合型事务流程都能找到合适的解决方案予以应对。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值