SQL Server相關的sql語句

目錄

  • 一、數據定義語言(DDL)
      • 1. 創建數據庫
      • 2. 修改數據庫
      • 3. 刪除數據庫
      • 4. 創建表
      • 5. 修改表結構
      • 6. 刪除表
  • 二、數據操作語言(DML)
      • 1. 插入數據
      • 2. 更新數據
      • 3. 刪除數據
  • 三、數據查詢語言(DQL)
      • 1. 基礎查詢
      • 2. 去重與聚合函數
      • 3. 分組查詢(GROUP BY/HAVING)
      • 4. 連接查詢(JOIN)
      • 5. 子查詢
      • 6. 分頁查詢(SQL Server 特有的分頁方式)
  • 四、觸發器(Triggers)
      • 1. 插入后觸發器(AFTER INSERT)
      • 2. 更新前觸發器(INSTEAD OF UPDATE)
      • 3. 級聯刪除觸發器
      • 4. 管理觸發器
  • 五、索引(Indexes)
      • 1. 索引類型
      • 2. 創建索引
      • 3. 查看索引
      • 4. 索引優化建議
  • 六、函數(Functions)
    • (一)內置函數
      • 1. 字符串函數
      • 2. 數值函數
      • 3. 日期和時間函數
      • 4. 聚合函數
      • 5. 邏輯函數
    • (二)自定義函數
      • 1. 標量函數(Scalar Functions)
      • 2. 表值函數(Table-Valued Functions)
    • (四)最佳實踐
    • (五)管理函數
  • 七、存儲過程(Stored Procedures)
      • 1. 創建存儲過程
      • 2. 執行存儲過程
      • 3. 帶輸出參數的存儲過程
      • 4. 存儲過程中的事務處理
      • 5. 修改和刪除存儲過程
  • 八、約束(Constraints)
      • 1. 主鍵約束(PRIMARY KEY)
      • 2. 唯一約束(UNIQUE)
      • 3. 外鍵約束(FOREIGN KEY)
      • 4. 檢查約束(CHECK)
      • 5. 默認約束(DEFAULT)
  • 九、授權(Permissions)
    • (一)安全主體(Security Principals)
      • 1. 服務器級主體
      • 2. 數據庫級主體
    • (二)權限分類
      • 1. 對象權限
      • 2. 語句權限
      • 3. 架構權限
    • (三)權限管理語句
      • 1. 授予權限(GRANT)
      • 2. 撤銷權限(REVOKE)
      • 3. 拒絕權限(DENY)
    • (四)預定義角色
      • 1. 服務器級角色
      • 2. 數據庫級角色
  • 十、事務控制語言(TCL)
      • 1. 開啟事務
      • 2. 提交事務(永久保存更改)
      • 3. 回滾事務(撤銷更改)
      • 4. 帶錯誤處理的事務(TRY...CATCH)
  • 十一、視圖(Views)
    • (一)視圖基礎
      • 1. 創建視圖
      • 2. 查詢視圖
    • (二)視圖的高級特性
      • 1. 索引視圖(物化視圖)
      • 2. 可更新視圖
      • 3. 分區視圖
    • (三)視圖的管理與優化
      • 1. 修改視圖
      • 2. 刪除視圖
      • 3. 查看視圖依賴關系
      • 4. 視圖優化
    • (四)視圖的應用場景
      • 1. 簡化復雜查詢
      • 2. 數據安全控制
      • 3. 兼容舊表結構
    • (五)視圖的優缺點
      • 1. 優點
      • 2. 缺點

一、數據定義語言(DDL)

用于創建、修改和刪除數據庫對象(如表、索引、視圖等)。

1. 創建數據庫

CREATE DATABASE DatabaseName; -- 創建數據庫
CREATE DATABASE DatabaseName ON PRIMARY -- 指定主數據文件
(NAME = 'LogicalFileName', -- 邏輯文件名FILENAME = 'PhysicalFilePath.mdf', -- 物理文件路徑SIZE = 10MB, -- 初始大小MAXSIZE = 50MB, -- 最大大小FILEGROWTH = 5MB -- 自動增長幅度
);

2. 修改數據庫

ALTER DATABASE DatabaseName ADD FILE -- 添加數據文件
(NAME = 'NewLogicalFileName',FILENAME = 'NewPhysicalFilePath.ndf',SIZE = 5MB,MAXSIZE = 20MB,FILEGROWTH = 2MB
);ALTER DATABASE DatabaseName MODIFY FILE -- 修改文件屬性(需指定 NAME)
(NAME = 'LogicalFileName',SIZE = 15MB,MAXSIZE = UNLIMITED -- 無限制增長
);ALTER DATABASE DatabaseName ADD LOG FILE -- 添加日志文件
(NAME = 'LogLogicalFileName',FILENAME = 'LogPhysicalFilePath.ldf',SIZE = 2MB,MAXSIZE = 10MB,FILEGROWTH = 1MB
);

3. 刪除數據庫

DROP DATABASE IF EXISTS DatabaseName; -- 存在時刪除(SQL Server 2016+)
DROP DATABASE DatabaseName; -- 直接刪除(需確保數據庫未被使用)

4. 創建表

CREATE TABLE dbo.Students -- dbo為架構名,可省略
(StudentID INT PRIMARY KEY IDENTITY(1,1), -- 主鍵(自增列)StudentName NVARCHAR(50) NOT NULL, -- 非空字符串Gender NVARCHAR(10) CHECK (Gender IN ('男', '女')), -- 檢查約束Age INT DEFAULT 18, -- 默認值約束EnrollDate DATE NOT NULL DEFAULT GETDATE() -- 默認值為當前日期
);

