[AS的用法](https://www.notion.so/AS-c98591d0c4184cb6a418bac4b23521ad?pvs=21)
上面蓝色字是下面正文涉及到的内容,不用点击,点击会跳转到Notion空白页
- 查看视图定义:
EXEC sp_helptext 'view3';
这个命令用于显示存储过程、触发器或视图的源代码。在这里,它用于显示视图 view3
的定义。
EXEC sp_helptext 'view3'; 显示视图
-
修改视图:
ALTER VIEW view3 WITH ENCRYPTION AS SELECT depart.depname, AVG(salary.income) AS '平均工资' FROM worker, depart, salary GROUP BY depart.depname;
这个命令用于修改已存在的视图
view3
。WITH ENCRYPTION
选项表示将视图定义加密,这样就不能通过sp_helptext
查看其定义。AS
后面跟着的是一个SELECT
语句,它定义了视图的内容。这个SELECT
语句从worker
、depart
和salary
表中选择部门名称和平均工资,并且使用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
列相匹配。
-
声明和使用滚动游标:
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
的滚动游标,它用于从worker
和depart
表中选择所有记录,其中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';
-
声明游标 (
DECLARE worker_cur SCROLL CURSOR
):DECLARE
是 SQL 中用来声明游标的关键字。worker_cur
是游标的名称,你可以根据需要选择任何有效的标识符。SCROLL CURSOR
指定了游标的类型。滚动游标允许你以各种方式浏览结果集,包括向前、向后、到第一行、到最后一行等。
-
定义游标选择范围 (
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' 的记录。
-
游标操作:
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_cur
。FETCH FIRST
和 FETCH NEXT
分别获取第一条和下一条记录。@@fetch_status
是一个系统变量,用于显示最近一次游标操作的状态。FETCH RELATIVE
和 FETCH ABSOLUTE
用于移动游标到相对位置或绝对位置的记录。
-
关闭游标:
CLOSE worker_cur;
这个命令用于关闭游标 worker_cur
。
-
声明和使用动态游标:
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 用法
- 筛选比王华年龄大
SELECT * FROM 学生信息表 WHERE 年龄 > (SELECT 年龄 FROM 学生信息表 WHERE 学生姓名 = '王华');
- 检索C2课程中成绩最高的学生的学号
SELECT 学号 FROM 学生成绩表 WHERE 课程名称 = 'C2' ORDER BY 成绩 DESC LIMIT 1;
ORDER BY 用法
-
按单一列升序排序:
SELECT * FROM table_name ORDER BY column1 **ASC**;
-
按单一列降序排序:
SELECT * FROM table_name ORDER BY column1 **DESC**;
-
按多个列排序: 可以按照多个列进行排序,第一列排序后,第二列将用于对具有相同值的行进行排序。
SELECT * FROM table_name ORDER BY column1 ASC, column2 DESC;
-
选择特定列并排序: 只选择特定的列,并按照另一列进行排序。
SELECT column1, column2 FROM table_name ORDER BY column3 DESC;
-
排序并限制结果数量: 结合
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;
在这个例子中,查询将根据 Department
和 HireYear
进行分组,计算每个部门、每个年份的平均薪资。
2. 空值分组
在 GROUP BY
中,如果存在 NULL
值,它们通常会被聚合成一个单独的组。如果您想要区分 NULL
值,可能需要使用条件表达式或特定的数据库功能。
3. 与 HAVING
子句结合使用
GROUP BY
与 HAVING
子句结合使用可以对分组后的结果进行条件过滤。
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 BY
与 DISTINCT
子句不同。DISTINCT
用于返回唯一不同的值,而 GROUP BY
用于聚合操作
DISTINCT 用法
DISTINCT
是 SQL 中的一个关键字,用于返回唯一不同的值,从而去除重复的行。DISTINCT
通常与 SELECT
语句一起使用,可以应用于一个或多个列。以下是 DISTINCT
的几种常见用法:
基本用法
SELECT DISTINCT column_name
FROM table_name;
这个查询将从 table_name
表中选择 column_name
列的唯一不同的值。
示例
假设有一个名为 Orders
的表,包含 OrderID
、CustomerName
和 OrderDate
列。如果我们想获取唯一的客户名称,可以这样写:
SELECT DISTINCT CustomerName
FROM Orders;
多列 DISTINCT
DISTINCT
也可以与多个列一起使用,这样它会基于这些列的组合来去除重复行。
SELECT DISTINCT column_name1, column_name2
FROM table_name;
这个查询将返回 column_name1
和 column_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的用法
-
重命名:在SQL语句中,
AS
用于给表、列或查询结果重命名。这在编写更易读的查询时非常有用。示例:
SELECT employee_id AS ID, first_name AS Name FROM employees;
在这个例子中,
AS
用于将employee_id
列重命名为ID
,将first_name
列重命名为Name
。-
定义别名:在连接(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
。 -
创建视图:在创建视图(VIEW)时,
AS
用于指定视图的SQL查询。示例:
CREATE VIEW employee_view AS SELECT * FROM employees WHERE department_id = 10;
在这个例子中,
AS
后面跟着的是一个查询,定义了employee_view
视图的内容。 -
定义存储过程:在创建存储过程(PROCEDURE)时,
AS
用于开始存储过程的主体。示例:
CREATE PROCEDURE MyProcedure AS BEGIN -- SQL statements END;
这里
AS
用于开始存储过程MyProcedure
的主体部分,之后跟着的是存储过程的SQL语句。 -
定义函数:在创建函数(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;
调用存储过程
创建存储过程后,可以通过EXEC
或EXECUTE
关键字来调用它:
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(触发器)
自动触发、事件触发
触发器的类型:
- AFTER触发器:在数据库操作之后触发。AFTER触发器不能修改触发它的操作的结果。
- INSTEAD OF触发器:在数据库操作之前触发,并且可以拦截原始操作,执行一系列不同的SQL语句。INSTEAD OF触发器主要用于视图,但也可以用于表。
- BEFORE触发器:在数据库操作之前触发。BEFORE触发器可以访问旧数据(即操作前的数据),但不能访问新数据。
- 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()
函数的一些常见用法:
-
生成随机数: 直接调用
RAND()
将返回一个0到1之间的随机浮点数。SELECT RAND();
-
与数值相乘:
RAND()
常与数值相乘,以生成一个特定范围的随机数。例如,如果你有一个数值n
,并且想要一个介于0到n
之间的随机数,你可以这样做:SELECT RAND() * n;
这将生成一个介于0到
n
的随机浮点数。 -
作为排序的依据:
RAND()
可以用作ORDER BY
子句的一部分,以随机排序结果集。SELECT * FROM table_name ORDER BY RAND();
这将随机地返回
table_name
表中的行。 -
随机选择记录: 当需要从大量记录中随机选择几条时,
RAND()
可以与TOP
关键字结合使用(在某些数据库系统中,如SQL Server)。SELECT TOP 10 * FROM table_name ORDER BY RAND();
这将随机选择
table_name
表中的10条记录。 -
随机分页:
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
是一种特定类型的约束,用来限制列中的值必须满足特定的条件。约束主要有以下几种类型:
- PRIMARY KEY(主键): 用于唯一标识数据库表中的每条记录。
- FOREIGN KEY(外键): 用于在两个表之间建立链接,并确保引用的数据的完整性。
- UNIQUE(唯一性): 保证在某个列或列的组合中的所有值都是不同的。
- CHECK(检查): 用于确保列中的值满足特定的条件。
- DEFAULT(默认值): 当没有为列提供值时,将使用默认值。
CHECK 约束
CHECK
约束用于限制列中的值必须满足特定的条件。这个条件是一个逻辑表达式,结果必须为TRUE
或UNKNOWN
(在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
表中Department
为Finance
的所有员工记录,并将它们插入到OldEmployeeRecords
表中。4. 插入默认值
如果你想要插入一个新行,但不需要为所有列提供值,并且表的其他列具有默认值或允许为空(NULL),可以省略列名和值:
INSERT INTO 表名 VALUES (DEFAULT, ...);
或者:
INSERT INTO 表名 VALUES (NULL, ...);
示例:
INSERT INTO Employees (EmployeeID) VALUES (DEFAULT);
这条语句将只插入一个新的
EmployeeID
,默认值由该列的默认值或自动增长规则决定。注意事项
- 确保插入的数据类型与表定义的列数据类型相匹配。
- 如果列有
NOT NULL
约束,必须为这些列提供值,除非它们有默认值。 - 如果表有主键约束,需要确保插入的值是唯一的,除非主键列的值由数据库自动生成。
INSERT INTO
是数据库操作中非常基本且常用的语句,掌握它的用法对于数据库管理和数据维护至关重要。