精华内容
下载资源
问答
  • 到微软官网下载SQL Server Developer版本,现在最新版本是SQL Server 2019 Developer。... 下载完成之后,在文件夹中...点了安装之后会出现如下图所示界面,我们需要等待它下载安装包,此过程等待时间可能较长...

    文章目录

    一、安装SQL Server
    二、安装SQL Server Management Studio
    三、编写SQL语句


    一、安装SQL Server

    1.到微软官网下载SQL Server Developer版本,现在的最新版本是SQL Server 2019 Developer。微软官网传送门:点击此处直达
    在这里插入图片描述

    2.下载完成之后,在文件夹中找到刚才下载的文件,双击打开,打开之后的界面如下图所示。
    在这里插入图片描述

    3.我们选择自定义安装,之后再选择要安装的位置,再点击安装,如下图所示
    在这里插入图片描述

    4.点了安装之后会出现如下图所示的界面,我们需要等待它下载安装包,此过程等待的时间可能较长
    在这里插入图片描述

    5.安装包下载并提取完成之后,会出现下图所示的界面
    在这里插入图片描述

    6.依次点击安装、全新SQL Server独立安装或向现有安装添加功能,如下图所示
    在这里插入图片描述

    7.出现如下图所示的界面,不用管密钥,点击下一步
    在这里插入图片描述

    8.再点击我接受许可条款,点击下一步,之后新出现的窗口会让你选择是否检查更新,大家可以根据自己的需要选择,默认是不检查更新,再点击下一步,这时会显示正在检查更新,如下图所示,不用管它,直接点击下一步
    在这里插入图片描述

    9.出现下图所示的界面时,点击下一步
    在这里插入图片描述

    10.实例功能部分按照下图进行勾选,其余的可以根据自己的需要进行选择,设置好了之后点击下一步
    在这里插入图片描述

    11.出现如下图所示的界面,使用默认选择,点击下一步
    在这里插入图片描述

    12.不用做更改,点击下一步
    在这里插入图片描述

    13.在下图所示的界面中,将我用红色矩形圈起来的地方进行修改,系统管理员的名称为sa,密码需要自己设定,一定不要忘了点击添加当前用户按钮。点击下一步。
    在这里插入图片描述

    14.点击安装

    15.等待一段时间,即可看到安装成功,点击右下角关闭即可
    在这里插入图片描述


    二、安装SQL Server Management Studio

    1.到微软官网下载SQL Server Management Studio,如下图所示。
    官网传送门:点此直达官网

    在这里插入图片描述

    2.将下载的SSMS-Setup-CHS双击打开,如下图所示,选好安装位置之后,点击安装即可
    在这里插入图片描述

    3.等待一段时间后可以看到安装成功的提示,点击关闭退出安装
    在这里插入图片描述


    三、编写SQL语句

    1.在开始菜单中,找到刚才安装的Microsoft SQL Server Management Studio,单击打开,如下图所示
    在这里插入图片描述

    2.打开SSMS后,会让你连接服务器,点击连接就能连接到本地服务器
    在这里插入图片描述

    3.成功连接本地服务器之后的界面如下图所示
    在这里插入图片描述

    4.点击下图红色矩形圈起来的新建查询
    在这里插入图片描述

    5.在输入框中输入下面的代码

    Use Master;
    GO
    CREATE Database MyDatabase1;
    GO
    Use MyDatabase1;
    GO
    CREATE TABLE student
    (
    学号 char(8)  PRIMARY KEY,
    姓名 varchar(8)  NOT NULL,
    性别 char(2)  CHECK( 性别 = '男' OR  性别 = '女'),
    成绩 numeric(4,1)  CHECK( 成绩 >= 0 AND  成绩 <= 100)
    );
    GO
    INSERT INTO student VALUES('20102001',' 阎妮','女', 98);
    INSERT INTO student VALUES('20102002',' 张有来','男', 58);
    INSERT INTO student VALUES('20102003',' 王文喜','男', 72);
    INSERT INTO student VALUES('20102004',' 赵敏','女', 66);
    INSERT INTO student VALUES('20102005',' 罗莎','女', 88.5);
    INSERT INTO student VALUES('20102006',' 蒙恬','男', 93);
    GO
    
    

    6.点击执行
    在这里插入图片描述

    7.在对象资源管理器中依次展开数据库MyDatabase1,如下图所示

    在这里插入图片描述

    8.将光标移动到dbo.student,右键,点击编辑前200百行,如下图所示
    在这里插入图片描述

    9.现在可以看到我们刚才插入的数据,如下图所示
    在这里插入图片描述

    展开全文
  • 虽然 Oracle 和 sql sever 是不同的数据库,但其一些基础语法还是比较一致的,但细微也有点区别,...在 SQL *Plus 环境中编写较长的 SQL 语句时,按回车键即可实现换行。需要注意的是,在按回车键之前不要输入分号,...

    虽然 Oracle 和 sql sever 是不同的数据库,但其一些基础语法还是比较一致的,但细微也有点区别,这里就简单介绍下 Oracle 数据库中 SQL 语言的使用。

    目录

    用户模式

    检索数据

    1、简单查询

    2、筛选查询

    3、多表关联查询


     

    用户模式

    在 SQL *Plus 环境中编写较长的 SQL 语句时,按回车键即可实现换行需要注意的是,在按回车键之前不要输入分号,分号表示 SQL 语句的结束

    在 Oracle 数据库中,为了方便管理用户所创建的数据库对象(如数据表、索引、视图等),引入了模式的概念,这样某个用户所创建的数据库对象就都属于该用户模式。模式是一个数据库对象的集合,为一个数据库用户所有,并且具有与该用户相同的名称,如 system 模式、scott 模式等。在一个模式内部不可以直接访问其他模式的数据库对象,即使在具有访问权限的情况下,也需要指定模式名称才可以访问其他模式的数据库对象。

    模式对象是由用户创建的逻辑结构,用以存储或引用数据。简单地说,模式与模式对象之间的关系就是拥有和被拥有的关系,即模式拥有模式对象,而模式对象被模式拥有。一个不属于某个用户所拥有的数据库对象就不能称之为模式对象,如角色、表空间及目录等数据库对象。

    这里我们再介绍一个典型的示例模式——scott 模式,该模式及其所拥有的模式对象在后面经常使用到,Oracle 数据库提供的 scott 模式的目的就是为了给用户提供一些示例表和数据来展示 Oracle 数据库的一些特性。scott 模式拥有的模式对象(都是数据表)如下:

    emp (员工信息表)   dept (部门表)  
    empno

    number (4)

    deptno number (2)
    ename varchar (10) dname varchar (14)
    job (职位) varchar (9) loc (所在位置) varchar (13)
    mgr (经理) number (4)    
    hiredate (入职日期) date    
    sal (基本工资) number (7,2)    
    comm (奖金) number (7,2)    
    deptno (部门编号) number (2)    
    salgr(工资等级表)   bonus (工资表)  
    grade (工资等级) number ename varchar (10)
    losal (该等级下的最低工资) number job varchar (9)
    hisal (该等级下的最高工资) number sal number
        comm number

    该模式演示了一个很简单的公司人力资源管理的数据结构,它也是 Oracle 的各个版本中一直在沿用的示例模式。

    我们可以连接到 scott 用户模式,查询数据字典视图 user_tables 可以获得该模式所包含的数据表,如下:

    我们也可以在 system 模式下查询 scott 模式所拥有的数据表,但要求使用 dba_tables 数据表,如下:

    别忘了模式名要大写!!

     

    检索数据

    这部分和 sql sever 中数据查询的语法差不多一致,这里就简述一下,不过多详细介绍,如果有什么地方不清楚的话,看我前面关于 SQL 语言的博客吧。

    1、简单查询

    只包含 select 子句和 from 子句的查询就是简单查询,select 子句和 from 子句是 select 语句的必选项,就是说,每个 select 语句都必须包含这两个子句。

    上面的查询若要在 system 模式下执行,则需要在表 dept 前面加上 scott ,即 “ scott.dept ”,另外 from 子句的后面可以指定多个数据表,每个数据表名之间用逗号 (,) 分隔开。

    使用星号(*) 来检索所有的列,此时的数据将按照表结构的自然顺序来显示。用户也可以指定查询表中的某些列而不是全部列,并且被指定列的顺序不受控制,指定部分列也称作投影操作,这些列名紧跟在 select 关键字后面,每个列名之间用逗号隔开,而使用 select 指定列的好处就是可以改变列在查询结果中的默认显示顺序。

    在 Oracle 数据库中,有一个标识行中唯一特性的行标识符,该标识符的名称为 rowid 。行标识符 rowid 是 Oracle 数据库内部使用的隐藏列,由于该列实际上并不是定义在表中的,所以也称为伪列。伪列 rowid 是长度为18的字符,包含了该行数据在 Oracle 数据库中的物理地址。用户使用 describe 命令是无法查到 rowid 列的,但是可以在 select 语句中检索到该列

    在使用 select 语句时,对于数字数据和日期数据都可以使用算术表达式。在 select 语句中可以使用算术运算符,包括 +、-、*、/和括号,另外在 select 语句中不仅可以执行单独的数学运算,还可以执行单独的日期运算以及与列名关联的运算。

    在很多的数据表中,其列名都是一些英文的缩写,用户为了方便查看检索结果,可以为这些列指定别名。在 Oracle 系统中,为列指定别名既可以使用 as 关键字,也可以不使用任何关键字而直接指定

    在默认情况下,结果集中包含所有符合查询条件的数据行,这样在结果集中就有可能出现重复数据,而在实际的应用中,这些重复的数据除了占据较大的显示空间外,可能不会给用户带来太多有价值的东西,这样就需要除去重复记录,保留唯一的记录即可。在 select 语句中,同样使用 distinct 关键字来限制在查询结果显示不重复的数据,该关键字用在 select 子句的列表前面。 

     

    2、筛选查询

    在 select 语句中使用 where 子句可以实现对数据行的筛选操作,只有满足 where 子句中判断条件的行才会显示在结果集中,而那些不满足 where 子句判断条件的行则不包括在结果集中。这种筛选是非常有意义的,通过筛选数据,可以从大量的数据中得到用户所需要的数据。在 select 语句中,where 子句位于 from 子句之后。

    1)、比较查询

    在 where 子句中使用比较运算符来筛选数据,基本的比较筛选操作主要有一下6种情况:A=B、A!=B或A<>B(都是比较A与B是否不相等)、A<B、A>B、A>=B、A<=B。

    另外,除了基本的比较筛选操作外,还有两个特殊的比较筛选操作,具体如下:A {operator} any (B) 表示 A 与 B 中任何一个元素进行 operator 运算符的比较,只要有一个比较值为 true ,就返回数据行;A={operator} all (B) 表示 A 与 B 中的所有元素进行 operator 运算符的比较,只有与所有元素比较值都为 true 时,才返回数据行。 

    另外需要注意的是:在进行比较筛选的过程中,字符串和日期的值必须使用单引号标识,否则 Oracle 会提示 “标识符无效”。

    2)、特殊关键字查询

    SQL 语言提供了 like、in、between 和 is null 等关键字来筛选数据,这些关键字的功能分别是匹配字符串、查询目标值、限定值的范围和判断值是否为空等,下面简单来说一下。

    使用 like 关键字查询数据的方式也称字符串模式匹配或字符串模糊查询,like 关键字需要使用通配符在字符串内查找指定的模式,所以需要了解常用的通配符。常用的通配符有下划线 “ _ ” ,它代表一个字符;百分号 “ % ” ,它代表任意数量的字符。比如,“ K% ” 表示以字母 K 开头的任意长度的字符串, “ %M% ” 表示包含字母 M 的任意长度的字符串,“ _MRKJ ” 表示5个字符长度且后面4个字符是 MRKJ 的字符串。另外可以在 like 关键字前面加上 not 表示否定的判断,如果 like 为真,则 not like 为假,其他的如 in、between 和 is null 等关键字前面均可通过加上 not 来表示否定判断

    当测试一个数据值是否匹配一组目标值中的一个时,通常使用 in 关键字来指定列表搜索条件。in 关键字的格式是 in(目标1,目标2,目标3,... ),目标值的项目之间必须使用逗号分隔,并且括在括号中。

    当需要返回某一个数据值是否位于两个给定的值之间,可以使用范围条件进行检索。通常使用 between...and 和 not between ... and 来指定范围条件。使用 between ... and 查询条件时,指定的第一个值必须小于第二个值,因为 between ... and 实质是查询条件 “大于等于第一个值,并且小于等于第二个值” 的简写形式,等价于比较运算符 (>= ... <=)。

    空值(null)从技术上来说就是未知的、不确定的值,但空值与空字符串不同,因为空值是不存在的值,而空字符串是长度为 0 的字符串。因为空值代表的是未知的值,所以并不是所有的空值都相等。比如,student 表中有两个学生的年龄未知,但无法证明这两个学生的年龄相等,这样就不能用 “=” 运算符来检测空值,所以 SQL 引入了一个 is null 关键字来检测特殊值之间的等价性。 is null 关键字通常在 where 子句中使用。

    逻辑筛选是指在 where 子句中使用逻辑运算符 and 、or 和 not 进行数据筛选操作,那么这些逻辑运算符可以把多个筛选条件组合起来,以便于用户获取更加准确的数据记录。

    3)、分组查询

    数据分组的目的是用来汇总数据或为整个分组显示单行的汇总信息,通常在查询结果集中使用 group by 子句对记录进行分组。在 select 子句中,group by 子句位于 from 子句之后,也在 where 条件子句之后。group by 子句可以基于指定某一列的值将数据集合划分为多个分组,同一组内所有记录在分组属性上具有相同值,也可以基于指定多列的值将数据集合划分为多个分组。

    group by 子句经常与聚集函数一起使用,如果 select 子句中包含聚集函数,则计算每组的汇总值,当用户指定 group by 时,选择列表中任一非聚集表达式内的所有列都应包含在 group by 列表中,或者 group by 表达式必须与选择列表表达式完全匹配。

    having 子句可以对 group by 子句选择出来的结果进行再次筛选,最后输出符合 having 子句中条件的记录,having 子句的语法与 where 子句的语法比较相似,不同的是,having 子句中可以包括聚合函数,如count、avg、sum等,而 where 子句中不可使用

    4)、排序查询

    在检索数据时,如果把数据从数据库中直接读取出来,这时查询结果将按照默认顺序排列,但往往这种默认排列顺序并不是用户所需要看到的。尤其返回数据量较大时,用户查看自己想要的信息非常不方便,因此需要对检索的结果集进行排序。在 select 语句中,可以使用 order by 子句对检索的结果集进行排序,该子句位于 from 子句之后(where 之后,以及 group by 子句之后)

    关键字 asc 表示按升序排列,也是默认的排序方式,desc 表示降序排列。另外 order by 子句也可以根据查询结果中的一个列或多个列对查询结果进行排序,并且第一个排序项是主要的排序依据,其次那些是次要的排序依据

     

    3、多表关联查询

    1)、表的别名

    在多表关联查询时,如果多个表之间存在同名的列,则必须使用表名来限定列的引用。例如,在 scott 模式中,dept 表和 emp 表都有 deptno 列,那么当用户使用该列关联查询两个表时,就需要通过指定表名来区分这两个列的归属,但随着查询变得越来越复杂,语句就会因为每次限定列必须输入表名而变得冗长乏味,。对于这种情况,SQL 语言提供了设定表别名的机制,通过使用简短的表别名就可以替代原有较长的表名称,这样就可以大大缩减语句的长度。

    需要注意的是,一旦在 from 子句中为表指定了别名,则必须在剩余的子句中都使用表的别名,而不允许再使用原来的表名称

    2)、内连接

    内连接是一种常用的多表关联查询方式,一般使用关键字 inner join 来实现。其中 inner 关键字可以省略,但只使用 join 关键字时,语句只表示内连接操作。在使用内连接查询多个表时,必须在 from 子句之后定义一个 on 子句,该子句用来指定两个表实现内连接的 “连接条件” 。需要注意的是,在内连接的检索结果中,所有记录行都是满足连接条件的。其连接的语法格式如下:

    select columns_list
    from table_name1 [inner] join table_name2
    on join_condition ;
    
    // columns_list :字段列表
    // table_name1 和 table_name2 :两个要实现内连接的表
    // join_condition :实现内连接的条件表达式

    3)、外连接

    使用内连接进行多表查询时,返回的查询结果中只包含符合查询条件和连接条件的行。内连接消除了与另一个表中的任何行不匹配的行,而外连接扩展了内连接的结果集,除了返回有匹配的行外,还会返回一部分或全部不匹配的行,这主要取决于外连接的种类。外连接通常有以下三种:1)、左外连接:关键字为 left outer join 或 left join ;2)、右外连接:关键字为 right outer join 或 right join ;3)、完全外连接:关键字为 full outer join 或 full join 。

    与内连接不同的是,外连接不只列出与连接条件匹配的行,还能够列出左表(左外连接时)、右表(右外连接时)或两个表(完全外连接时)中所有符合搜索条件的数据行。

    左外连接的查询结果中不仅包含了满足连接条件的数据行,而且还包含左表中不满足连接条件的数据行。

    上面例子首先是使用 insert 语句在 emp 表中插入新纪录(注意没有为 deptno 和 dname 列插入值,即它们的值为 null),然后实现 emp 表和 dept 表之间通过 deptno 列进行左外连接,从查询结果我们也可以看出,虽然插入数据行的 deptno 列值为 null ,但该记录仍然出现在查询结果中,这说明左外连接的查询结果会包含左表中不满足 “连接条件” 的数据行

    同样,右外连接的查询结果中不仅包含了满足连接条件的数据行,而且还包含右表中不满足连接条件的数据行。见下:

    上面的查询结果中,虽然部门编号为 40 的部门现在在 emp 表中还没有员工记录,但它却出现在查询结果中,这说明右外连接的查询结果会包含右表中不满足 “连接条件” 的数据行。

    而在执行完全外连接时,Oracle 会执行一个完整的左外连接和右外连接查询,然后将查询结果合并,并消除重复的记录行。

    4)、自然连接

    自然连接是指在检索多个表时,Oracle 会将第一个表中的列与第二个表中具有相同名称的列进行自动连接。在自然连接中,用户不需要明确指定进行连接的列,这个任务由 Oracle 系统自动完成自然连接使用 “natural join” 关键字

    自然连接强制要求表之间必须具有相同的列名称,这样容易在设计表时出现不可预知的错误,所以在实际应用系统开发中很少使用到自然连接。但这毕竟是一种多表关联查询数据的方式,在某些特定情况下还是有一定的使用价值。另外需要注意的是,在使用自然连接时,不能为列指定限定词(即表名或表的别名),否则 Oracle 系统将会提示自然连接中使用的列不能有限定词的错误提示。

    5)、自连接

    在应用系统开发中,用户可能会拥有 “自引用式” 的外键。“自引用式” 外键是指表中的一个列可以是该表主键的一个外键。例如,在 scott 模式下,emp 表中某一行的 mgr 列值(管理者列)可能是另一行的 empno 列值(员工列),因为管理者本身也是公司的员工,这样用户就可以通过 mgr 列与 empno 列的关系,实现查询某个管理者所管理的下属员工信息。

    6)、交叉连接

    交叉连接实际上就是不需要任何连接条件的连接,它使用 cross join 关键字来实现,其执行结果是一个笛卡儿积,而且这种查询结果是非常冗余的,但可以通过 where 子句来过滤出有用的记录信息。

     

    展开全文
  • 1.select语句*号问题...如varchar2(1000)以上字段,但该SQL实际并不需要取出该字段值  3)字段数量多,但实际使用字段很少,比如表有50个字段,而实际需要使用只有5个,并且该SQL没有被重用2.严格

    1.select语句中的*号问题

      多表连接必须杜绝使用select *

      单表连接,一般情况不建议使用select *,但是如果出现以下情况,必须禁用:

      1)表中包含lob字段(BLOB,CLOB,LONG,RAW等)

      2)表中包含长度较大的字段,如varchar2(1000)以上的字段,但该SQL实际并不需要取出该字段的值

      3)字段数量较多,但实际使用的字段很少,比如表有50个字段,而实际需要使用的只有5个,并且该SQL没有被重用

    2.严格要求使用正确类型的变量,杜绝oracle做隐式类型转换的情况

      1)推荐在sqlmap的变量中制定变量的数据类型,如:

           select * from tablename where id = #id:VARCHAR#

      2)对于时间类型的字段,必须使用TO_DATE进行赋值(当前时间可直接用sysdate表示)

           错误的写法(使用date类型的变量):

           select * from tablename where id = #id:varchar#

              and dt >= #dateBegin:date#

              and dt < #dateEnd:date#

           错误的写法(使用包含sysdate的表达式):

           select * from tablename where id= #id:varchar#

              and dt >= trunc(sysdate - 1)

              and dt < sysdate + 1

           错误的写法(将to_date函数和数字进行算术运算):

           select * from tablename where id = #id:varchar#

              and dt >= to_date(#dateBegin:varchar#, 'yyyy-mm-dd hh24:mi:ss')

              and dt < to_date(#dateBegin:varchar#, 'yyyy-mm-dd hh24:mi:ss') + 1

           正确的写法:

           select * from tablename where id = #id:varchar#

              and dt >= to_date(#dateBegin:varchar#, 'yyyy-mm-dd hh24:mi:ss')

              and dt < to_date(#dateEnd:varchar#, 'yyyy-mm-dd hh24:mi:ss') /*或 dt < sysdate */

    3.杜绝循环调用

     

    例如:在迭代的过程中,使用同一SQL反复查询DB,如:

    while
     (listObj.hasnext()) {
    SELECT * FROM process_table WHERE (no = ?)
    ......
    }

       这样不仅效率不高,还造成交互过于频繁,严重情况会导致服务器LOAD增加
       解决方式:
       如果该查询是使用唯一键(如上例),参考后面的STR2VARLIST或STR2NUMLIST的用法

    4.绑定变量和替代变量

    在Ibatis中:
    绑定变量用 #变量名# 表示
    替代变量用 $变量名$ 表示

    注意几点:
    1)通常,应使用绑定变量,尤其是具体取值变化范围较大的变量,如id = #id#。
    2)取值范围很小(比如枚举字段),并且通常取值会比较固定,在DBA预先同意的情况下使用替代变量,或者干脆使用常量。
    3)当一个绑定变量在实际使用中实际取值总是为某一固定常量时,应当直接使用常量而不是变量
    4)在order by子句中,通常使用替代变量而不是绑定变量。
    5)IN子句,使用"iterate + 数组类型变量"的方式实现绑定变量,例如:

    <isNotEmpty prepend="and"
     property="userIds"
    >
    <iterate property="Ids" open="t.creator in (" close=")" conjunction="," >
    #Ids[]#
    </iterate>
    </isNotEmpty>

    将生成 t.creator in (:1, :2, :3, :4, :5 ...) 的语句

    5.在字段上加函数的问题

    1)通常,不允许在字段上添加函数或者表达式,如:

       错误的写法:

    select * from tableName where to_char ( dt, 'yyyy-mm-dd') = '2011-03-04';
    select qty from tableName where id + 12 = 168;

       正确的写法:

    select * from tableName  where dt >= to_date ( '2007-04-04', 'yyyy-mm-dd') and dt < to_date ( '2007-04-05', 'yyyy-mm-dd');
    select qty from tableName where id = 168 - 12;

    2)特别注意,当表连接时,用于连接的两个表的字段如果数据类型不一致,则必须在一边加上类型转换的函数,如

       错误的写法(a.id是number类型,而b.operator_number是char类型):

    select count(*) from tableName1 a, tableName2 b where a.id = b.operator_number and a.username = '小钗';

       正确的写法:

    select count(*) from tableName1 a, tableName2 b where to_char(a.id) = b.operator_number and a.username = '小钗';
    select count(*) from tableName1 a, tableName2 b where a.id = to_number(b.operator_number) and a.username = '小钗';

    6.表连接

       不使用ANSI连接,如inner join、left join、right join、full outer join,而使用(+)来表示外连接

       错误的写法:

    select a.*, b.goods_title from tableName1 a left join tableName2 b on a.NO = b.no
    where a.code = '1234' and a.name = #name:varchar# and a.dt > to_date(...)

       正确的写法:

    select a.*, b.goods_title from tableName a, tableName b
    where a.NO = b.no(+) and a.code = '1234' and a.name = #name:varchar# and a.dt > to_date(...)

    7.SQLMAP的其它编写规范

    1)对表的记录进行更新的时候,必须包含对gmt_modified字段的更新,并且不要使用dynamic标记,如:

       错误的写法:

    update tableName
    <dynamic prepend="set" >
    ......
    <isNotNull prepend="," property="gmtModified" >
    MODIFIED = #modified:TIMESTAMP#
    </isNotNull>
    </dynamic>
    where ID = #id#

       正确的写法(当然,这里更推荐直接更新为sysdate):

    update tableName  set MODIFIED = #modified:TIMESTAMP#
    <dynamic>
    ......
    </dynamic>
    where ID = #id#

    2)不允许在where后添加1=1这样的无用条件,where可以写在prepend属性里,如:

       错误的写法:

    select count(*) from tableName t where 1=1
    <dynamic>
    ......
    </dynamic>

       正确的写法:

    select count(*) from tableName t
    <dynamic prepend="where" >
    ......
    </dynamic>

    3)对大表进行查询时,在SQLMAP中需要加上对空条件的判断语句,如:

       性能上不保险的写法:

    select count(*) from tableName a
    <dynamic prepend="where" >
    <isNotEmpty prepend="AND" property="id" >
    a.id = #id:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="email" >
    a.email = #email:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="type" >
    a.type = #type:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="no" >
    a.no = #no:varchar#
    </isNotEmpty>
    </dynamic>

       性能上较保险的写法(防止那些能保证查询性能的关键条件都为空):

    select count(*) from tableName a
    <dynamic prepend="where" >
    <isNotEmpty prepend="AND" property="id" >
    a.id = #id:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="email" >
    a.email = #email:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="type" >
    a.type = #type:varchar#
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="no" >
    a.no = #no:varchar#
    </isNotEmpty>
    <isEmpty property="id" >
    <isEmpty property="email" >
    <isEmpty property="no" >
    query not allowed
    </isEmpty>
    </isEmpty>
    </isEmpty>
    </dynamic>

    8.聚合函数常见问题

    1)不要使用count(1)代替count(*)
    2)count(column_name)计算该列不为NULL的记录条数
    3)count(distinct column_name)计算该列不为NULL的不重复值数量
    4)count()函数不会返回NULL,但sum()函数可能返回NULL,可以使用nvl(sum(qty),0)来避免返回NULL

    9. NULL的使用

    1)理解NULL的含义,是"不确定",而不是"空"
    2)查询时,使用is null或者is not null
    3)更新时,使用等于号,如:update tablename set column_name = null

    10.STR2NUMLIST、STR2VARLIST函数的使用

    1)适用情况:使用唯一值(或者接近唯一值)批量取数据时 ,能够大大减少和数据库的交互次数

    2)编写规范:a表必须放在from list的第一位,并且必须在select后加上下面的hint
      注意一:参数是由各个交易号拼成的字符串,以逗号间隔,不要有空格
      注意二:函数的参数是一个字符串,长度不能超过4000个字节
      注意三:函数生成的表只有一个字段,名字是column_value
      注意四:生成表的column_value字段是varchar2类型,如果希望是number类型,请使用str2numlist函数,并将vartabletype替换为numtabletype

       错误的写法(缺少hint):

    select a.column_value, b.goods_title
    from TABLE(CAST(str2varlist(:1) as vartabletype)) a, tableName b
    where a.column_value = b.no;

       错误的写法(函数生成的表必须放在from list的第一位):

    select /*+ ordered use_nl(a,b) */ a.column_value, b.goods_title
    from tableName b, TABLE(CAST(str2varlist(:1) as vartabletype)) a
    where a.column_value = b.no;

       正确的写法:

    select /*+ ordered use_nl(a,b) */ a.column_value, b.goods_title
    from TABLE(CAST(str2varlist(:1) as vartabletype)) a, tableName b
    where a.column_value = b.no;

       如果要求返回的结果记录条数和参数中交易号的个数一致,可使用外连接:

    select /*+ ordered use_nl(a,b) */ a.column_value, b.goods_title
    from TABLE(CAST(str2varlist(:1) as vartabletype)) a, tableName b
    where a.column_value = b.no (+);

       如果参数内的值不唯一,可能返回多行,而并不需要返回多行,可考虑使用聚合函数:

    select /*+ ordered use_nl(a,b) */
    a.column_value, min(b.goods_title) goods_title
    from TABLE(CAST(str2varlist(:1) as vartabletype)) a, tableName b
    where a.column_value = b.no (+)
    group by a.column_value;

       使用该函数与使用IN的区别:
        (1)IN返回的结果是无序的,而该函数返回的结果是以参数中各值的顺序为顺序的
        (2)IN返回的结果是不重复的,而该函数返回的结果可重复,取决于输入的参数

    11.分页查询的使用

     

    1 )分页通常是先执行COUNT语句然后执行分页语句,当COUNT返回值为0的时候,应当避免执行后面的分页语句

    2 )有时,只须执行分页语句而无须执行COUNT语句,就不要执行COUNT语句,例如,用户下载excel格式的账户明细

    3 )有时,在分页前除了要统计COUNT还需要统计SUM,这些WHERE子句一致的统计应该在一条SQL中查出,而不是分多次统计

    4)包含排序逻辑的分页查询写法,必须是三层select嵌套:

       错误的写法:

    SELECT t1.*
    FROM (SELECT t.*, ROWNUM rnum
    FROM tableName t
    WHERE no = :1
    AND gmt_create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND gmt_create < TO_DATE (:3, 'yyyy-mm-dd')
    ORDER BY create DESC) t1
    WHERE rnum >= :4 AND rnum < :5

       正确的写法:

    SELECT t2.*
    FROM (SELECT t1.*, ROWNUM rnum
    FROM (SELECT t.*
    FROM tableName t
    WHERE no = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')
    ORDER BY create DESC) t1
    WHERE ROWNUM <= :4) t2
    WHERE rnum >= :5

    5)不包含排序逻辑的分页查询写法,则是两层select嵌套,但对rownum的范围指定仍然必须在不同的查询层次指定:

       错误的写法:

    SELECT t1.*
    FROM (SELECT t.*, ROWNUM rnum
    FROM tableName t
    WHERE no = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')) t1
    WHERE rnum >= :4 AND rnum <= :5

       正确的写法:

    SELECT t1.*
    FROM (SELECT t.*, ROWNUM rnum
    FROM tableName t
    WHERE seller_account = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')
    AND ROWNUM <= :4) t1
    WHERE rnum >= :5

    6)注意下面两种写法的逻辑含义是不同的:

       按交易创建时间排序(倒序),然后再取前10条:

    SELECT t2.*
    FROM (SELECT t1.*, ROWNUM rnum
    FROM (SELECT t.*
    FROM tableName t
    WHERE no = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')
    ORDER BY create DESC) t1
    WHERE ROWNUM <= 10) t2
    WHERE rnum >= 1

       随机取10条,然后在这10条中按照交易创建时间排序(倒序):

    SELECT t1.*
    FROM (SELECT t.*, ROWNUM rnum
    FROM tableName t
    WHERE no = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')
    AND ROWNUM <= 10
    ORDER BY create DESC) t1
    WHERE rnum >= 1

    7)先连接后分页与先分页后连接

       性能较差:

    SELECT t2.*
    FROM (SELECT t1.*, ROWNUM rnum
    FROM (SELECT a.*, b.fee
    FROM tableName1 a, tableName2 b
    WHERE a.no = b.no(+)
    AND a.seller = :1
    AND a.create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND a.create < TO_DATE (:3, 'yyyy-mm-dd')
    ORDER BY a.create DESC) t1
    WHERE ROWNUM <= :4) t2
    WHERE rnum >= :5

       性能较好:

    SELECT /*+ ordered use_nl(a,b) */
    a.*, b.fee
    FROM (SELECT t2.*
    FROM (SELECT t1.*, ROWNUM rnum
    FROM (SELECT t.*
    FROM tableName t
    WHERE no = :1
    AND create >= TO_DATE (:2, 'yyyy-mm-dd')
    AND create < TO_DATE (:3, 'yyyy-mm-dd')
    ORDER BY create DESC) t1
    WHERE ROWNUM <= :4) t2
    WHERE rnum >= :5) a,
    tableName1 b
    WHERE a.no = b.no(+)

       后面这种写法的适用情况:

       a、where子句中的查询条件都是针对 tableName 表的(否则得到的结果将不相同)
       b、关联 tableName1 表时,用的是该表的主键或者唯一键字段(否则将改变结果集的条数)

    展开全文
  • SQL 耗时优化

    2018-12-04 16:21:00
    这时,就要去分析我们的 SQL 语句,导致耗时较长的原因,从而优化我们的 SQL 语句。 说明:本文仅为笔者所思、所想、所写,有用之处欢迎借鉴,不对之处欢迎指出。 1. 内连接查询中,子查询(关联相同的两张...

    Ø  简介

    在平常的开发中,我们经常会编写各种各样的 SQL 语句,比如:SQL 查询、存储过程、或者视图查询等。当我们编写的 SQL 语句比较复杂,或者表的数据量比较大,导致查询超时!这时,就要去分析我们的 SQL 语句,导致耗时较长的原因,从而优化我们的 SQL 语句。

    说明:本文仅为笔者所思、所想、所写,有用之处欢迎借鉴,不对之处欢迎指出。

     

    1.   内连接查询中,子查询(关联相同的两张表)使用 TOP 子句解决耗时

    1)   LINQ 语句

    var datas = (from t1 in DataContext.Orders

                    join t3 in DataContext.UserInfoes on t1.UserId equals t3.id

                    join t5 in DataContext.Customers on t3.CustomerId equals t5.Id

                    join t7 in (from t1 in DataContext.CateringCategorys

                                join t3 in DataContext.CateringCategorys on t1.CategoryId equals t3.ParentId

                                where t1.Level == 1

                                select new

                                {

                                    CategoryId1 = t1.CategoryId,

                                    CategoryId2 = t3.CategoryId

                                }) on t5.TradeType equals t7.CategoryId2

                    where 1 == 1

                    && (cityId == 0 || t1.CityId == strCityId)

                    && t1.OrderStatusId >= (int)OrderStates.Undelivered && t1.OrderStatusId < (int)OrderStates.Cancelled

                    && t1.PayStatusId != (int)OrderPayStates.Unpaid

                    && (t1.PayTime >= startDate && t1.PayTime < endDate)

                    select new

                    {

                        CategoryId = t7.CategoryId1,

                        OrderId = t1.Id,

                        t1.RealTotal,

                        t3.CustomerId

                    }).ToArray();

     

    2)   生成 SQLsp_executesql 转换后的同等 SQL 语句)

    SELECT

        [Filter2].[CategoryId1] AS [CategoryId],

        [Filter1].[Id1] AS [Id],

        [Filter1].[RealTotal] AS [RealTotal],

        [Filter1].[CustomerId] AS [CustomerId]

        FROM   (SELECT [Extent1].[Id] AS [Id1], [Extent1].[RealTotal] AS [RealTotal], [Extent1].[PayTime] AS [PayTime], [Extent1].[CityId] AS [CityId1], [Extent2].[CustomerId] AS [CustomerId], [Extent3].[TradeType] AS [TradeType]

            FROM   [dbo].[Orders] AS [Extent1]

            INNER JOIN [dbo].[UserInfo] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[id]

            INNER JOIN [dbo].[Customer] AS [Extent3] ON [Extent2].[CustomerId] = [Extent3].[Id]

            WHERE ([Extent1].[OrderStatusId] >= 2) AND ([Extent1].[OrderStatusId] < 10) AND (cast(1 as bigint) <> [Extent1].[PayStatusId]) ) AS [Filter1]

        INNER JOIN  (SELECT [Extent4].[CategoryId] AS [CategoryId1], [Extent5].[CategoryId] AS [CategoryId2]

            FROM  [dbo].[Crm_CateringCategory] AS [Extent4]

            INNER JOIN [dbo].[Crm_CateringCategory] AS [Extent5] ON [Extent4].[CategoryId] = [Extent5].[ParentId]

            WHERE 1 = [Extent4].[Level] ) AS [Filter2] ON [Filter1].[TradeType] = [Filter2].[CategoryId2]

    WHERE ((0 = 0) OR ([Filter1].[CityId1] = '0') OR (([Filter1].[CityId1] IS NULL) AND ('0' IS NULL))) AND ([Filter1].[PayTime] >= '2018-12-01 00:00:00') AND ([Filter1].[PayTime] < '2019-01-01 00:00:00')

     

    3)   执行结果

    执行以上语句,耗时为:00:01:43.853

     

    4)   SQL 分析

    1.   首先,我们创建了一个子查询([Filter1]),关联了三张表:OrdersUserInofo Customer,这没什么好说的,是一个正常查询。

    2.   另外,又关联了一个子查询([Filter2]),Crm_CateringCategory Crm_CateringCategory 关联(使用 CategoryId ParentId 关联),就是因为这个子查询,导致了较长的耗时!这是为什么呢,这里先打个问号?

    3.   然后,笔者开始各种猜测

    1)   这个子查询数量量大?NO,只有23记录。

    2)   在关联的第二个 Crm_CateringCategory 表上再派生一层,再关联外层 Crm_CateringCategory 表,并只输出所需字段?结果还是不行!

    3)   因为关联的是相同的表?对的,就是这个原因!因为,尝试创建与 CateringCategory 相同的另一张表 CateringCategory_1 去关联查询,耗时问题就解决了。

    4)   为什么呢,表上加 (NOLOCK) 关键字也不管用,原因不祥(如有博友们知道,欢迎指出)!

    4.   然后,笔者又尝试在这个子查询上加上 TOP 子句,结果执行耗时变为了 00:00:00.740,耗时问题同样解决了。因为开发中,不可能再去创建一张相同的一张表。(Linq 只需加上 Take() 方法即可)。

    转载于:https://www.cnblogs.com/abeam/p/10064847.html

    展开全文
  • 实验2答案-sql1.sql

    2019-09-21 16:00:44
    编写SQL语句,使查询结果显示为如下形式: 教师号 教师名 教授 副教授 T1 A 教授 T2 B 副教授 T3 C 教授 2、创建表: 教师表(  tid 普通编码定字符型,长度为10,主码  tname 普通...
  • SQL语法大全

    2014-03-30 11:00:11
    rs.open SQL语句,conn,3,2 3. SQL常用命令使用方法: (1) 数据记录筛选: sql="select * from 数据表 where 字段名=字段值 order by 字段名 [desc]" sql="select * from 数据表 where 字段名 like \'%字段值%\'...
  •  SQL过于复杂,过长的SQL语句满足程序需求但是影响性能。子查询嵌套过多对性能有影响,查询关联的表特别多也影响性能  频繁访问数据等等 SQL如何被SQLServer执行的 SQL执行原理  解释:首先解释SQL语句...
  • 一、Qt Creator 安装和hello world 程序的编写(原创) 1.首先到Qt 官方网站上下载Qt Creator,这里我们下载windows 版。 下载地址:http://qt.nokia.com/downloads 如下图我们下载:Download Qt SDK for ...
  • 最近在将excel中文件导入到数据库中,用程序进行编写,由于数据量大所以速度很慢,后来采用了SqlBulkCopy类,解决了速度问题,我就insert语句,sqldataadapter.update(dataset,tablename);sqlbulkcopy....
  • SQL sever 实训

    2018-06-28 21:10:03
    --使用ALTER TABLE 语句为已经创建表添加主键约束、外键约束 --主键 ALTER TABLE Customer ADD CONSTRAINT PK_Customer PRIMARY KEY(CusNo) GO ALTER TABLE Product ADD CONSTRAINT PK_Product PRIMARY KEY...
  • 6.2.1 查看最近生成的SQL语句 149 6.2.2 查看相关执行计划 149 6.2.3 收集执行计划统计信息 151 6.2.4 标识SQL语句以便以后取回计划 153 6.2.5 深入理解DBMS_XPLAN的细节 156 6.2.6 使用计划信息来解决问题 ...
  • 6.2.1 查看最近生成的SQL语句 149 6.2.2 查看相关执行计划 149 6.2.3 收集执行计划统计信息 151 6.2.4 标识SQL语句以便以后取回计划 153 6.2.5 深入理解DBMS_XPLAN的细节 156 6.2.6 使用计划信息来解决问题 ...
  •  为了简化SQL的讲解,我必须(尽可能)只写各种主要的DBMS通用的SQL语句。这要求我不得不舍弃一些更好的、针对具体DBMS的解决方案。  虽然基本的SQL在不同的DBMS间具有好的可移植性,但是高级的SQL显然不是这样...
  • Mybatis和Hibernate比较

    2017-06-03 01:02:52
    两者都是比较流行ORM框架,前者着力点在POJO与SQL之间映射...Mybatis:需要手动编写SQL语句以及ResultMap。 开发难度对比: Hibernate:开发难度比Mybatis难度大,主要是因为他比较复杂,庞大,学习时间较长
  • 自我评价 热爱读书、热爱编程,喜欢java语言,曾在学校期间独立编写可联网小游戏。...1、精通sql语句、可编写复杂sql。 2、熟练操作Oracle、SQLServer、MySQL数据库。 3、熟悉Spirng框架,已读书籍:《J2e...
  • 大部分情况下,尤其是记录数量情况下Mysql总是能正常运转很好,但不可避免,随着数据库记录数增长以及SQL语句越来越复杂,总会有一些实际效果与数据库或SQL设计人员理解相违背情况,这就需要开发者对...
  • 这会引起多条sql语句执行性能问题。万一执行中断,因没有事物操作,那么数据回滚就不可能发生</li><li>统计定时发送问题,你们当前实现是:正常情况下,每到来一条数据,...
  • 3.使用annotation配置

    2017-09-16 16:52:32
    这种方式不适合sql语句较复杂场景,语句过也不便于代码维护和查看,如果要用到高级映射和动态sql也不好编写创建maven工程,目录结构如下 maven配置...
  • INSERT DELAYED ...用于INSERT语句的DELAYED选项是MySQL...您也可以定期运行SELECT和UPDATE语句,这些语句花费时间较长。当一个客户端使用INSERT DELAYED时,会立刻从服务器处得到一个确定。并且行被排入队列,当...
  • 超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关...EntityBean:Entity Beans能存活相对较长的时间,并且状态是持续的。只要数据库中的数据存在,Entity beans就一直存活。而不是...
  • 9.3.2 JDBC:面向Java程序设计的SQL函数调用 211 9.4 数据库存储过程与SQL/PSM 214 9.4.1 数据库存储过程和函数 214 9.4.2 SQL/PSM: 扩展SQL以指定持久存储模块 215 9.5 小结 216 复习题 216 ...
  • 4.9 主要的SQL*Plus数据库管理命令 104 4.9.1 RECOVER命令 104 4.9.2 STARTUP和SHOUTDOWN命令 104 4.9.3 ARCHIVE LOG命令 104 4.10 用SQL生成SQL 104 4.11 Oracle SQL Developer 105 4.12 OEM 106 ...
  • 目前支持JSP应用服务器是,Tomcat是其中较为流行一个Web服务器,被JavaWorld杂志编辑选为2001年度最具创新Java产品,可见其在业界地位。 Tomcat是一个免费开源Serlvet容器,在Tomcat中,应用...
  • §12.3.6 一般的SQL语句优化 143 §12.4 SQL语句优化技巧 144 §12.4.1 对所有SQL语句执行EXPLAIN_PLAN 145 §12.4.2 磁盘读和缓冲区获取 146 §12.4.3 判定式崩溃 146 §12.5 使用EXISTS和IN 148 §12.6 分离事务...
  • 3.4.3 增强对SQL*PlusBLOB数据类型支持 119 3.5 联机应用维护 119 3.5.1 支持新对象 120 3.5.2 增强联机索引创建和重建 120 3.5.3 增强默认列值功能 120 3.5.4 联机重组实体化视图 121 3.5.5 使...
  • 3、使用备份进行恢复,此方法一般花费时间较长。 快速shutdown数据库 1. 停止监听 2. 做一个检查点操作 SQL> alter system checkpoint; 3. 杀掉所有LOCAL=NO操作系统进程 AIX、HP-UX、Linux、...
  •  数据查询语言 (Data Query Language, DQL) 是SQL语言中,负责进行数据查询而不会对数据本身进行修改的语句,这是最基本的SQL语句。例如:SELECT(查询)  数据控制语言Data Controlling Language(DCL),用来...
  • 14.4.1 SQL语句的执行过程 466 14.4.2 SQL性能调整基本方法 467 14.4.3 PL/SQL和SQL 471 14.5 小结 473 前言  从2008年2月开始动笔到定稿出版,这本书的编写几乎花费了我10个月时间,大大超出了最初3...
  • TRUNCATE 语句时间过长的诊断 13 隐式转换影响物化视图查询重写 18 批量修改数据后应收集统计信息 21 如何监测一个PL/SQL 过程的运行情况 25 一次RAC 环境性能诊断过程 30 数据泵功能灵活运用案例 35 杨廷琨...
  • 采用MybatisJavaConfig方式编写Sql语句。由于并没有使用Mybatis逆向功能,需要自己手写所有sql语句 关于事务实现,在启动类中开启事务,并在service层需要实现事务业务接口上使用@Transactional注解,还是...

空空如也

空空如也

1 2 3
收藏数 53
精华内容 21
关键字:

编写较长的sql语句