5. 修改表結構

ALTER TABLE Students ADD Address NVARCHAR(200); -- 添加列ALTER TABLE Students ALTER COLUMN Age INT NOT NULL; -- 修改列屬性(非空)ALTER TABLE Students DROP COLUMN Address; -- 刪除列sp_rename 'Students.Age', 'StudentAge', 'COLUMN'; -- 重命名列(存儲過程方式)
EXEC sp_rename 'Students', 'NewStudents'; -- 重命名表

6. 刪除表

DROP TABLE IF EXISTS dbo.Students; -- 存在時刪除

二、數據操作語言(DML)

用于操作表中的數據(增、刪、改)。

1. 插入數據

-- 插入指定列數據
INSERT INTO Students (StudentName, Gender, Age)
VALUES ('張三', '男', 20);-- 插入所有列數據(按表結構順序)
INSERT INTO Students
VALUES ('李四', '女', 19, '2023-09-01');-- 批量插入(從其他表查詢數據插入)
INSERT INTO NewStudents (StudentID, StudentName)
SELECT StudentID, StudentName FROM OldStudents;

2. 更新數據

-- 更新單條記錄
UPDATE Students
SET Age = 21, Gender = '男'
WHERE StudentID = 1;-- 更新所有記錄(無 WHERE 條件時需謹慎!)
UPDATE Students
SET Age = Age + 1;

3. 刪除數據

-- 刪除單條記錄
DELETE FROM Students
WHERE StudentID = 1;-- 刪除所有記錄(保留表結構)
DELETE FROM Students; -- 逐行刪除,記錄日志
TRUNCATE TABLE Students; -- 快速刪除,不記錄日志(不可回滾)

三、數據查詢語言(DQL)

用于從表中檢索數據,是 SQL 的核心部分。

1. 基礎查詢

SELECT StudentID, StudentName, Age -- 查詢指定列
FROM Students
WHERE Age > 18 AND Gender = '男'; -- 條件過濾SELECT * -- 查詢所有列
FROM Students
ORDER BY Age DESC, StudentName ASC; -- 按年齡降序、姓名升序排序

2. 去重與聚合函數

SELECT DISTINCT Gender -- 去重查詢
FROM Students;SELECT COUNT(*) AS TotalStudents -- 統計總行數
FROM Students;SELECT MAX(Age) AS MaxAge, MIN(Age) AS MinAge -- 最大值、最小值
FROM Students;SELECT SUM(Score) AS TotalScore -- 求和
FROM Exams;SELECT AVG(Score) AS AverageScore -- 平均值
FROM Exams;

3. 分組查詢(GROUP BY/HAVING)

SELECT Gender, COUNT(*) AS StudentCount -- 按性別分組統計人數
FROM Students
GROUP BY Gender;SELECT ClassID, AVG(Score) AS AvgScore -- 按班級分組,查詢平均分≥80的班級
FROM Exams
GROUP BY ClassID
HAVING AVG(Score) >= 80;

4. 連接查詢(JOIN)

-- 內連接:查詢學生及其課程成績
SELECT S.StudentName, C.CourseName, E.Score
FROM Students S
INNER JOIN Exams E ON S.StudentID = E.StudentID
INNER JOIN Courses C ON E.CourseID = C.CourseID;-- 左外連接:查詢所有學生(包括無成績的)
SELECT S.StudentName, E.Score
FROM Students S
LEFT OUTER JOIN Exams E ON S.StudentID = E.StudentID;-- 右外連接、全外連接類似,分別用 RIGHT JOIN/FULL JOIN

5. 子查詢

-- 查詢年齡大于平均年齡的學生
SELECT StudentName, Age
FROM Students
WHERE Age > (SELECT AVG(Age) FROM Students);-- 存在性查詢(IN/EXISTS)
SELECT StudentName
FROM Students
WHERE StudentID IN (SELECT StudentID FROM Exams WHERE Score > 90);

6. 分頁查詢(SQL Server 特有的分頁方式)

-- 使用 OFFSET-FETCH(SQL Server 2012+)
SELECT StudentID, StudentName, Age
FROM Students
ORDER BY StudentID
OFFSET 10 ROWS -- 跳過前10條
FETCH NEXT 5 ROWS ONLY; -- 取接下來的5條(共5條)-- 舊版使用 ROW_NUMBER()
WITH PagedData AS
(SELECT StudentID, StudentName, Age,ROW_NUMBER() OVER (ORDER BY StudentID) AS RowNumFROM Students
)
SELECT *
FROM PagedData
WHERE RowNum BETWEEN 11 AND 15;

四、觸發器(Triggers)

觸發器是一種特殊的存儲過程,它會在特定的表發生 INSERT、UPDATE、DELETE 操作時自動執行。常用于實現復雜的業務規則、數據審計或級聯操作。

1. 觸發器類型

  • DML 觸發器:響應 INSERT、UPDATE、DELETE 操作。
  • DDL 觸發器:響應 CREATE、ALTER、DROP 等數據定義語言操作。
  • 登錄觸發器:響應 LOGON 事件(SQL Server 2008+)。

2. 觸發器中的特殊表

  • INSERTED:存儲插入或更新后的新數據。
  • DELETED:存儲刪除或更新前的舊數據。

1. 插入后觸發器(AFTER INSERT)

CREATE TRIGGER trg_InsertStudent
ON Students
AFTER INSERT
AS
BEGIN-- 記錄日志INSERT INTO StudentLog (StudentID, Action, LogDate)SELECT StudentID, 'INSERT', GETDATE()FROM INSERTED;
END;

