SQL基础语句笔记

改WHERE为JOIN

Alter 修改视图

声明和使用滚动游标:

SELECT 用法

ORDER BY 用法

Group by 的用法

DISTINCT 用法

CASE的用法

构建函数实例1

[AS的用法](https://www.notion.so/AS-c98591d0c4184cb6a418bac4b23521ad?pvs=21)

PROCEDURE(存储过程)

TRIGGER(触发器)

CAST(取整

RAND(取随机伪随机

CONSTRAINT(约束)

管理角色以及用户

INSERT INTO

上面蓝色字是下面正文涉及到的内容,不用点击,点击会跳转到Notion空白页

  1. 查看视图定义:
EXEC sp_helptext 'view3';

这个命令用于显示存储过程、触发器或视图的源代码。在这里,它用于显示视图 view3 的定义。

EXEC sp_helptext 'view3'; 显示视图

  1. 修改视图:

    ALTER VIEW view3
    WITH ENCRYPTION
    AS
    SELECT depart.depname, AVG(salary.income) AS '平均工资'
    FROM worker, depart, salary
    GROUP BY depart.depname;
    
    

    这个命令用于修改已存在的视图 view3WITH ENCRYPTION 选项表示将视图定义加密,这样就不能通过 sp_helptext 查看其定义。AS 后面跟着的是一个 SELECT 语句,它定义了视图的内容。这个 SELECT 语句从 workerdepartsalary 表中选择部门名称和平均工资,并且使用 GROUP BY 对部门名称进行分组。

Alter 修改视图

With Encryption 将视图定义加密

AS的作用 第一个AS 表明加密的内容是随后的SELECT语句

             第二个AS 将AVG(salary.income)定义别名为’平均工资’

From 指定 depart.depname salary income 的来源

JOIN

SELECT depart.depname, AVG(salary.income) AS '平均工资'
FROM worker
JOIN depart ON worker.depid = depart.depid
JOIN salary ON worker.empid = salary.empid
GROUP BY depart.depname;
  • JOIN depart ON worker.depid = depart.depid 定义了 worker 表和 depart 表之间的连接条件,即 worker 表中的 depid 列与 depart 表中的 depid 列相匹配。
  • JOIN salary ON worker.empid = salary.empid 定义了 worker 表和 salary 表之间的连接条件,即 worker 表中的 empid 列与 salary 表中的 empid 列相匹配。
  1. 声明和使用滚动游标:

    DECLARE worker_cur SCROLL CURSOR
    FOR SELECT * FROM worker, depart WHERE worker.depid = depart.depid AND depname = 'HR Dept';
    OPEN worker_cur;
    SELECT 当前游标记录数目 = @@cursor_rows;
    
    

    这里声明了一个名为 worker_cur 的滚动游标,它用于从 workerdepart 表中选择所有记录,其中 worker.depid 必须与 depart.depid 相等,并且 depart.depname 必须是 'HR Dept'。然后打开这个游标,并查询当前游标记录的数量。

    3.在 SQL 语句中,@@cursor_rows 是一个返回当前游标中行数的系统函数

改WHERE为JOIN

DECLARE worker_cur SCROLL CURSOR
FOR SELECT *
FROM worker
JOIN depart ON worker.depid = depart.depid
WHERE depart.depname = 'HR';
  1. 声明游标 (DECLARE worker_cur SCROLL CURSOR):

    • DECLARE 是 SQL 中用来声明游标的关键字。
    • worker_cur 是游标的名称,你可以根据需要选择任何有效的标识符。
    • SCROLL CURSOR 指定了游标的类型。滚动游标允许你以各种方式浏览结果集,包括向前、向后、到第一行、到最后一行等。
  2. 定义游标选择范围 (FOR SELECT * FROM worker, depart WHERE worker.depid = depart.depid AND depart.depname = 'HR'):

    • FOR 关键字后面跟着的是一个 SELECT 语句,它定义了游标 worker_cur 将包含的数据。
    • SELECT * 表示选择所有列。
    • FROM worker, depart 指定了要从 worker 和 depart 这两个表中选择数据。
    • WHERE worker.depid = depart.depid 是一个连接条件,它指定了 worker 表和 depart 表之间的匹配规则,即只有在 worker 表中的 depid 列的值与 depart 表中的 depid 列的值相同时,相应的行才会被选中。
    • AND depart.depname = 'HR' 是一个额外的过滤条件,它进一步筛选出 depart 表中 depname 列值为 'HR' 的记录。
  3. 游标操作:

    FETCH FIRST FROM worker_cur;
    FETCH NEXT FROM worker_cur;
    SELECT 当前游标记录数目 = @@fetch_status;
    FETCH RELATIVE 2 FROM worker_cur;
    FETCH ABSOLUTE 3 FROM worker_cur;
    
    

这些命令用于操作游标 worker_curFETCH FIRSTFETCH NEXT 分别获取第一条和下一条记录。@@fetch_status 是一个系统变量,用于显示最近一次游标操作的状态。FETCH RELATIVEFETCH ABSOLUTE 用于移动游标到相对位置或绝对位置的记录。

  1. 关闭游标:

    CLOSE worker_cur;
    
    

这个命令用于关闭游标 worker_cur

  1. 声明和使用动态游标:

    DECLARE worker_curupdate CURSOR DYNAMIC
    FOR SELECT * FROM worker
    FOR UPDATE;
    OPEN worker_curupdate;
    FETCH RELATIVE 3 FROM worker_curupdate;
    UPDATE worker
    SET depid = '005'
    WHERE CURRENT OF worker_curupdate;
    CLOSE worker_curupdate;
    
    

    这里声明了一个名为 worker_curupdate 的动态游标,它用于从 worker 表中选择所有记录,并允许对这些记录进行更新操作。然后打开这个游标,获取相对于当前位置的第三条记录。接着,使用 UPDATE 语句更新当前游标指向的 worker 表中的 depid 字段为 '005'。最后关闭游标。

DECLARE worker_curupdate CURSOR 
FOR SELECT *
FROM worker;

OPEN worker_curupdate;

WHILE (FETCH NEXT FROM worker_curupdate)
BEGIN
   UPDATE worker
   SET depid = '005'
   WHERE CURRENT OF worker_curupdate;
END;

CLOSE worker_curupdate;
DEALLOCATE worker_curupdate;

使用动态游标更改表内数据的例子游标

worker_curupdate 被用来遍历 worker 表中的所有行。在循环中,每次 FETCH NEXT 成功获取一行后,就会执行 UPDATE 语句来更新当前行的 depid 列。

SELECT 用法

  1. 筛选比王华年龄大
SELECT * FROM 学生信息表 WHERE 年龄 > (SELECT 年龄 FROM 学生信息表 WHERE 学生姓名 = '王华');
  1. 检索C2课程中成绩最高的学生的学号
SELECT 学号 FROM 学生成绩表 WHERE 课程名称 = 'C2' ORDER BY 成绩 DESC LIMIT 1;

ORDER BY 用法

  1. 按单一列升序排序

    SELECT * FROM table_name ORDER BY column1 **ASC**;
    
    
  2. 按单一列降序排序

    SELECT * FROM table_name ORDER BY column1 **DESC**;
    
    
  3. 按多个列排序: 可以按照多个列进行排序,第一列排序后,第二列将用于对具有相同值的行进行排序。

    SELECT * FROM table_name ORDER BY column1 ASC, column2 DESC;
    
    
  4. 选择特定列并排序: 只选择特定的列,并按照另一列进行排序。

    SELECT column1, column2 FROM table_name ORDER BY column3 DESC;
    
    
  5. 排序并限制结果数量: 结合 LIMIT 子句使用,可以返回排序后的前几行。

    SELECT * FROM table_name ORDER BY column1 DESC LIMIT 10;
    
    
INSERT INTO SCC(CNO, CNAME, AVE_GRADE)
SELECT C.C#, C.CNAME, AVG(SC.GRADE)
FROM SC
INNER JOIN C ON SC.C# = C.C#
GROUP BY C.C#, C.CNAME;

Group by 的用法

1. 多列分组

您可以在 GROUP BY 子句中使用多个列来对数据进行更细致的分组。

SELECT Department, YEAR(HireDate) AS HireYear, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department, HireYear;

在这个例子中,查询将根据 DepartmentHireYear 进行分组,计算每个部门、每个年份的平均薪资。

2. 空值分组

GROUP BY 中,如果存在 NULL 值,它们通常会被聚合成一个单独的组。如果您想要区分 NULL 值,可能需要使用条件表达式或特定的数据库功能。

3. 与 HAVING 子句结合使用

GROUP BYHAVING 子句结合使用可以对分组后的结果进行条件过滤。

SELECT Department, COUNT(*) AS EmployeeCount
FROM Employees
GROUP BY Department
HAVING COUNT(*) > 10;

这个查询将返回员工数量超过 10 人的部门。

4. 选择性聚合

有时候,您可能希望在不同的分组中聚合不同的列。

SELECT Department, MAX(Salary) AS MaxSalary, MIN(Salary) AS MinSalary
FROM Employees
GROUP BY Department;

在这个查询中,每个部门的最大薪资和最小薪资被计算出来。

5. 使用 GROUP BY 与非聚合列

在某些数据库系统中,您可以直接在 SELECT 列表中包含未在 GROUP BY 中出现的非聚合列,但这可能会导致不确定的结果或错误。最佳实践是只 GROUP BY 那些您确实需要聚合的列。

6. 避免不必要的列

SELECT 语句中,应该只包含需要的列,避免包含不必要的列,尤其是那些没有在 GROUP BY 中指定的非聚合列。

7. 性能考虑

在大型数据集上使用 GROUP BY 可能会影响查询性能。确保对参与分组的列进行了适当的索引。

8. 与 DISTINCT 的区别

GROUP BYDISTINCT 子句不同。DISTINCT 用于返回唯一不同的值,而 GROUP BY 用于聚合操作

DISTINCT 用法

DISTINCT 是 SQL 中的一个关键字,用于返回唯一不同的值,从而去除重复的行。DISTINCT 通常与 SELECT 语句一起使用,可以应用于一个或多个列。以下是 DISTINCT 的几种常见用法:

基本用法

SELECT DISTINCT column_name
FROM table_name;

这个查询将从 table_name 表中选择 column_name 列的唯一不同的值。

示例

假设有一个名为 Orders 的表,包含 OrderIDCustomerNameOrderDate 列。如果我们想获取唯一的客户名称,可以这样写:

SELECT DISTINCT CustomerName
FROM Orders;

多列 DISTINCT

DISTINCT 也可以与多个列一起使用,这样它会基于这些列的组合来去除重复行。

SELECT DISTINCT column_name1, column_name2
FROM table_name;

这个查询将返回 column_name1column_name2 的所有唯一不同的组合。

DISTINCT 与聚合函数

DISTINCT 可以与聚合函数一起使用,以返回某个列的唯一不同的值的聚合结果。

SELECT DISTINCT COUNT(column_name)
FROM table_name;

不过,这种用法可能有些不寻常,因为 COUNT() 通常用于计算行数,而 DISTINCT 用于返回不同的值。更常见的模式是将 DISTINCT 与聚合函数一起使用,例如:

SELECT column_name1, COUNT(DISTINCT column_name2)
FROM table_name
GROUP BY column_name1;

这个查询将为 column_name1 的每个唯一不同的值计算 column_name2 的唯一不同值的数量。

DISTINCT 与 WHERE

DISTINCT 可以与 WHERE 子句结合使用,以便在满足特定条件的情况下返回唯一不同的值。

SELECT DISTINCT column_name
FROM table_name
WHERE condition;

DISTINCT 的性能

使用 DISTINCT 可能会影响查询性能,尤其是在大型数据集上,因为它需要对结果集进行排序以消除重复。在某些情况下,使用索引或临时表可能会提高性能。

DISTINCT ON

在某些数据库系统(如 PostgreSQL)中,有一个 DISTINCT ON 语法,它允许你基于一个或多个列对结果进行排序并返回每组的第一个唯一不同的行。

SELECT DISTINCT ON (column_name) *
FROM table_name
ORDER BY column_name, another_column;

这将为 column_name 的每个唯一不同的值返回第一行,然后根据 another_column 对结果进行排序。

请记住,DISTINCT 的使用应根据你的具体需求来决定,它在简化结果集和提高数据质量方面非常有用。

CASE的用法

CASE 语句的基本语法如下:

在SQL中,CASE 语句是一种条件表达式,它允许你根据不同的条件返回不同的结果。CASE 语句通常用于在查询中根据一个或多个条件来返回不同的值。

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE default_result
END

  • condition1, condition2, ... 是需要评估的条件。
  • result1, result2, ... 是当相应条件为真时返回的结果。
  • default_result 是当所有条件都不满足时返回的默认结果。

这里有一个简单的例子,说明如何使用 CASE 语句来根据职工的职位级别返回不同的工资:

SELECT
    职工号,
    姓名,
    职位级别,
    CASE
        WHEN 职位级别 = '高级' THEN '高薪'
        WHEN 职位级别 = '中级' THEN '中薪'
        WHEN 职位级别 = '初级' THEN '低薪'
        ELSE '未定义'
    END AS 工资等级
FROM 职工表;

在这个例子中,CASE 语句检查 职位级别 列的值,并根据该值返回相应的工资等级。

AVG(平均)

在SQL中,计算平均值通常使用 AVG() 函数。AVG() 是一个聚合函数,用于计算某个列中所有行的平均值。以下是如何使用 AVG() 函数的基本示例:

SELECT AVG(列名) FROM 表名;

  • 列名 是你想要计算平均值的列。
  • 表名 是包含该列的表。

例如,如果你有一个名为 Employees 的表,其中包含一个名为 Salary 的列用于存储工资信息,你可以使用以下SQL语句来计算所有员工的平均工资:

SELECT AVG(Salary) AS AverageSalary FROM Employees;

在这个例子中,AS AverageSalary 是一个别名,用于给结果列命名,使其更易于理解。

如果你需要根据不同的条件(如性别)来计算平均值,你可以使用 GROUP BY 子句来对结果进行分组,如下所示:

SELECT Gender, AVG(Salary) AS AverageSalary FROM Employees GROUP BY Gender;

这个查询会返回每个性别的平均工资。

在之前的问题中,我们使用了 AVG() 函数来计算男性和女性职工的平均工资,并根据这些平均值来确定显示的信息。如果你需要实现这个逻辑,可以参考以下SQL查询:

WITH GenderAverages AS (
    SELECT Gender, AVG(Salary) AS AverageSalary
    FROM Employees
    GROUP BY Gender
)
SELECT
    CASE
        WHEN MAX(CASE WHEN Gender = 'Male' THEN AverageSalary END) > 1.5 * MIN(CASE WHEN Gender = 'Female' THEN AverageSalary END) THEN '男职工比女职工的工资高多了'
        WHEN MAX(CASE WHEN Gender = 'Male' THEN AverageSalary END) BETWEEN 1.5 AND 0.8 THEN '男职工跟女职工的工资差不多'
        ELSE '女职工比男职工的工资高多了'
    END AS SalaryComparison
FROM GenderAverages;

请注意,这个查询中的 BETWEEN 1.5 AND 0.8 可能需要根据你的具体需求进行调整,因为 BETWEEN 通常用于数值范围,而不是比率。你可能需要将比率转换为实际的数值,或者使用不同的逻辑来比较这些比率。

构建函数实例1

CREATE FUNCTION dbo.CheckDepartmentExists (@DepID INT)
RETURNS INT
AS
BEGIN
    DECLARE @Result INT; -- 声明一个变量来存储结果

    -- 检查部门是否存在
    IF EXISTS (SELECT 1 FROM dbo.depart WHERE DepID = @DepID)
    BEGIN
        SET @Result = 0; -- 如果存在,设置结果为0
    END
    ELSE
    BEGIN
        SET @Result = -1; -- 如果不存在,设置结果为-1
    END

    -- 返回结果
    RETURN @Result;
END
-- 假设 worker 表有以下列:workerid, name, position, department_id 等
-- 假设 要插入的记录如下:
DECLARE @NewWorkerID INT = 1001; -- 假设的新员工ID
DECLARE @NewWorkerName NVARCHAR(100) = 'John Doe'; -- 假设的新员工姓名
DECLARE @NewDepartmentID INT; -- 假设的新员工部门ID

-- 设置新员工的部门ID,这里只是一个示例值
SET @NewDepartmentID = 5;

-- 调用函数检查部门ID是否存在
DECLARE @DepartmentExists INT;
SET @DepartmentExists = dbo.CheckDepartmentExists(@NewDepartmentID);

-- 根据函数返回值决定是否插入记录
IF @DepartmentExists = 0
BEGIN
    -- 部门存在,可以插入新员工记录
    INSERT INTO dbo.worker (workerid, name, depid)
    VALUES (@NewWorkerID, @NewWorkerName, @NewDepartmentID);
    PRINT '记录已成功插入到worker表';
END
ELSE
BEGIN
    -- 部门不存在,不插入记录
    PRINT '部门不存在,无法插入记录';
END

AS的用法

  1. 重命名:在SQL语句中,AS用于给表、列或查询结果重命名。这在编写更易读的查询时非常有用。

    示例

    SELECT employee_id AS ID, first_name AS Name FROM employees;
    
    

    在这个例子中,AS用于将employee_id列重命名为ID,将first_name列重命名为Name

    1. 定义别名:在连接(JOIN)操作或子查询中,AS用于为表或查询结果定义别名。

      示例

      SELECT a.name, b.salary
      FROM employees AS a
      JOIN salaries AS b ON a.id = b.employee_id;
      
      

      这里AS用于为employees表定义别名a,为salaries表定义别名b

    2. 创建视图:在创建视图(VIEW)时,AS用于指定视图的SQL查询。

      示例

      CREATE VIEW employee_view AS
      SELECT * FROM employees WHERE department_id = 10;
      
      

      在这个例子中,AS后面跟着的是一个查询,定义了employee_view视图的内容。

    3. 定义存储过程:在创建存储过程(PROCEDURE)时,AS用于开始存储过程的主体。

      示例

      CREATE PROCEDURE MyProcedure AS
      BEGIN
      -- SQL statements
      END;
      
      

      这里AS用于开始存储过程MyProcedure的主体部分,之后跟着的是存储过程的SQL语句。

    4. 定义函数:在创建函数(FUNCTION)时,AS用于指定函数的SQL语句。

      示例

      CREATE FUNCTION MyFunction AS
      BEGIN
          RETURN (SELECT COUNT(*) FROM employees);
      END;
      
      

      在这个例子中,AS后面跟着的是一个查询,定义了MyFunction函数的返回值。

PROCEDURE(存储过程)

优点(作用):避免重复编译,可以实现代码复用,可接收参数,将复杂操作封装为单一事务

创建存储过程

存储过程的创建通常使用CREATE PROCEDURE语句,其基本语法如下:

CREATE PROCEDURE ProcedureName
    [@Parameter1 DataType,
     @Parameter2 DataType, ...]
AS
BEGIN
-- SQL statements-- 可以包括SELECT, INSERT, UPDATE, DELETE等
END;

调用存储过程

创建存储过程后,可以通过EXECEXECUTE关键字来调用它:

EXEC ProcedureName @Parameter1 = Value1, @Parameter2 = Value2, ...;

如果存储过程没有参数,可以省略参数列表:

EXEC ProcedureName;

插入工作表实例

CREATE PROCEDURE AddWorker
    @workerId INT,
    @workerName VARCHAR(255),
    @workersex VARCHAR(255),
    @workerbirthdate TIME,
    @workdate TIME,
    @workerdepid INT
AS
BEGIN
    INSERT INTO worker (workerid, name, sex, birthdate, workdate, depid) 
    VALUES (@workerId, @workerName, @workersex, @workerbirthdate, @workdate, @workerdepid);
END;

EXEC AddWorker
    @workerId = 1,
    @workerName = '张三',
    @workersex = '男',
    @workerbirthdate = '1990-01-01 08:00:00', -- 假设出生日期和时间
    @workdate = '2010-06-01 09:00:00', -- 假设工作开始时间和日期
    @workerdepid = 101; -- 假设部门ID
select * from  worker

删除worker实例

CREATE PROCEDURE DelWorker
    @WorkerIdToDelete INT
AS
BEGIN
    BEGIN TRANSACTION;
    DELETE FROM worker
    WHERE workerid = @WorkerIdToDelete;
    IF @@ROWCOUNT > 0
    BEGIN
        COMMIT TRANSACTION;
    END
    ELSE
    BEGIN
        ROLLBACK TRANSACTION;
    END
END;
EXEC DelWorker
@WorkerIdToDelete = 1

TRIGGER(触发器)

自动触发、事件触发

触发器的类型:

  1. AFTER触发器:在数据库操作之后触发。AFTER触发器不能修改触发它的操作的结果。
  2. INSTEAD OF触发器:在数据库操作之前触发,并且可以拦截原始操作,执行一系列不同的SQL语句。INSTEAD OF触发器主要用于视图,但也可以用于表。
  3. BEFORE触发器:在数据库操作之前触发。BEFORE触发器可以访问旧数据(即操作前的数据),但不能访问新数据。
  4. AFTER INSTEAD OF触发器:这不是一个单独的触发器类型,而是在某些数据库系统中,AFTER触发器可以具有类似INSTEAD OF触发器的行为。

创建触发器:

创建触发器的基本语法如下:

CREATE TRIGGER TriggerName
ON TableName
AFTER|INSTEAD OF TriggerEvent
AS
BEGIN
-- 触发器内部的SQL语句-- 可以是INSERT, UPDATE, DELETE等
END;

Update触发器

CREATE TRIGGER depart_update
ON depart
AFTER UPDATE
AS
BEGIN
    IF UPDATE(depid)
    BEGIN
        BEGIN TRANSACTION;
        UPDATE w
        SET w.depid = i.depid
        FROM worker w
        INNER JOIN inserted i ON w.depid = i.depid
        WHERE w.depid IN (SELECT depid FROM deleted);
        COMMIT TRANSACTION;
    END
END;

AFTER触发器

CREATE TRIGGER DDL_DELTABLE ON DATABASE
AFTER DROP_TABLE
AS
BEGIN
PRINT 'CAN NOT DEL THIS TABLE'
ROLLBACK TRANSACTION
END ;

INSTEAD OF触发器

CREATE TRIGGER CheckDepidOnInsertOrUpdate
ON worker
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    DECLARE @depid INT;
    SELECT @depid = depid FROM (SELECT * FROM inserted) AS i WHERE i.depid = @depid;
    IF EXISTS (SELECT 1 FROM depart WHERE depid = @depid)
    BEGIN
        INSERT INTO worker (workerid, name, depid)
        SELECT workerid, name, depid 
        FROM inserted;
        PRINT '插入成功,部门ID存在。';
    END
    ELSE
    BEGIN
        PRINT '插入或更新已取消,部门ID不存在。';
    END
END;

CAST(取整

CAST是一个SQL函数,用于将一个表达式转换为指定的数据类型。在您的例子中,CAST被用来将RAND()函数生成的浮点数转换为整数。

这里是CAST在您的代码中的具体用法:

复制CAST(RAND() * @LN_N + 1 AS INT)

RAND(取随机伪随机

RAND()函数在SQL中用于生成随机浮点数。每次调用RAND()时,如果没有指定种子值,它都会生成一个介于0(含)和1(不含)之间的随机数。这意味着生成的随机数可以是0.000...1,但永远不会达到1。

以下是RAND()函数的一些常见用法:

  1. 生成随机数: 直接调用RAND()将返回一个0到1之间的随机浮点数。

    SELECT RAND();
    
    
  2. 与数值相乘: RAND()常与数值相乘,以生成一个特定范围的随机数。例如,如果你有一个数值n,并且想要一个介于0到n之间的随机数,你可以这样做:

    SELECT RAND() * n;
    
    

    这将生成一个介于0到n的随机浮点数。

  3. 作为排序的依据: RAND()可以用作ORDER BY子句的一部分,以随机排序结果集。

    SELECT * FROM table_name ORDER BY RAND();
    
    

    这将随机地返回table_name表中的行。

  4. 随机选择记录: 当需要从大量记录中随机选择几条时,RAND()可以与TOP关键字结合使用(在某些数据库系统中,如SQL Server)。

    SELECT TOP 10 * FROM table_name ORDER BY RAND();
    
    

    这将随机选择table_name表中的10条记录。

  5. 随机分页: RAND()还可以用于实现随机分页的效果,尽管这不是一个标准的分页技术。

    SELECT * FROM (
      SELECT ROW_NUMBER() OVER (ORDER BY RAND()) as rn, *
      FROM table_name
    ) AS x WHERE rn BETWEEN 11 AND 20;
    
    

    这个例子中,我们首先为table_name表中的每行分配一个随机数作为行号,然后选择行号在11到20之间的行,这可以看作是一种随机分页的方式。

    CONSTRAINT(约束)

    在SQL中,CONSTRAINT(约束)是用来限制表中数据的规则,确保数据的准确性和可靠性。约束可以应用于数据库表的列或表本身,用来防止插入无效或不一致的数据。CHECK是一种特定类型的约束,用来限制列中的值必须满足特定的条件。

    约束主要有以下几种类型:

    1. PRIMARY KEY(主键): 用于唯一标识数据库表中的每条记录。
    2. FOREIGN KEY(外键): 用于在两个表之间建立链接,并确保引用的数据的完整性。
    3. UNIQUE(唯一性): 保证在某个列或列的组合中的所有值都是不同的。
    4. CHECK(检查): 用于确保列中的值满足特定的条件。
    5. DEFAULT(默认值): 当没有为列提供值时,将使用默认值。

    CHECK 约束

    CHECK 约束用于限制列中的值必须满足特定的条件。这个条件是一个逻辑表达式,结果必须为TRUEUNKNOWN(在SQL Server中,UNKNOWN结果通常视为FALSE);如果结果为FALSE,则违反了约束,操作将被数据库拒绝。

    特点

    • CHECK 约束可以应用于单个列或多个列。
    • 使用CHECK 约束可以限制数值范围、字符串长度、枚举值等。

    示例

    假设我们有一个Employees表,其中有一个Salary列,我们希望确保工资在1000到5000之间:

    CREATE TABLE Employees (
        EmployeeID INT,
        EmployeeName NVARCHAR(255),
        Salary DECIMAL(10, 2),
        CONSTRAINT chk_Salary CHECK (Salary BETWEEN 1000 AND 5000)
    );
    
    

    在这个例子中,chk_Salary 是一个CHECK 约束的名称,它确保Salary列的值在1000到5000之间。如果尝试插入或更新Salary列的值超出这个范围,操作将失败,并且数据库将返回一个错误。

    管理角色以及用户

    创建用户名以及登录密码

    CREATE LOGIN sql_ABC WITH PASSWORD = '123456';
    

    将用户连接到指定数据库

    USE YourDatabase;
    GO
    
    CREATE USER ABC FOR LOGIN sql_ABC;
    

    在数据库中创建ROLE,并将创建的用户加入ROLE2中,方便管理拥有同权限的用户

    CREATE ROLE ROLE2;
    
    ALTER ROLE ROLE2 ADD MEMBER ABC; //高版本用这个
    EXEC sp_addrolemember 'ROLE2', 'ABC'; //低版本用这个
    

    为ROLE加入表

    GRANT SELECT ON OBJECT::dbo.worker TO ROLE2;
    

    对ROLE中用户的权限加以限制(解除限制

    DENY SELECT, INSERT, UPDATE, DELETE ON OBJECT::dbo.Salary TO ABC;
    
    REVOKE DENY OPTION FOR SELECT, INSERT, UPDATE, DELETE ON OBJECT::dbo.Salary FROM ABC;
    
    GRANT SELECT, INSERT, UPDATE, DELETE ON OBJECT::dbo.Salary TO ABC;//仍需添加权限
    
    

    删除用户删除ROLE

    从角色 ROLE2 中删除用户 ABC
    ALTER ROLE ROLE2 DROP MEMBER ABC;//高版本
    EXEC sp_droprolemember 'ROLE2', 'ABC';//低版本
    
    删除数据库用户 ABC
    DROP USER ABC;
    
    删除数据库角色 ROLE2
    DROP ROLE ROLE2;
    

    INSERT INTO

    INSERT INTO 是SQL(Structured Query Language,结构化查询语言)的一个基本操作,用于向数据库表中添加新的行记录。以下是 INSERT INTO 的几种常见用法:

    1. 插入完整的新行

    当你想要插入一整行新数据,并且知道每个列的值时,可以使用以下语法:

    INSERT INTO 表名 (列名1, 列名2, ..., 列名N)
    VALUES (值1, 值2, ..., 值N);
    

    这里的 表名 是你要插入数据的表,列名 是表中列的名称, 是你想要插入的具体数值。

    示例

    INSERT INTO Employees (EmployeeID, FirstName, LastName, Department)
    VALUES (101, 'John', 'Doe', 'Finance');
    
    

    这条语句将向 Employees 表中插入一个新的员工记录。

    2. 插入多行数据

    如果你想要一次性插入多行数据,可以使用以下语法:

    INSERT INTO 表名 (列名1, 列名2, ..., 列名N)
    VALUES
        (值1a, 值2a, ..., 值Na),
        (值1b, 值2b, ..., 值Nb),
        ...;
    
    

    示例

    INSERT INTO Employees (EmployeeID, FirstName, LastName, Department)
    VALUES
        (102, 'Jane', 'Smith', 'IT'),
        (103, 'Bob', 'Johnson', 'HR');
    
    

    这些语句将向 Employees 表中插入两行新的员工记录。

    3. 插入查询结果

    你还可以将查询结果直接插入到另一个表中,使用以下语法:

    INSERT INTO 表名 (列名1, 列名2, ..., 列名N)
    SELECT 列1, 列2, ..., 列N
    FROM 另一个表名
    WHERE 条件;
    
    

    示例

    INSERT INTO OldEmployeeRecords (EmployeeID, FirstName, LastName)
    SELECT EmployeeID, FirstName, LastName
    FROM Employees
    WHERE Department = 'Finance';
    
    

    这条语句将选择 Employees 表中 DepartmentFinance 的所有员工记录,并将它们插入到 OldEmployeeRecords 表中。

    4. 插入默认值

    如果你想要插入一个新行,但不需要为所有列提供值,并且表的其他列具有默认值或允许为空(NULL),可以省略列名和值:

    INSERT INTO 表名
    VALUES (DEFAULT, ...);
    
    

    或者:

    INSERT INTO 表名
    VALUES (NULL, ...);
    
    

    示例

    INSERT INTO Employees (EmployeeID) VALUES (DEFAULT);
    
    

    这条语句将只插入一个新的 EmployeeID,默认值由该列的默认值或自动增长规则决定。

    注意事项

    • 确保插入的数据类型与表定义的列数据类型相匹配。
    • 如果列有 NOT NULL 约束,必须为这些列提供值,除非它们有默认值。
    • 如果表有主键约束,需要确保插入的值是唯一的,除非主键列的值由数据库自动生成。

    INSERT INTO 是数据库操作中非常基本且常用的语句,掌握它的用法对于数据库管理和数据维护至关重要。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值