PL/SQL使用INSERT...SELECT一次插入多行数据

  通常我们使用INSERT命令向表中插入行,而有时用户需要根据已有表和视图的记录,讲其中特定的数据添加到目标表中,这是可以使用INSERT...SELECT语句来实现。该语句实际上包含两个部分:INSERT(插入语句)和SELECT(查询语句),其语法可表示如下:

Insert into Table2(field1,field2,...) select value1,value2,... from Table1

  这样,通过INSERT...SELECT语句一次性向目标表中插入大量数据。另外,使用该语句时,需要注意一下几点:
    INSERT语句不能从正在被插入的表和视图中选择数据。

    在INSERT INTO语句红,列的数目必须等于从SELECT语句返回列的数目。

    在INSERT INTO语句中,列的数据类型必须与SELECT语句返回列的数据类型相同。

  T-SQL中相同效果的语法如下:SELECT vale1, value2 into Table2 from Table1。

  INSERT...SELECT语句通常用来创建一个查找表,已提高检索性能。查找表可以包含分布在多个数据库的多个表中的数据。因为多个表连接起来比简单茶韵要慢,对一个表执行SELECT查询,则明显快于执行又长又复杂的连接查询。

  今天做门诊医生站项目刚好需要从其他表中复制一些行到另外的一张表中,固写下此文。这个方法可行且高效,为证可行,截图如下:

当然,为达到这个目的,方法还有很多,本文就是提供一个解决此类需求的方案,不一定最好,仅供各位需要的博友参考~

如果你是这方面高手,温故以知新~

 