2. 更新前觸發器(INSTEAD OF UPDATE)

CREATE TRIGGER trg_PreventSalaryDecrease
ON Employees
INSTEAD OF UPDATE
AS
BEGINIF EXISTS (SELECT * FROM INSERTED i JOIN DELETED d ON i.EmployeeID = d.EmployeeID WHERE i.Salary < d.Salary)BEGINRAISERROR('不能降低員工工資!', 16, 1);ROLLBACK TRANSACTION;ENDELSEBEGINUPDATE EmployeesSET Salary = i.SalaryFROM Employees eJOIN INSERTED i ON e.EmployeeID = i.EmployeeID;END
END;

3. 級聯刪除觸發器

CREATE TRIGGER trg_CascadeDeleteOrders
ON Customers
AFTER DELETE
AS
BEGINDELETE FROM OrdersWHERE CustomerID IN (SELECT CustomerID FROM DELETED);
END;

4. 管理觸發器

-- 禁用觸發器
ALTER TABLE Students DISABLE TRIGGER trg_InsertStudent;-- 啟用觸發器
ALTER TABLE Students ENABLE TRIGGER trg_InsertStudent;-- 刪除觸發器
DROP TRIGGER IF EXISTS trg_InsertStudent;

五、索引(Indexes)

1. 索引類型

  • 聚集索引(Clustered Index):決定表中數據的物理存儲順序,一張表只能有一個。
  • 非聚集索引(Non-Clustered Index):存儲索引鍵和指向數據行的指針,一張表可有多。
  • 唯一索引(Unique Index):確保索引鍵不重復。
  • 覆蓋索引(Covering Index):包含查詢所需的所有列,避免回表。
  • 復合索引(Composite Index):基于多列創建的索引。

2. 創建索引

-- 創建聚集索引
CREATE CLUSTERED INDEX IX_Products_Price
ON Products (Price);-- 創建唯一非聚集索引
CREATE UNIQUE NONCLUSTERED INDEX UQ_Products_SKU
ON Products (SKU);-- 創建復合索引(注意列順序:最左匹配原則)
CREATE NONCLUSTERED INDEX IX_Orders_CustomerDate
ON Orders (CustomerID, OrderDate DESC);-- 創建包含列的覆蓋索引
CREATE NONCLUSTERED INDEX IX_Employees_Department
ON Employees (DepartmentID)
INCLUDE (EmployeeName, Salary); -- 包含列不參與索引鍵,但可直接返回結果

3. 查看索引

-- 查看表的所有索引
EXEC sp_helpindex 'Products';-- 查看索引使用情況
SELECT * FROM sys.dm_db_index_usage_stats
WHERE object_id = OBJECT_ID('Products');

4. 索引優化建議

  • 對查詢頻繁的列(如 WHERE、JOIN、ORDER BY 子句中的列)創建索引。
  • 避免對更新頻繁的表創建過多索引。
  • 使用 INCLUDE 關鍵字創建覆蓋索引,減少回表操作。
  • 通過執行計劃(SET SHOWPLAN_ALL ON)分析索引使用情況。

六、函數(Functions)

(一)內置函數

SQL Server 提供了豐富的內置函數,按功能可分為以下幾類:

1. 字符串函數

-- LEN: 返回字符串長度
SELECT LEN('Hello World') AS StringLength; -- 輸出: 11-- SUBSTRING: 截取子字符串
SELECT SUBSTRING('Hello', 2, 3) AS SubStr; -- 輸出: ell-- UPPER/LOWER: 大小寫轉換
SELECT UPPER('hello') AS UpperCase; -- 輸出: HELLO-- REPLACE: 替換字符串
SELECT REPLACE('Hello World', 'World', 'SQL') AS Replaced; -- 輸出: Hello SQL-- TRIM/LTRIM/RTRIM: 去除空格
SELECT TRIM('  SQL  ') AS Trimmed; -- 輸出: SQL

2. 數值函數

-- ROUND: 四舍五入
SELECT ROUND(3.14159, 2) AS Rounded; -- 輸出: 3.14-- ABS: 絕對值
SELECT ABS(-10) AS Absolute; -- 輸出: 10-- CEILING/FLOOR: 向上/向下取整
SELECT CEILING(3.1) AS CeilingVal; -- 輸出: 4
SELECT FLOOR(3.9) AS FloorVal; -- 輸出: 3-- RAND: 生成隨機數
SELECT RAND() AS RandomNum; -- 輸出: 0-1之間的隨機數

3. 日期和時間函數

-- GETDATE: 獲取當前日期和時間
SELECT GETDATE() AS CurrentDateTime; -- 輸出: 當前時間戳-- DATEADD: 日期加減
SELECT DATEADD(DAY, 7, '2023-01-01') AS NextWeek; -- 輸出: 2023-01-08-- DATEDIFF: 計算日期差
SELECT DATEDIFF(YEAR, '2000-01-01', GETDATE()) AS YearsPassed; -- 輸出: 當前年份-2000-- FORMAT: 格式化日期
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd') AS FormattedDate; -- 輸出: 2023-06-05

4. 聚合函數

-- SUM: 求和
SELECT SUM(Price) AS TotalPrice FROM Products;-- AVG: 平均值
SELECT AVG(Age) AS AverageAge FROM Employees;-- COUNT: 計數
SELECT COUNT(*) AS TotalRows FROM Customers;-- MAX/MIN: 最大值/最小值
SELECT MAX(Salary) AS MaxSalary, MIN(Salary) AS MinSalary FROM Employees;

