sql基础2

 ̄綄美尐妖づ 提交于 2019-11-26 21:28:33

1交叉联接

  cross join 笛卡尔积 将一个表的每行与另一个表的所有行进行匹配 m行表与n行表cross join 得到m*n行的结果集

--ANSI SQL-92标准 CROSS JOIN 关键字
SELECT  c.custid ,
        e.empid
FROM    Sales.Customers AS c
        CROSS JOIN hr.Employees AS e
--ANSI SQL-89标准
SELECT  c.custid ,
        e.empid
FROM    Sales.Customers AS c ,
        hr.Employees AS e
--利用自联接生成数字表
DECLARE @table TABLE
    (
      digit INT NOT NULL PRIMARY KEY
    )
INSERT  INTO @table( digit )VALUES  ( 0 ),( 1 ),( 2 ),( 3 ),( 4 ),( 5 ),( 6 ),( 7 ),( 8 ),( 9 )

SELECT  T1.digit + T2.digit * 10 + T3.digit * 100 + 1 AS d        
FROM    @table AS T1
        CROSS JOIN @table AS T2
        CROSS JOIN @table AS T3
ORDER BY d

2内联接

-- join ... on ..  推荐使用 更安全
SELECT  e.empid ,e.firstname ,e.lastname ,o.orderid
FROM    hr.Employees AS e
        JOIN Sales.Orders AS o ON e.empid = o.empid

--where
SELECT  e.empid ,e.firstname ,e.lastname ,o.orderid
FROM    hr.Employees AS e ,
        Sales.Orders AS o
WHERE   e.empid = o.empid

3其他联接

--组合联接
SELECT  *
FROM    tabName1 AS A
        INNER JOIN tabName2 AS B ON A.id1 = B.id
                                    AND A.id = B.id2

--不等联接
SELECT  *
FROM    tabName1 AS A
        INNER JOIN tabName2 AS B ON A.id1 > B.id

--多表联接
SELECT c.custid ,c.companyname ,o.orderid ,od.productid ,od.qty
 FROM   Sales.Customers AS c
        INNER JOIN Sales.Orders AS o ON c.custid = o.custid
        INNER JOIN Sales.OrderDetails AS od ON o.orderid = od.orderid

--外联接

left join, right join, full join 

 4存储过程

  优点 :容易维护,移植,执行速度较快,可设置权限

--常用系统存储过程exec sp_databases; --查看数据库
exec sp_tables;        --查看表
exec sp_columns student;--查看列
exec sp_helpIndex student;--查看索引
exec sp_helpConstraint student;--约束
exec sp_stored_procedures;
exec sp_helptext 'sp_stored_procedures';--查看存储过程创建、定义语句
exec sp_rename student, stuInfo;--修改表、索引、列的名称
exec sp_renamedb myTempDB, myDB;--更改数据库名称
exec sp_defaultdb 'master', 'myDB';--更改登录名的默认数据库
exec sp_helpdb;--数据库帮助,查询数据库信息
exec sp_helpdb master;--实例--表重命名exec sp_rename 'stu', 'stud';select * from stud;--列重命名exec sp_rename 'stud.name', 'sName', 'column';exec sp_help 'stud';--重命名索引exec sp_rename N'student.idx_cid', N'idx_cidd', N'index';exec sp_help 'student';--查询所有存储过程select * from sys.objects where type = 'P';select * from sys.objects where type_desc like '%pro%' and name like 'sp%';

  1获取某个员工的所有下级

--with as 相当于子查询Create PROCEDURE [dbo].[getnode]
@emp_id int
AS
BEGIN

 WITH aCTE AS
(
SELECT *
FROM Employees
WHERE emp_id=@emp_id and emp_isworking = 730
UNION ALL
SELECT b.*
FROM aCTE a
JOIN Employees b
ON a.emp_id=b.emp_pid and b.emp_isworking = 730
)