转载于:https://www.cnblogs.com/DebugLZQ/archive/2012/06/19/2554984.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PL/SQL Developer是一个集成开发环境,专门面向Oracle数据库存储程序单元的开发。如今,有越来越多的商业逻辑和应用逻辑转向了Oracle Server,因此,PL/SQL编程也成了整个开发过程的一个重要组成部分。PL/SQL Developer侧重于易用性、代码品质和生产力,充分发挥Oracle应用程序开发过程中的主要优势。 主要特性    登录界面PL/SQL编辑器,具有语法加强、SQLPL/SQL帮助、对象描述、代码助手、编译器提示、PL/SQL完善、代码内容、代码分级、浏览器按钮、超链接导航、宏库等许多智能特性,能够满足要求性最高的用户需求。当您需要某个信息时,它将自动出现,至多单击即可将信息调出。 重要功能 集成调试器   该调试器(要求Oracle 7.3.4或更高)提供您所需要的全部特性:跳入(Step In)、跳过(Step Over)、跳出(Step Out)、异常时停止运行、断点、观察和设置变量、观察全部堆栈等。基本能够调试任何程序单元(包括触发器和Oracle8 对象类型),无需作出任何修改。 PL/SQL完善器   该完善器允许您通过用户定义的规则对SQLPL/SQL代码进行规范化处理。在编译、保存、打开一个文件时,代码将自动被规范化。该特性提高了您编码的生产力,改善了PL/SQL代码的可读性,促进了大规模工作团队的协作。 SQL 窗口   该窗口允许您输入任何SQL语句,并以栅格形式对结果进行观察和编辑,支持按范例查询模式,以便在某个结果集合中查找特定记录。另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口   使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的感观,另外还增加了一个内置的带语法加强特性的脚本编辑器。这样,您就可以开发自己的脚本,无需编辑脚本/保存脚本/转换为SQL*Plus/运行脚本过程,也不用离开PL/SQL Developer集成开发环境。 报告   PL/SQL Developer提供内置的报告功能,您可以根据程序数据或Oracle字典运行报告。PL/SQL Developer本身提供了大量标准报告,而且您还可以方便的创建自定义报告。自定义报告将被保存在报告文件中,进而包含在报告菜单内。这样,运行您自己经常使用的自定义报告就非常方便。   您可以使用Query Reporter免费软件工具来运行您的报告,不需要PL/SQL Developer,直接从命令行运行即可。 工程   PL/SQL Developer内置的工程概念可以用来组织您的工作。一个工程包括源文件集合、数据库对象、notes和选项。PL/SQL Developer允许您在某些特定的条目集合范围之内进行工作,而不是在完全的数据库或架构之内。这样,如果需要编译所有工程条目或者将工程从某个位置或数据库移动到其他位置时,所需工程条目的查找就变得比较简单。 To-Do条目   您可以在任何SQLPL/SQL源文件中使用To-Do条目快速记录该文件中那些需要进行的事项。以后能够从To-Do列表中访问这些信息,访问操作可以在对象层或工程层进行。 对象浏览器   可配置的树形浏览能够显示同PL/SQL开发相关的全部信息,使用该浏览器可以获取对象描述、浏览对象定义、创建测试脚本以便调试、使能或禁止触发器或约束条件、重新编译不合法对象、查询或编辑表格、浏览数据、在对象源中进行文本查找、拖放对象名到编辑器等。   此外,该对象浏览器还可以显示对象之间的依存关系,您可以递归的扩展这些依存对象(如包参考检查、浏览参考表格、图表类型等)。 性能优化   使用PL/SQL Profiler,可以浏览每一执行的PL/SQL代码行的时序信息(Oracle8i或更高),从而优化您SQLPL/SQL的代码性能。   更进一步,您还可以自动获取所执行的SQL语句和PL/SQL程序统计信息。该统计信息包括CPU使用情况、块I/O、记录I/O、表格扫描、分类等。 HTML指南   Oracle目前支持HTML格式的在线指南。您可以将其集成到PL/SQL Developer工作环境中,以便在编辑、编译出错或运行时出错时提供内容敏感帮助。 非PL/SQL对象   不使用任何SQL,您就可以对表格、序列、符号、库、目录、工作、队列、用户和角色进行浏览、创建和修改行为。PL/SQL Developer提供了一个简单易用的窗体,只要将信息输入其中,PL/SQL Developer就将生成相应的SQL,从而创建或转换对象。 模板列表   PL/SQL Developer的模板列表可用作一个实时的帮助组件,
PL/SQL 基础,一个不错的 PL/SQL 参考手册。内容预览: ---- 第一章 PL/SQL 简介 ---- 1. Oracle应用编辑方法概览 1) Pro*C/C++/... : C语言和数据库打交道的方法,比OCI更常用; 2) ODBC 3) OCI: C语言和数据库打交道的方法,和Pro*C很相似,更底层,很少用 只适合ORACLE; 4) SQLJ: 很新的一种用Java访问Oracle数据库的方法,会的人不多; 5) JDBC 6) PL/SQL: 存储在数据库内运行, 其他方法为在数据库外对数据库访问,只适合ORACLE; 2. PL/SQL 1) PL/SQL(Procedual language/SQL)是在标准SQL的基础上增加了过程化处理的语言; 2) Oracle客户端工具访问Oracle服务器的操作语言; 3) Oracle对SQL的扩充; 4. PL/SQL的优缺点 优点:1) 结构化模块化编程,不是面向对象; 2) 良好的可移植性(不管Oracle运行在何种操作系统); 3) 良好的可维护性(编译通过后存储在数据库里); 4) 提升系统性能; 缺点 1) 不便于向异构数据库移植应用程序(只能用于Oracle); 5. SQLPL/SQL的区别 SQL:1) 第四代语言(智能语言); 2) 做什么,不管怎么做; 3) 缺少过程与控制语句; 4) 无算法 PL/SQL: (相对SQL扩展部分) 1) 扩展变量和类型; 2) 扩展控制结构; 3) 扩展过程与函数; 4) 扩展对象类型与方法 ---- 第二章 PL/SQL程序结构 ---- 1. PL/SQL块 1) 申明部分, DECLARE (如果语句不需要声明任何变量,可以不写); 2) 执行部分, BEGIN <---------> END; 3) 异常处理,EXCEPTION(可以没有); 2. PL/SQL开发环境 可以运用任何纯文本的编辑器编辑,例如:VI 3. PL/SQL字符集 字母: A-Z, a-z; 数字: 0-9; 空白: TAB , SPACE , 回车; 符号: +_)(*&^%$#@!~ ; PL/SQL对大小写不敏感(注意) 4. 标识符命名规则答: 1) 字母开头; 2) 后跟任意的 非空格字符 数字 货币符号( $ ) 下划线( _ ) 或 # ; 3) 最大长度为30个字符(八个字符左右最合适); 用来给对象命名(潜规则): 变量: 以v_开头 游标: 以c_开头 类型: 子程序: 5. 分界符 1) 运算符 + - * / **(指数操作符) 2) 关系 =(相当于JAVA中的==) > < <> != ~= ^= <= >= 3) 赋值 := 例子a:=2 4) 连接 || 例: 'abc' || 123 5) 标号 << 需要的标记 >> 6) 注释 --(单行) /* */(段落) 7) 替代 <scape> <tab> <enter> 6. 文字 1)字符型文字(字符串) 'tom' (单引号) 'tom''s pen' ''为2个单引号(标识转义) 为tom's pen 2)数字型 123 -4 +56 0 9.0 1.23E5 9.8e-3 3)布尔型 TRUE FALSE NULL 7. 变量声明 语法 Var_name [CONSTANT](标识常量,可选) type [NOT NULL](标识为not-null后必须在后面初始化) [:=value](赋值,初始化); Var_name [CONSTANT](标识常量,可选) type [NOT NULL] [ default value](赋值,初始化)等同于上面的语句; 注:1) 申明时可以有默认值也可以没有; 2) 如有[CONSTANT][NOT NULL], 变量一定要有一个初始值; 3) 赋值语句为“:=”; 4) 变量可以认为是数据库里一个字段; 5) 规定没有初始化的变量为NULL; ---- 第三章 变量与数据类型 ---- 1. 数据类型 1) 标量型:数字型(BINARY_INTEGER,NUMBER)(DEC,FLOAT,REAL... NUMBER的子类型)、 NUMBER(P,S) P:精度:整个的有效数位(从左边开始第一个不为0的数字起) S:刻度,可选(小数点后面的保留位数) BINARY_INTEGER:保存整数. 和NUMBER的底层的保存方式不同, BINARY_INTEGER为2进制保存,NUMBER 需要考虑其他东西不是2进制方式 BINARY_INTEGER之间做加法效率快而NUMBER要先转换2进制再计算 单纯的计算---->BINARY_INTEGER 考虑和表中其他数据的交互的话一般------->NUMBER 字符型、CHAR VARCHAR VARCHAR2 STRING LONG 一般CHAR VARCHAR2就够了 CHAR 定长(例子:CHAR(5) 如果不够5个字符的话就会用空白填充 ) ,可以不带长度规定(默认为1) VARCHAR2 变长((VARCHAR2(5)标识最长可以保存5个字符) 后面的长度规定必须要有 布尔型、BOOLEAN 日期型; DATE(后增加 TIMESTAMP(比DATE更精细点(精确到秒) INTERVAL) 一般用DATE 2) 组合型:RECORD(常用)、TABLE(常用)、VARRAY(较少用) 3) 参考型:REF CURSOR(游标)、REF object_type 4) LOB(Large Object) 2. %TYPE [变量名] [表名.字段名] [%TYPE] 表示变量具有与数据库的表中某一字段相同的类型 例:v_FirstName s_emp.first_name%TYPE; 3. RECORD类型 TYPE t_emp IS RECORD( /*其中TYPE,IS,RECORD为关键字,record_name为变量名称*/ field1 type [NOT NULL][:=expr1], /*每个等价的成员间用逗号分隔*/ field2 type [NOT NULL][:=expr2], /*如果一个字段限定NOT NULL,那么它必须拥有一个初始值*/ ... /*所有没有初始化的字段都会初始为NULL*/ fieldn type [NOT NULL][:=exprn] ); 4. %ROWTYPE 返回一个基于数据库定义的类型 DECLARE v_emp s_emp%ROWTYPE; /*s_emp为表的名字*/ 注:与RECORD类型中定一个record相比,一步就完成, 而RECORD类型中定义分二步:a. 所有的成员变量都要申明; b. 实例化变量; 可以代替RECORD类型. 5. TABLE类型 TYPE tabletype IS TABLE OF type(类型名,要保存成的数据类型) INDEX BY BINARY_INTEGER; 例:DECLARE TYPE t_emp IS TABLE OF s_emp%ROWTYPE INDEX BY BINARY_INTERGER; v_emp t_emp; BEGIN SELECT * INTO v_emp(100) FROM s_emp WHERE id = 1; SELECT * INTO v_emp(200) FROM s_emp WHERE id = 2; DBMS_OUTPUT.PUT_LINE(v_emp(200).id||' '||v_emp(200).lastname||' '||v_emp(200).salary); END; 注:1) id(索引) 的数目的限制由BINARY_INTEGER的范围决定(-2147483647<----->2147483647); 2) TABLE类型与map<int,_T>类似; 3) 表中的元素可以是复合类型; 4) KEY 没有必要是顺序的; 5) 当数据插入表中的时候,表所需的空间就被分配了; 6. 变量的作用域和可见性 <<outer>> 1) 执行块里可以嵌入执行块; 2) 里层执行块的变量对外层不可见; 3) 里层执行块对外层执行块变量的修改会影响外层块变量的值 (在此里层,对其他里层则不影响,想要不影响此里层的话可以使用标号标注外层); ---- 第四章 PL/SQL控制语句 ---- 1. 条件语句 IF boolean_expression1(条件1) THEN ... ELSIF boolean_expression2(条件2) THEN /*注意是ELSIF,而不是ELSEIF*/ ... /*ELSE语句(ELSIF)不是必须的,但END IF;是必须的*/ ELSE ... END IF; 注意:1)有多个BOOLEAN表达式时候 AND(与),OR(或),NOT(非) 2)条件为FALSE与TRUE 相同; 2. 循环语句 1) Loop 循环 Loop ... (循环体) IF boolean_expr(条件) THEN /* 加条件语句,当满足条件时候退出循环*/ EXIT; /* EXIT WHEN boolean_expr */ END IF; END LOOP; 2) WHILE 循环 WHILE boolean_expr(条件) LOOP /* boolean_expr 循环条件*/ ... (循环体) END LOOP; 3) FOR循环 FOR loop_counter IN [REVERSE] low_bound..high_bound LOOP /* 范围中间用2个点表示 从 low_blound 到 high_bound */ ... (循环体) END LOOP; 例: FOR v_cnt IN 1..5 LOOP SELECT * INTO v_emp FROM s_emp WHERE id = v_cnt; 注:a. 加上REVERSE关键字 表示递减,从结束边界到起始边界,递减步长为一; 不加为递增,从起始边界到结束边界,递减步长为一; b. low_blound 起始边界; high_bound 结束边界; 3. GOTO语句 GOTO label_name; 1) 只能由内部块跳往外部块; 2) 设置标签:<< >> 3) 示例: LOOP ... IF D%ROWCOUNT = 50 THEN GOTO l_close; END IF; ... END LOOP; <<l_close>>: ... 4. NULL语句 在语句块中加空语句,用于补充语句的完整性。 例:IF boolean_expr THEN ... ELSE NULL; END IF; 5. SQL in PL/SQL 1) 只有DML SQL和transaction Control SQL可以直接在PL/SQL使用; 2) PL/SQL中的动态SQL可以使用所有有效的SQL语句,包括DDL; 3) 动态SQL在运行时动态生成SQL语句,然后分析语句并执行; 4) PL/SQL中的动态SQL有两种:本地动态SQL和DBMS_SQL包; ---- 第五章 PL/SQL游标 ---- 1. 游标(CURSOR) 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数 据指针,在初始状态下指向的是首记录,利用 fetch 语句可以移动该指针,从而对游标中的数 据进行各种操作,然后将操作结果写回数据表中。 1)分类: a)显式游标:程序员可以操作控制,是针对select 语句的,指向select 语句的结束集 b)隐式游标:程序员不可控制,但可以有限制的应用 2)作用:用于处理查询语句的结果,提取多行数据集; 3)使用步骤: a) 声明游标: a. 普通声明: DELCARE v_emp s_emp%ROWTYPE; v_did s_dept.id%TYPE; CURSOR cur_emp IS select * FROM s_emp WHERE dept_id =v_did; /* CURSOR的内容必须是一条查询语句 */ b. 带参数声明明:DELCARE CURSOR c_emp(v_did s_emp.ID%TYPE) SELECT * FROM s_emp WHERE dept_id = v_did; b) 为查询打开游标: OPEN cur_emp; /* 相当于执行select语句,且把执行结果存入CURSOR; c) 从游标中取结果,存入PL/SQL变量中: a. FETCH cur_emp INTO var1, var2, ...(变量名 1, 变量名 2,.......); /* 变量的数量、类型、顺序要和Table中字段一致; */ b. FETCH cur_emp INTO record_var(记录型变量名); 注:将值从CURSOR取出放入变量中,每FETCH一次取一条记录; d) 关闭游标: CLOSE cur_emp; 注:a. 游标使用后应该关闭; b. 关闭后的游标不能FETCH和再次CLOSE; c. 关闭游标相当于将内存中CURSOR的内容清空; 2. 游标的属性 游标名%属性名 1) %FOUND: 是否有值; 有则返回TRUE,否则返回FALSE; 2) %NOTFOUND: 是否没有值; 如果没有值则返回TRUE,否则返回FALSE; 3) %ISOPEN: 是否是处于打开状态; 处于打开状态就返回TRUE,否则返回FALSE; 4) %ROWCOUNT: CURSOR当前的记录号(当前游标的指针位移量,表示在此之前,游标所处理的数据量(多少条记录)); 3. 游标的FETCH循环 1) LOOP FETCH 游标名 INTO 定义的变量 EXIT WHEN 游标名%NOTFOUND; /* 当游标没取道记录后退出 要及时的做出判断 */ END LOOP; 2) WHILE 游标名%FOUND LOOP FETCH 游标名 INTO 定义的变量; END LOOP; 3) FOR 保存数据的变量(不用事先定义,是根据游标声明的时候SELECT 的类型来确定) IN 游标名 LOOP (FETCH 游标名 INTO ...) (可以不用FETCH 语句) END LOOP; 4.带参数的游标CURSOR DECLARE v_emp s_emp%ROWTYPE CURSOR cur_emp(p_did s_emp.dept_id%TYPE) IS /* 定义参数p_did的类型 */ SELECT * FROM s_emp WHERE dept_id= p_did FOR UPDATE OF salary; /*FOR UPDATE OF salary; 加行级锁,在我修改这些数据的时候, *其他人无法修改数据,直到游标被CLOSE后 */ BEGIN OPEN cur_emp(31); /*带的参数值 31 就是赋给参数p_did 的 */ LOOP FETCH cur_emp INTO v_emp; EXIT WHEN cur_emp%NOTFOUND; DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name); END LOOP; CLOSE cur_emp; END 5.显式游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况下; 而对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL,这是由ORACLE 系统定义的。 对于隐式游标的操作,如定义、打开、取值及关闭操作,都由ORACLE 系统自动地完成,无需用户进行处理。 用户只能通过隐式游标的相关属性,来完成相应的操作。 在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL 语句所包含的数据。 格式调用为: SQL% 注:INSERT, UPDATE, DELETE, SELECT 语句中不必明确定义游标。 隐式游标属性 SQL%FOUND 布尔型属性,当最近一次读记录时成功返回,则值为true; SQL%NOTFOUND 布尔型属性,与%found相反; SQL %ROWCOUNT 数字型属性, 返回已从游标中读取得记录数; SQL %ISOPEN 布尔型属性, 取值总是FALSE。SQL命令执行完毕立即关闭隐式游标。
C# 访问Oracle示例+PL/SQL+存储过程+触发器 完整示例 测试可用 --PL/SQL基础1 declare begin dbms_output.('不输出不换行'); dbms_output.put_line('输出并换行'); end; --PL/SQL基础2 declare dig number(20,2); begin select avg(price) into dig from products; dbms_output.put_line('电子产品的平均价格是'||dig); end; --PL/SQL基础3 根据产品编号获得产品对象 --pname products.name%type; pname变量的类型与products.name列的类型一样 declare pid constant products.id%type:=1; --定义常量,初值1 pname products.name%type; pdate products.adddate%type; begin --pid:=1; select name,adddate into pname,pdate from products where id=pid; dbms_output.put_line('产品名称是:'||pname||',日期'||pdate); end; --PL/SQL基础4 根据产品编号获得产品对象 --obj products%rowtype; obj与products表的单行类型一样,可以通过点运算取值obj.price declare obj products%rowtype; begin select * into obj from products where id=&编号; dbms_output.put_line('产品名称是:'||obj.name||',价格:'||obj.price); end; --PL/SQL基础5 条件if declare vid products.id%type; vprice products.price%type; begin vid:=&编号; select price into vprice from products where id=vid; if vprice100 and vprice<=1000 then dbms_output.put_line('价格在100—1000之间'); else dbms_output.put_line('价格在1000以上'); end if; end; --PL/SQL基础5 多条件case begin case '&等级' when 'A' then dbms_output.put_line('优秀'); when 'B' then dbms_output.put_line('合格'); when 'C' then dbms_output.put_line('不合格'); end case; end; select id, name, typeid, price, adddate from products create table students( Id int primary key, sex int ) insert into students select 1,1 from dual union select 2,0 from dual union select 3,1 from dual union select 4,0 from dual union select 5,1 from dual insert into students(Id) values(6) select * from students; select translate(translate('1心1意 3心2意','1','一'),'3','三') from dual; select id,nvl(translate(translate(sex,1,'女'),0,'男'),'未知') from students; select id,case as 性别 from( sele

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值