5. 邏輯函數

-- CASE: 條件判斷
SELECT ProductName,CASE WHEN Price > 100 THEN 'Expensive'WHEN Price > 50 THEN 'Medium'ELSE 'Cheap'END AS PriceCategory
FROM Products;-- ISNULL: 處理 NULL 值
SELECT ISNULL(Email, 'No Email') AS ContactInfo FROM Customers;-- COALESCE: 返回第一個非 NULL 值
SELECT COALESCE(Phone, Email, 'No Contact') AS Contact FROM Customers;

(二)自定義函數

用戶可以創建自己的函數,分為以下兩類:

1. 標量函數(Scalar Functions)

返回單個值:

-- 創建計算年齡的標量函數
CREATE FUNCTION dbo.CalculateAge(@BirthDate DATE)
RETURNS INT
AS
BEGINRETURN YEAR(GETDATE()) - YEAR(@BirthDate) - CASE WHEN MONTH(@BirthDate) > MONTH(GETDATE()) OR (MONTH(@BirthDate) = MONTH(GETDATE()) AND DAY(@BirthDate) > DAY(GETDATE())) THEN 1 ELSE 0 END;
END;-- 使用標量函數
SELECT EmployeeName, dbo.CalculateAge(BirthDate) AS Age FROM Employees;

2. 表值函數(Table-Valued Functions)

返回表數據:

-- 內聯表值函數(簡單查詢)
CREATE FUNCTION dbo.GetProductsByCategory(@Category NVARCHAR(50))
RETURNS TABLE
AS
RETURN (SELECT ProductID, ProductName, PriceFROM ProductsWHERE Category = @Category
);-- 使用內聯表值函數
SELECT * FROM dbo.GetProductsByCategory('Electronics');-- 多語句表值函數(復雜邏輯)
CREATE FUNCTION dbo.GetEmployeeDetails()
RETURNS @Result TABLE (EmployeeID INT,FullName NVARCHAR(100),Department NVARCHAR(50),Salary DECIMAL(10,2)
)
AS
BEGININSERT INTO @ResultSELECT e.EmployeeID,e.FirstName + ' ' + e.LastName AS FullName,d.DepartmentName,e.SalaryFROM Employees eJOIN Departments d ON e.DepartmentID = d.DepartmentID;RETURN;
END;-- 使用多語句表值函數
SELECT * FROM dbo.GetEmployeeDetails();

(四)最佳實踐

  1. 避免在 WHERE 子句中調用標量函數:可能導致全表掃描,例如:

    -- 低效:對每一行調用函數
    SELECT * FROM Employees WHERE dbo.CalculateAge(BirthDate) > 30;-- 優化:先過濾再計算
    SELECT * FROM Employees WHERE BirthDate < DATEADD(YEAR, -30, GETDATE());
    
  2. 優先使用內聯表值函數:性能優于多語句表值函數。

  3. 保持函數簡潔:避免在函數中實現復雜業務邏輯。

  4. 使用 SCHEMABINDING:創建函數時綁定架構,防止依賴對象被修改:

    CREATE FUNCTION dbo.GetProducts()
    RETURNS TABLE
    WITH SCHEMABINDING
    AS
    RETURN (SELECT ProductID, ProductName FROM dbo.Products);
    

(五)管理函數

-- 修改函數
ALTER FUNCTION dbo.CalculateAge(@BirthDate DATE)
RETURNS INT
AS
BEGIN-- 修改后的邏輯RETURN DATEDIFF(YEAR, @BirthDate, GETDATE());
END;-- 刪除函數
DROP FUNCTION IF EXISTS dbo.CalculateAge;-- 查看函數定義
EXEC sp_helptext 'dbo.GetProductsByCategory';

七、存儲過程(Stored Procedures)

1. 創建存儲過程

-- 帶參數的存儲過程
CREATE PROCEDURE sp_GetProductsByPrice@MinPrice DECIMAL(10,2),@MaxPrice DECIMAL(10,2) = 1000.00 -- 默認值
AS
BEGINSELECT ProductID, ProductName, PriceFROM ProductsWHERE Price BETWEEN @MinPrice AND @MaxPriceORDER BY Price DESC;
END;

2. 執行存儲過程

-- 帶參數執行
EXEC sp_GetProductsByPrice @MinPrice = 50.00, @MaxPrice = 200.00;-- 使用默認參數
EXEC sp_GetProductsByPrice @MinPrice = 100.00;

3. 帶輸出參數的存儲過程

CREATE PROCEDURE sp_CalculateTotalSales@StartDate DATE,@EndDate DATE,@TotalSales DECIMAL(10,2) OUTPUT -- 輸出參數
AS
BEGINSELECT @TotalSales = SUM(Amount)FROM SalesWHERE SaleDate BETWEEN @StartDate AND @EndDate;
END;-- 調用帶輸出參數的存儲過程
DECLARE @Total DECIMAL(10,2);
EXEC sp_CalculateTotalSales @StartDate = '2023-01-01', @EndDate = '2023-12-31', @TotalSales = @Total OUTPUT;
PRINT '總銷售額: ' + CAST(@Total AS VARCHAR);

4. 存儲過程中的事務處理