SELECT * FROM aCTE where emp_id <>@emp_id order by emp_id
END--exec getnode 46

  2、变量

    局部变量@开头,全局变量@@开头

--简单声明declare @emp_id int--声明时直接赋值declare @emp_id int = 3set与select --当表达式返回多个值时,使用set赋值报错,使用select赋值返回结果集最后一列值1、declare @name nvarchar(200)set @name = (select emp_zhname from Employees)print @name/*报错*/2、declare @name nvarchar(200)select @name = (select emp_zhname from Employees)print @name /*返回结果集中嘴个一个emp_zhname的值*/--当表达式未返回值时,使用set赋值null,使用select返回原来的值declare @name varchar(20)set @name='jack'set @name= (select username from userinfo where username='not')print @name  --Null值/**/declare @name varchar(20)set @name='jack'select @name=username from userinfo where username='not'print @name  --jack,保存原来的值/*jack*/
  SELECT SET
同时对多个变量同时赋值 支持 不支持
表达式返回多个值时 将返回的最后一个值赋给变量 出错
表达式未返回值 变量保持原值 变量被赋null值
 

   3、流程控制 if...else...,case,while(没有for循环)

--if else简单使用declare @id int           --声明个变量
set @id=5                 --设置厨初始值
if(@id=1)
    begin
        print 'right'
    end
else if(@id=0)
    begin
        print 'error'
    end
else
    begin 
         print 'default'
    end
--while简单使用Declare @i int,@sum int
set @i=0
set @sum=0
while @i<=100   --开始循环
begin
set @sum=@sum+@i

set @i=@i+1  --自增一
 end print @sum
结果
-----------
--case简单使用Declare @iret int,@var varchar(10)
set @var='A'
select @iret=
case when @var='A' then 0
 when @var='B' then 1
 when @var='C' then 2
 when @var='D' then 3
 else -1
 end
 print @iret

结果
-------

  4、事务

    开始事务:BEGIN TRANSACTION
    提交事务:COMMIT TRANSACTION
    回滚事务:ROLLBACK TRANSACTION

    1、使用存储过程执行事物,需要开启XACT_ABORT参数(默认值为Off),将该参数设置为On,表示当执行事务时,如果出错,会将transcation设置      为uncommittable状态,那么在语句块批处理结束后将回滚所有操作;如果该参数设置为Off,表示当执行事务时,如果出错,出错的语句将不会执行,其他正确的操作继续执行。(Set XACT_ABORT on)

    2、Set NOCOUNT ON 不返回计数

USE [StoreTest]
GO

create Procedure  [dbo].[P_InsertUser]
@UserName varchar(100),
@UserPwd varchar(100)
AS
Begin
Set NOCOUNT ON; 
Set XACT_ABORT ON; --这句话非常重要

Begin try
    if(isnull(@UserName,'')='')
   begin
        print 'UserName is empty';
     return ;
    end

    declare @iCount int;
    set @iCount = 0;
    select @iCount = Count(1) from userinfo with(nolock) where username=@UserName;
    if( @iCount > 0 )
    begin
        print 'the current name already exist';
        return
    end
    Begin  Tran   --开始事务,事务中不能有return语句
    --insert
    insert into userinfo(
        username
        ,userpwd
        ,RegisterTime 
        )
        values(
        @UserName,
        @UserPwd,
        getdate()
        )

    Commit Tran       --提交事务
end try
begin catch
--在此可以使用xact_state()来判断是否有不可提交的事务,不可提交的事务
--表示在事务内部发生错误了。Xact_state()有三种值:-1.事务不可提交;
--1.事务可提交;0.表示没有事务,此时commit或者rollback会报错。
if xact_state()=-1
begin
    rollback tran;   --事务回滚
    SELECT ERROR_NUMBER() AS ErrorNumber,
    ERROR_MESSAGE() AS ErrorMessage;
end
end catch   
Set XACT_ABORT off; 
End

--调用存储过程
exec [P_InsertUser] '','admin'   --插入失败的
GO

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!