CREATE PROCEDURE sp_TransferFunds@FromAccount INT,@ToAccount INT,@Amount DECIMAL(10,2)
AS
BEGINSET NOCOUNT ON; -- 減少消息開銷BEGIN TRYBEGIN TRANSACTION;-- 檢查余額IF (SELECT Balance FROM Accounts WHERE AccountID = @FromAccount) < @AmountBEGINRAISERROR('余額不足', 16, 1);RETURN;END-- 轉賬操作UPDATE Accounts SET Balance = Balance - @Amount WHERE AccountID = @FromAccount;UPDATE Accounts SET Balance = Balance + @Amount WHERE AccountID = @ToAccount;COMMIT TRANSACTION;END TRYBEGIN CATCHIF @@TRANCOUNT > 0ROLLBACK TRANSACTION;PRINT '錯誤: ' + ERROR_MESSAGE();END CATCH
END;

5. 修改和刪除存儲過程

-- 修改存儲過程(使用 ALTER 而非 CREATE)
ALTER PROCEDURE sp_GetProductsByPrice@MinPrice DECIMAL(10,2),@MaxPrice DECIMAL(10,2) = 1000.00
AS
BEGIN-- 修改后的邏輯SELECT ProductID, ProductName, Price, CategoryFROM ProductsWHERE Price BETWEEN @MinPrice AND @MaxPrice;
END;-- 刪除存儲過程
DROP PROCEDURE IF EXISTS sp_GetProductsByPrice;

八、約束(Constraints)

約束用于強制數據的完整性,確保數據符合業務規則。SQL Server 支持以下約束類型:

1. 主鍵約束(PRIMARY KEY)

確保列值唯一且不為空,一張表只能有一個主鍵。

CREATE TABLE Products (ProductID INT PRIMARY KEY, -- 隱式約束ProductName NVARCHAR(50)
);-- 或顯式定義約束名
CREATE TABLE Products (ProductID INT,ProductName NVARCHAR(50),CONSTRAINT PK_Products PRIMARY KEY (ProductID)
);

2. 唯一約束(UNIQUE)

確保列值唯一,但允許 NULL(只能有一個 NULL)。

CREATE TABLE Employees (EmployeeID INT PRIMARY KEY,Email NVARCHAR(50) UNIQUE, -- 隱式約束Phone NVARCHAR(20)
);-- 或顯式定義約束名
CREATE TABLE Employees (EmployeeID INT PRIMARY KEY,Email NVARCHAR(50),Phone NVARCHAR(20),CONSTRAINT UQ_Employees_Email UNIQUE (Email)
);

3. 外鍵約束(FOREIGN KEY)

確保一個表中的列值匹配另一個表的主鍵或唯一鍵。

CREATE TABLE Orders (OrderID INT PRIMARY KEY,CustomerID INT,OrderDate DATE,CONSTRAINT FK_Orders_Customers FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);

4. 檢查約束(CHECK)

確保列值滿足特定條件。

CREATE TABLE Employees (EmployeeID INT PRIMARY KEY,Salary DECIMAL(10,2) CHECK (Salary >= 2000), -- 工資必須≥2000Age INT CHECK (Age BETWEEN 18 AND 65) -- 年齡范圍
);-- 或使用命名約束
ALTER TABLE Employees
ADD CONSTRAINT CK_Employees_Age CHECK (Age BETWEEN 18 AND 65);

5. 默認約束(DEFAULT)

為列提供默認值,當插入數據未指定值時自動使用。

CREATE TABLE Orders (OrderID INT PRIMARY KEY,OrderDate DATE DEFAULT GETDATE(), -- 默認當前日期Status NVARCHAR(20) DEFAULT 'Pending' -- 默認狀態
);```###  6. 管理約束```sql
-- 添加約束
ALTER TABLE Products
ADD CONSTRAINT CK_Products_Price CHECK (Price > 0);-- 刪除約束
ALTER TABLE Products
DROP CONSTRAINT CK_Products_Price;-- 禁用約束(臨時允許違反規則)
ALTER TABLE Orders
NOCHECK CONSTRAINT FK_Orders_Customers;-- 啟用約束并驗證現有數據
ALTER TABLE Orders
CHECK CONSTRAINT FK_Orders_Customers;

九、授權(Permissions)

(一)安全主體(Security Principals)

SQL Server 中的安全主體是可以被授予權限的實體,包括:

1. 服務器級主體

  • 登錄賬戶(Logins):訪問 SQL Server 實例的憑證。
    -- 創建 SQL 認證登錄(密碼驗證)
    CREATE LOGIN AppUser WITH PASSWORD = 'StrongPassword123!';-- 創建 Windows 認證登錄(域賬戶)
    CREATE LOGIN [DOMAIN\UserName] FROM WINDOWS;
    

2. 數據庫級主體

  • 數據庫用戶(Users):登錄賬戶在特定數據庫中的映射。

    -- 在當前數據庫創建用戶并關聯登錄
    CREATE USER AppUser FOR LOGIN AppUser;
    
  • 數據庫角色(Roles):預定義或自定義的用戶組,便于批量授權。

    -- 創建自定義數據庫角色
    CREATE ROLE DataReader;-- 將用戶添加到角色
    ALTER ROLE DataReader ADD MEMBER AppUser;
    

(二)權限分類

SQL Server 的權限分為三類:

1. 對象權限

針對表、視圖、存儲過程等數據庫對象的操作權限:

-- 授予 SELECT 權限
GRANT SELECT ON dbo.Products TO AppUser;-- 授予多個權限
GRANT INSERT, UPDATE, DELETE ON dbo.Orders TO DataWriterRole;-- 授予對所有表的查詢權限
GRANT SELECT ON ALL TABLES IN SCHEMA dbo TO DataReader;

2. 語句權限

執行特定 SQL 語句的權限(如創建數據庫、備份等):

-- 授予創建表的權限
GRANT CREATE TABLE TO DeveloperRole;-- 授予備份數據庫的權限
GRANT BACKUP DATABASE TO BackupOperator;

3. 架構權限

針對架構(Schema)的權限控制:

-- 授予對架構中所有對象的全部權限
GRANT CONTROL ON SCHEMA::dbo TO DBA;

(三)權限管理語句

1. 授予權限(GRANT)

-- 授予用戶查詢 Products 表的權限
GRANT SELECT ON dbo.Products TO AppUser;-- 授予用戶執行存儲過程的權限
GRANT EXECUTE ON dbo.sp_GetOrderDetails TO ReportUser;

2. 撤銷權限(REVOKE)

-- 撤銷用戶的 DELETE 權限
REVOKE DELETE ON dbo.Customers FROM JuniorDBA;

3. 拒絕權限(DENY)

拒絕權限會覆蓋已授予的權限(即使通過角色獲得權限也無效):

-- 拒絕用戶修改 Products 表
DENY UPDATE ON dbo.Products TO ReadOnlyUser;

(四)預定義角色

SQL Server 提供了預定義的服務器角色和數據庫角色,便于快速授權:

1. 服務器級角色

-- 將登錄添加到 sysadmin 角色(超級管理員)
ALTER SERVER ROLE sysadmin ADD MEMBER [DOMAIN\AdminUser];-- 將登錄添加到 bulkadmin 角色(允許 BULK INSERT)
ALTER SERVER ROLE bulkadmin ADD MEMBER AppUser;

2. 數據庫級角色

-- 將用戶添加到 db_datareader 角色(允許查詢所有表)
ALTER ROLE db_datareader ADD MEMBER AppUser;-- 將用戶添加到 db_ddladmin 角色(允許執行 DDL 語句)
ALTER ROLE db_ddladmin ADD MEMBER Developer;

十、事務控制語言(TCL)

用于管理事務,確保數據的一致性和完整性。

1. 開啟事務

BEGIN TRANSACTION; -- 開始事務

2. 提交事務(永久保存更改)

COMMIT TRANSACTION; -- 提交事務

3. 回滾事務(撤銷更改)

ROLLBACK TRANSACTION; -- 回滾到事務開始前的狀態

4. 帶錯誤處理的事務(TRY…CATCH)

BEGIN TRYBEGIN TRANSACTION;-- 執行可能出錯的操作UPDATE Accounts SET Balance = Balance - 100 WHERE AccountID = 1;UPDATE Accounts SET Balance = Balance + 100 WHERE AccountID = 2;COMMIT TRANSACTION;
END TRY
BEGIN CATCHROLLBACK TRANSACTION; -- 出錯時回滾PRINT '事務執行失敗:' + ERROR_MESSAGE(); -- 打印錯誤信息
END CATCH

十一、視圖(Views)

創建視圖

CREATE VIEW vw_StudentScores AS
SELECT S.StudentName, C.CourseName, E.Score
FROM Students S
JOIN Exams E ON S.StudentID = E.StudentID
JOIN Courses C ON E.CourseID = C.CourseID;-- 使用視圖
SELECT * FROM vw_StudentScores WHERE Score > 80;

以下是 SQL Server 中 視圖(Views) 的詳細介紹及示例,涵蓋視圖的創建、使用、優化及最佳實踐:

(一)視圖基礎

視圖是虛擬表,其內容由查詢定義。它不存儲實際數據,而是在查詢時動態生成結果。

1. 創建視圖

-- 創建簡單視圖
CREATE VIEW vw_ProductSummary AS
SELECT p.ProductID,p.ProductName,c.CategoryName,p.Price
FROM Products p
JOIN Categories c ON p.CategoryID = c.CategoryID
WHERE p.Price > 100;-- 創建帶聚合的視圖
CREATE VIEW vw_CategorySales AS
SELECT c.CategoryName,COUNT(p.ProductID) AS ProductCount,SUM(p.Price * od.Quantity) AS TotalSales
FROM Categories c
JOIN Products p ON c.CategoryID = p.CategoryID
JOIN OrderDetails od ON p.ProductID = od.ProductID
GROUP BY c.CategoryName;

2. 查詢視圖

-- 像查詢表一樣查詢視圖
SELECT * FROM vw_ProductSummary;-- 帶條件查詢視圖
SELECT CategoryName, ProductName 
FROM vw_ProductSummary 
WHERE CategoryName = 'Electronics';

(二)視圖的高級特性

1. 索引視圖(物化視圖)

預計算并存儲視圖結果,提高查詢性能:

-- 創建索引視圖(需滿足特定條件)
CREATE VIEW vw_IndexedProduct
WITH SCHEMABINDING -- 綁定架構,防止依賴對象被修改
AS
SELECT ProductID,ProductName,Price,CategoryID
FROM dbo.Products
WHERE Price > 50;-- 為視圖創建聚集索引(自動物化視圖)
CREATE UNIQUE CLUSTERED INDEX idx_vw_Product ON vw_IndexedProduct (ProductID);

2. 可更新視圖

滿足特定條件的視圖允許 DML 操作:

-- 創建可更新視圖
CREATE VIEW vw_Employees AS
SELECT EmployeeID,FirstName,LastName,DepartmentID
FROM Employees
WHERE DepartmentID = 1;-- 通過視圖插入數據
INSERT INTO vw_Employees (FirstName, LastName, DepartmentID)
VALUES ('John', 'Doe', 1);

3. 分區視圖

跨多個服務器或表分布數據:

-- 示例:將數據按區域分區
CREATE VIEW vw_Orders_All AS
SELECT * FROM Orders_East
UNION ALL
SELECT * FROM Orders_West
UNION ALL
SELECT * FROM Orders_North;

(三)視圖的管理與優化

1. 修改視圖

-- 修改視圖定義
ALTER VIEW vw_ProductSummary AS
SELECT p.ProductID,p.ProductName,c.CategoryName,p.Price,p.Discount
FROM Products p
JOIN Categories c ON p.CategoryID = c.CategoryID
WHERE p.Price > 50; -- 修改了價格過濾條件

2. 刪除視圖

DROP VIEW IF EXISTS vw_ProductSummary;

3. 查看視圖依賴關系

-- 查看視圖依賴的對象
EXEC sp_depends 'vw_ProductSummary';-- 查看依賴某個表的所有視圖
SELECT OBJECT_NAME(object_id) AS ViewName
FROM sys.sql_dependencies
WHERE referenced_object_id = OBJECT_ID('Products');

4. 視圖優化

  • 避免在視圖中使用函數:可能導致全表掃描。
  • 對索引視圖使用 WITH (NOEXPAND):強制 SQL Server 使用預計算結果。
    SELECT * FROM vw_IndexedProduct WITH (NOEXPAND) WHERE Price > 100;
    

(四)視圖的應用場景

1. 簡化復雜查詢

將常用的多表連接封裝為視圖:

CREATE VIEW vw_OrderDetails AS
SELECT o.OrderID,c.CustomerName,p.ProductName,od.Quantity,od.UnitPrice,od.Quantity * od.UnitPrice AS TotalAmount
FROM Orders o
JOIN Customers c ON o.CustomerID = c.CustomerID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID;

2. 數據安全控制

通過視圖限制用戶對敏感列的訪問:

CREATE VIEW vw_SafeEmployees AS
SELECT EmployeeID,FirstName,LastName,DepartmentID
FROM Employees; -- 不包含 Salary 等敏感列

3. 兼容舊表結構

在表結構變更時保持接口兼容性:

-- 舊表結構有 ProductName 列
-- 新表拆分為 FirstName 和 LastName 列
CREATE VIEW vw_LegacyProducts AS
SELECT ProductID,FirstName + ' ' + LastName AS ProductName,Price
FROM NewProducts;

(五)視圖的優缺點

1. 優點

  • 簡化查詢:封裝復雜邏輯,提高代碼復用性。
  • 安全性:限制用戶對底層數據的直接訪問。
  • 邏輯獨立性:表結構變更時無需修改應用代碼。
  • 性能優化:索引視圖可提高頻繁查詢的速度。

2. 缺點

  • 性能開銷:復雜視圖可能導致查詢變慢。
  • 維護成本:視圖依賴關系可能變得復雜。
  • 更新限制:可更新視圖需滿足嚴格條件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908244.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908244.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908244.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Hot 100】55. 跳躍游戲

目錄 引言跳躍游戲我的解題 &#x1f64b;?♂? 作者&#xff1a;海碼007&#x1f4dc; 專欄&#xff1a;算法專欄&#x1f4a5; 標題&#xff1a;【Hot 100】55. 跳躍游戲?? 寄語&#xff1a;書到用時方恨少&#xff0c;事非經過不知難&#xff01; 引言 跳躍游戲 &#x…

基于51單片機的車內防窒息檢測報警系統

目錄 具體實現功能 設計介紹 資料內容 全部內容 資料獲取 具體實現功能 具體實現功能&#xff1a; &#xff08;1&#xff09;檢測車內溫度及二氧化碳濃度并用lcd1602實時顯示。 &#xff08;2&#xff09;當人體紅外傳感器檢測到車內有人&#xff0c;且溫度或二氧化碳濃度…

關于智能體API參考接口

關于智能體在Flask的源碼&#xff1a;請求體(在payload里的是請求體)、請求頭&#xff08;在headers里的i局勢請求頭&#xff09;。 我的例子&#xff1a; 我的疑問&#xff1a;為什么沒按Coze官方API文檔格式&#xff0c;在Apifox里發POST請求卻能收到回復&#xff1f; 1. 你…

Excel 批量下載PDF、批量下載考勤圖片——仙盟創夢IDE

在辦公場景中&#xff0c;借助應用軟件實現 Excel 批量處理考勤圖片、電子文檔與 PDF&#xff0c;具有諸多顯著優勢。 從考勤圖片處理來看&#xff0c;通過 Excel 批量操作&#xff0c;能快速提取圖片中的考勤信息&#xff0c;如員工打卡時間、面部識別數據等&#xff0c;節省…

Apache Doris + MCP:Agent 時代的實時數據分析底座

一、Apache Doris&#xff1a;面向 Agent 時代的智能數據平臺 當我們談論 2025 年時&#xff0c;業界普遍認為這將是"Agent 革命年"&#xff08;Agentic Revolution&#xff09;的開端。與傳統的人機交互模式不同&#xff0c;AI Agent 作為一個全新的"用戶角色…

能不能用string接收數據庫的datetime類型字段

在Java中使用String類型通過MyBatis接收MySQL的datetime類型字段時&#xff0c;?可以正常工作&#xff0c;但需注意格式和潛在問題。以下是關鍵點&#xff1a; 1. ?直接轉換是可行的? MySQL的datetime字段&#xff08;如 2023-10-05 12:34:56&#xff09;會被MyBatis自動轉…

【Python訓練營打卡】day44 @浙大疏錦行

DAY 44 預訓練模型 知識點回顧&#xff1a; 1. 預訓練的概念 2. 常見的分類預訓練模型 3. 圖像預訓練模型的發展史 4. 預訓練的策略 5. 預訓練代碼實戰&#xff1a;resnet18 作業&#xff1a; 1. 嘗試在cifar10對比如下其他的預訓練模型&#xff0c;觀察差異&#xff0c;…

MySQL中關于事務和鎖的常見執行命令整理包括版本區別

MySQL中關于事務和鎖的常見執行命令實例整理&#xff0c;并標注了不同版本下的區別&#xff08;如MySQL 8.0與舊版本的差異&#xff09;&#xff1a; 一、事務相關命令 1. 事務控制 命令描述版本差異START TRANSACTION; 或 BEGIN;顯式開啟事務通用語法&#xff0c;無版本差異…

PyTorch-Transforms的使用(二)

對圖像進行處理 安裝open cv ctrlP 看用法 ToTensor的使用 常見的Transforms 歸一化的圖片 兩個長度為三的數組&#xff0c;分別表示三個通道的平均值和標準差 Resize&#xff08;&#xff09; Compose&#xff08;&#xff09; 合并執行功能&#xff0c;輸入進去一個列表&a…

vscode實用配置

前端開發安裝插件&#xff1a; 1.可以更好看的顯示文件圖標 2.用戶快速打開文件 使用步驟&#xff1a;在html文件下右鍵點擊 open with live server 即可 刷力扣&#xff1a; 安裝這個插件 還需要安裝node.js即可

Day130 | 靈神 | 回溯算法 | 子集型 電話號碼的字母組合

Day130 | 靈神 | 回溯算法 | 子集型 電話號碼的字母組合 17.電話號碼的字母組合 17. 電話號碼的字母組合 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 筆者用index代替i&#xff0c;這里的index其實就是digits數組的下標 按照靈神的回溯三問&#xff0c;那就…

深入理解JavaScript設計模式之閉包與高階函數

前言小序 一場失敗面試 2023年的某一天&#xff0c;一場讓我印象深刻的面試&#xff1a; 面試官&#xff1a; “你了解閉包嗎&#xff1f;請說一下你對閉包的理解。” 我自信滿滿地答道&#xff1a; “閉包就是函數里面套函數&#xff0c;里面的函數可以訪問外部函數的變量。…

使用 Spring Boot 3.3 和 JdbcTemplate 操作 MySQL 數據庫

在現代的 Java 應用開發中&#xff0c;Spring Boot 提供了強大的工具來簡化數據庫操作。JdbcTemplate 是 Spring 提供的一個核心類&#xff0c;用于簡化 JDBC 操作&#xff0c;減少樣板代碼。本文將介紹如何在 Spring Boot 3.3 項目中使用 JdbcTemplate 來操作 MySQL 數據庫&am…

如何做好一份技術文檔?(下篇)

如何做好一份技術文檔&#xff1f;&#xff08;下篇&#xff09; 下篇&#xff1a;文檔體驗的極致優化 ——從可用性到愉悅性的跨越 文檔用戶體驗地圖 新手路徑 專家路徑 [安裝] → [配置] → [示例] [API] → [參數] → [源碼] │ ▲ …

Windows 12確認沒了,Win11 重心偏移修Bug

微軟悄然擱置了傳說中的Windows 12開發計劃&#xff0c;轉身將精力投入到Windows 11的持續進化中。今年秋季的主角已經確定——Windows 11 25H2&#xff0c;它將于9月或10月間與我們正式見面。 與去年24H2的大規模更新不同&#xff0c;25H2更像是場精心策劃的“功能解鎖”。微軟…

JavaScript中的正則表達式:文本處理的瑞士軍刀

JavaScript中的正則表達式&#xff1a;文本處理的瑞士軍刀 在編程世界中&#xff0c;正則表達式&#xff08;Regular Expression&#xff0c;簡稱RegExp&#xff09;被譽為“文本處理的瑞士軍刀”。它能夠高效地完成字符串匹配、替換、提取和驗證等任務。無論是前端開發中的表…

基于LEAP模型在能源環境發展、碳排放建模預測及分析中實踐應用

在國家“3060”碳達峰碳中和的政策背景下&#xff0c;如何尋求經濟-能源-環境的平衡有效發展是國家、省份、城市及園區等不同級別經濟體的重要課題。根據國家政策、當地能源結構、能源技術發展水平以及相關碳排放指標制定合理有效的低碳能源發展規劃需要以科學準確的能源環境發…

Python爬蟲實戰:研究RoboBrowser庫相關技術

1. 引言 1.1 研究背景與意義 隨著電子商務的快速發展,商品信息呈現爆炸式增長。據 Statista 數據顯示,2025 年全球電子商務銷售額預計將達到 7.4 萬億美元,海量的商品數據蘊含著巨大的商業價值。對于電商企業而言,及時獲取競爭對手的產品信息、價格動態和用戶評價,能夠幫…

JVM垃圾回收器-ZGC

一、概述 ZGC&#xff08;Z Garbage Collector&#xff09;是一種高效且可擴展的低延遲垃圾回收器。在垃圾回收過程中&#xff0c;ZGC通過優化算法和硬件支持&#xff0c;將Stop-The-World&#xff08;STW&#xff09;時間控制在一毫秒以內&#xff0c;使其成為追求低延遲應用…

區間動態規劃

線性 DP 的一種&#xff0c;簡稱為「區間 DP」。以「區間長度」劃分階段&#xff0c;以兩個坐標&#xff08;區間的左、右端點&#xff09;作為狀態的維度。一個狀態通常由被它包含且比它更小的區間狀態轉移而來。 一、概念 間 DP 的主要思想就是&#xff1a;先在小區間內得到…