认识 SQL Server 的 T-SQL 语法

认识 SQL Server 的 T-SQL 语法

T-SQL(Transact-SQL)是微软在标准 SQL 之上扩展的"SQL Server 母语"------它既继承了 SQL 声明式的查询能力,又加入了过程式编程的变量、流程控制、错误处理,让 DBA 和开发能在一个语言里完成"查数据 + 写逻辑 + 控事务"。很多人写了多年 T-SQL 却没系统梳理过它的语法全貌。本文用一篇讲透 T-SQL 的分类、过程式扩展、批次机制与高频语法点。


一句话总结

T-SQL = 标准 SQL(DDL / DML / DCL / TCL)+ 过程式扩展(变量 / 流程控制 / 错误处理 / 批次)+ SQL Server 专属语法甜点(TOP / OUTPUT / CTE / PIVOT / APPLY / STRING_AGG ...)。理解这三层,就能从"会写 SELECT"进阶到"会写存储过程、会控事务、会用 SQL Server 的特性提效"。


一、T-SQL 到底是什么?

1.1 从标准 SQL 到 T-SQL

SQL 是 ANSI/ISO 标准化的查询语言,但各数据库厂商都做了"方言扩展"。SQL Server 的方言就是 T-SQL(Transact-SQL)

复制代码
SQL(ANSI 标准)
  │
  │  厂商扩展
  ▼
┌─────────────────────────────────────┐
│ T-SQL = 标准 SQL + 过程式编程扩展    │
│         + SQL Server 专属语法        │
└─────────────────────────────────────┘
对比项 标准 SQL T-SQL
基本查询 ✅ 支持 ✅ 支持
变量声明 ❌ 没有 DECLARE @x INT
流程控制 ❌ 没有 IF/WHILE/CASE
错误处理 ❌ 没有 TRY...CATCH
批次分隔 ❌ 没有 GO
TOP 取前 N 行 ❌(标准用 FETCH ✅ 原生支持
OUTPUT 子句 ❌ 没有 ✅ 原生支持

一句话:标准 SQL 告诉你"要什么数据",T-SQL 还能告诉你"按什么逻辑处理数据"。

1.2 T-SQL 的三大组成

复制代码
T-SQL
├── 1. 标准 SQL 语句(声明式)── DDL / DML / DCL / TCL
├── 2. 过程式扩展(命令式)── 变量 / 控制流 / 错误处理 / 批次
└── 3. 函数与语法甜点 ── 内置函数 / TOP / CTE / PIVOT / APPLY ...

二、四大语句分类(标准 SQL 部分)

T-SQL 继承了标准 SQL 的四类语句,这是 T-SQL 的地基。

类别 全称 作用 典型语句
DDL Data Definition Language 定义结构 CREATE / ALTER / DROP
DML Data Manipulation Language 操作数据 SELECT / INSERT / UPDATE / DELETE / MERGE
DCL Data Control Language 权限控制 GRANT / REVOKE / DENY
TCL Transaction Control Language 事务控制 BEGIN TRAN / COMMIT / ROLLBACK / SAVE

2.1 DDL:定义结构

sql 复制代码
-- 建表
CREATE TABLE dbo.Employee (
    EmpID    INT          IDENTITY(1,1) PRIMARY KEY,   -- 自增主键
    EmpName  NVARCHAR(50) NOT NULL,
    DeptID   INT          NOT NULL,
    Salary   DECIMAL(10,2),
    HireDate DATE         DEFAULT GETDATE(),
    CONSTRAINT FK_Emp_Dept FOREIGN KEY (DeptID) REFERENCES dbo.Department(DeptID)
);

-- 加列
ALTER TABLE dbo.Employee ADD Email NVARCHAR(100);

-- 改列类型
ALTER TABLE dbo.Employee ALTER COLUMN Salary DECIMAL(12,2);

-- 删表
DROP TABLE dbo.Employee;

2.2 DML:操作数据

sql 复制代码
-- 插入:VALUES 多行 / SELECT 子查询 / 输出
INSERT INTO dbo.Employee (EmpName, DeptID, Salary)
VALUES ('张三', 1, 12000),
       ('李四', 2, 15000);

INSERT INTO dbo.Employee (EmpName, DeptID, Salary)
SELECT Name, DeptID, Pay FROM dbo.HR_Stage;

-- 更新(带 FROM 联接是 T-SQL 特色)
UPDATE e
SET    e.Salary = e.Salary * 1.1
FROM   dbo.Employee e
JOIN   dbo.Department d ON e.DeptID = d.DeptID
WHERE  d.DeptName = N'研发部';

-- 删除
DELETE FROM dbo.Employee WHERE HireDate < '2020-01-01';

-- MERGE:一步实现"有则更新、无则插入"(upsert)
MERGE dbo.Employee AS t                      -- 目标表
USING (SELECT @Name AS EmpName, @DeptID AS DeptID) AS s  -- 源数据
ON t.EmpName = s.EmpName
WHEN MATCHED THEN
    UPDATE SET Salary = @Salary
WHEN NOT MATCHED THEN
    INSERT (EmpName, DeptID, Salary) VALUES (s.EmpName, s.DeptID, @Salary);

2.3 DCL:权限控制

sql 复制代码
GRANT  SELECT, INSERT ON dbo.Employee TO role_app;
REVOKE INSERT          ON dbo.Employee FROM role_app;
DENY   DELETE          ON dbo.Employee TO role_app;   -- DENY 优先级最高

2.4 TCL:事务控制

sql 复制代码
BEGIN TRAN;
    UPDATE Account SET Balance = Balance - 500 WHERE AcctID = 'A';
    UPDATE Account SET Balance = Balance + 500 WHERE AcctID = 'B';
COMMIT TRAN;        -- 成功则提交
-- ROLLBACK TRAN;   -- 失败则回滚
-- SAVE TRAN sp1;   -- 设置保存点,可部分回滚

事务的 ACID 特性就靠 TCL 来落地。生产环境更新必须包在事务里,否则中途失败会产生脏数据。


三、过程式扩展(T-SQL 的灵魂)

标准 SQL 只能声明"要什么",T-SQL 的过程式扩展让它能像编程语言一样"按逻辑处理"。这一层是 T-SQL 区别于裸 SQL 的核心。

3.1 变量

sql 复制代码
-- 局部变量(@开头,批内有效)
DECLARE @Cnt      INT = 0;            -- 声明并赋初值
DECLARE @AvgSal   DECIMAL(10,2);

SET   @AvgSal = 12000;               -- SET 赋值(推荐,单值)
SELECT @Cnt = COUNT(*) FROM dbo.Employee;  -- SELECT 赋值(从查询取值)

PRINT  '员工数:' + CAST(@Cnt AS NVARCHAR(10));   -- 输出到消息窗口
赋值方式 语法 特点
SET SET @x = 值 标准写法,单值赋值,推荐
SELECT SELECT @x = col FROM t 从查询取值,多行时取最后一行

局部变量以 @ 开头;全局变量(系统变量)以 @@ 开头,如 @@ROWCOUNT@@IDENTITY@@VERSION

sql 复制代码
UPDATE dbo.Employee SET Salary = 15000 WHERE EmpID = 1;
SELECT @@ROWCOUNT AS 受影响行数;   -- 上一语句影响的行数
SELECT @@IDENTITY  AS 新自增ID;
SELECT @@VERSION  AS 版本;

3.2 流程控制

BEGIN...END 块
sql 复制代码
IF @Cnt > 0
BEGIN
    PRINT '有数据';
    SET @Msg = 'OK';
END

BEGIN...END 相当于 C/Java 的 { },把多条语句打包成一个逻辑块。

IF...ELSE
sql 复制代码
IF @Cnt = 0
    PRINT '无数据';
ELSE IF @Cnt < 10
    PRINT '少量';
ELSE
    PRINT '大量';
WHILE 循环
sql 复制代码
DECLARE @i INT = 1;
WHILE @i <= 10
BEGIN
    PRINT '第 ' + CAST(@i AS VARCHAR) + ' 次';
    SET @i = @i + 1;       -- T-SQL 没有 i++,必须显式累加
    IF @i = 5 BREAK;       -- 跳出循环
    IF @i = 3 CONTINUE;    -- 跳过本次,进入下一次
END
CASE 表达式
sql 复制代码
-- 列级条件映射
SELECT EmpName,
       Salary,
       CASE
           WHEN Salary >= 20000 THEN N'高薪'
           WHEN Salary >= 10000 THEN N'中薪'
           ELSE                    N'起薪'
       END AS 薪资档位
FROM dbo.Employee;

CASE 是表达式不是语句,必须返回一个值,常用于 SELECT 列、ORDER BY、UPDATE 的 SET。

其他跳转
语句 作用
BREAK 跳出循环
CONTINUE 跳过本次循环剩余部分
RETURN 退出当前批/过程,可返回整数值
GOTO label 无条件跳转(不推荐,破坏可读性)
WAITFOR DELAY '00:00:05' 等待 5 秒

3.3 错误处理 TRY...CATCH

sql 复制代码
BEGIN TRY
    BEGIN TRAN;
        -- 这里写可能出错的操作
        INSERT INTO dbo.Employee (EmpName) VALUES (NULL);  -- 违反 NOT NULL
    COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK TRAN;     -- 有事务则回滚
    
    PRINT  N'错误号:'   + CAST(ERROR_NUMBER()    AS NVARCHAR(10));
    PRINT  N'严重度:'   + CAST(ERROR_SEVERITY()  AS NVARCHAR(10));
    PRINT  N'存储过程:'+ COALESCE(ERROR_PROCEDURE(), N'(无)');
    PRINT  N'行号:'    + CAST(ERROR_LINE()       AS NVARCHAR(10));
    PRINT  N'消息:'    + ERROR_MESSAGE();
END CATCH;
错误函数 返回
ERROR_NUMBER() 错误编号
ERROR_SEVERITY() 严重级别(0-25)
ERROR_MESSAGE() 错误文本
ERROR_LINE() 出错行号
ERROR_PROCEDURE() 出错的模块名

生产环境所有写操作都要包进 TRY...CATCH,并在 CATCH 里回滚事务------这是防止脏数据的安全网。

3.4 批次与 GO

**批次(Batch)**是 T-SQL 一次提交执行的一组语句,GO 是批次分隔符(不是真正的 T-SQL 语句,由工具解析)。

sql 复制代码
-- 批次 1:建表
CREATE TABLE #T1 (ID INT);
GO

-- 批次 2:建变量(@x 只在本批有效)
DECLARE @x INT = 1;
PRINT @x;
GO

-- 批次 3:@x 已失效,下面会报"未声明"
-- PRINT @x;    -- ❌ Must declare the scalar variable "@x".
规则 说明
变量作用域 局部变量只在当前批次有效,跨批失效
GO 后数字 GO 5 表示把上一批重复执行 5 次
不能在批中间的语句位置换批 某些语句(如 CREATE VIEW/PROC)必须独占一个批
sql 复制代码
-- GO 带次数:重复执行 3 次
INSERT INTO dbo.Log(Msg) VALUES ('init');
GO 3

GO 是 SQL Server 工具(SSMS、sqlcmd)识别的分隔符 ,不是标准 SQL 语法,在程序代码(如 ADO.NET、JDBC)里发 SQL 时不能用 GO


四、T-SQL 语法甜点(SQL Server 专属特性)

这些是标准 SQL 没有或写法不同的特性,是 T-SQL 的"加分项"。

4.1 TOP:取前 N 行

sql 复制代码
-- 取前 10 行
SELECT TOP 10 EmpName, Salary
FROM dbo.Employee
ORDER BY Salary DESC;

-- 取前 10%(按百分比)
SELECT TOP 10 PERCENT * FROM dbo.Employee;

-- WITH TIES:并列名次也带上
SELECT TOP 5 WITH TIES EmpName, Salary
FROM dbo.Employee
ORDER BY Salary DESC;

标准 SQL 用 OFFSET ... FETCH NEXT N ROWS ONLY 实现分页,T-SQL 的 TOP 更简洁但只支持"取前 N",分页推荐用 OFFSET/FETCH

sql 复制代码
-- 标准分页写法(2012+)
SELECT EmpName, Salary
FROM dbo.Employee
ORDER BY EmpID
OFFSET 20 ROWS          -- 跳过 20 行
FETCH NEXT 10 ROWS ONLY; -- 取 10 行(第 3 页)

4.2 OUTPUT 子句:返回受影响的数据

sql 复制代码
-- 删除并把删掉的数据记入日志
DELETE FROM dbo.Employee
OUTPUT deleted.EmpID, deleted.EmpName, GETDATE() INTO dbo.DeleteLog
WHERE HireDate < '2020-01-01';

-- 更新时看前后的值
UPDATE dbo.Employee
SET Salary = Salary * 1.1
OUTPUT inserted.EmpName, deleted.Salary AS 旧薪, inserted.Salary AS 新薪;
伪表 含义
inserted INSERT/UPDATE 后的新值
deleted DELETE/UPDATE 前的旧值

OUTPUT 相当于"操作 + 审计"一步到位,常用于变更留痕触发器逻辑替代

4.3 CTE:通用表表达式

sql 复制代码
WITH HighPaid AS (
    SELECT EmpName, Salary, DeptID
    FROM dbo.Employee
    WHERE Salary > 15000
),
DeptAvg AS (
    SELECT DeptID, AVG(Salary) AS AvgSal
    FROM dbo.Employee
    GROUP BY DeptID
)
SELECT h.EmpName, h.Salary, d.AvgSal
FROM HighPaid h
JOIN DeptAvg d ON h.DeptID = d.DeptID;

递归 CTE 是 CTE 的王牌应用------查树形结构(如组织架构、物料 BOM):

sql 复制代码
WITH OrgTree AS (
    -- 锚点:顶层节点
    SELECT EmpID, EmpName, ManagerID, 1 AS Lvl
    FROM dbo.Employee
    WHERE ManagerID IS NULL
    
    UNION ALL
    
    -- 递归成员:找下级
    SELECT e.EmpID, e.EmpName, e.ManagerID, o.Lvl + 1
    FROM dbo.Employee e
    JOIN OrgTree o ON e.ManagerID = o.EmpID
)
SELECT REPLICATE('  ', Lvl-1) + EmpName AS 组织层级, Lvl
FROM OrgTree
OPTION (MAXRECURSION 100);   -- 限制递归深度,默认 100,0 表示无限

4.4 PIVOT / UNPIVOT:行列转换

sql 复制代码
-- 把"行转列":每个部门的各职位薪资汇总
SELECT DeptID, [开发] AS 开发薪资, [测试] AS 测试薪资, [产品] AS 产品薪资
FROM (
    SELECT DeptID, Position, Salary FROM dbo.Employee
) AS src
PIVOT (
    SUM(Salary) FOR Position IN ([开发], [测试], [产品])
) AS pvt;

-- UNPIVOT:列转行(反向)
SELECT DeptID, Position, Salary
FROM PivotedTable
UNPIVOT (
    Salary FOR Position IN ([开发], [测试], [产品])
) AS up;

4.5 APPLY:联接表值函数/子查询

sql 复制代码
-- CROSS APPLY:类似 INNER JOIN,对每行调用表值函数
SELECT e.EmpName, t.TopOrderID
FROM dbo.Employee e
CROSS APPLY (
    SELECT TOP 3 OrderID
    FROM dbo.Orders
    WHERE CustID = e.EmpID
    ORDER BY OrderDate DESC
) t;

-- OUTER APPLY:类似 LEFT JOIN,函数无结果也保留行
SELECT e.EmpName, t.OrderID
FROM dbo.Employee e
OUTER APPLY (...) t;
APPLY 类型 行为
CROSS APPLY 只返回右表有匹配的行(= INNER JOIN)
OUTER APPLY 右表无匹配时返回 NULL(= LEFT JOIN)

APPLY 比普通 JOIN 强在:右表可以是依赖左表当前行的子查询或表值函数,JOIN 做不到。

4.6 STRING_AGG 与其他字符串函数(2017+)

sql 复制代码
-- 把一行行的名字拼成一列,用逗号分隔
SELECT DeptID,
       STRING_AGG(EmpName, ',') WITHIN GROUP (ORDER BY EmpName) AS 团队成员
FROM dbo.Employee
GROUP BY DeptID;
字符串函数 作用
STRING_AGG(col, sep) 拼接多值为一串(2017+)
STRING_SPLIT(str, sep) 拆分字符串为表(2016+)
CONCAT(a, b, ...) 自动处理 NULL 拼接
FORMAT(val, fmt) 格式化(如 FORMAT(getdate(),'yyyy-MM-dd')
STUFF(str, start, len, newstr) 在指定位置替换子串

五、内置函数分类速查

T-SQL 有 200+ 内置函数,按类型掌握最高效。

类别 作用 代表函数
聚合 多值汇总 SUM / AVG / COUNT / MIN / MAX
字符串 文本处理 SUBSTRING / REPLACE / CHARINDEX / STRING_AGG
日期时间 时间运算 GETDATE / DATEADD / DATEDIFF / FORMAT / EOMONTH
数学 数值计算 ROUND / CEILING / FLOOR / ABS / POWER
转换 类型转换 CAST / CONVERT / TRY_CAST / PARSE
NULL 处理 空值兜底 ISNULL / COALESCE / NULLIF
系统 元信息 @@ROWCOUNT / @@IDENTITY / SCOPE_IDENTITY / HOST_NAME
窗口 分组排名 ROW_NUMBER / RANK / DENSE_RANK / LEAD / LAG / SUM() OVER()

5.1 窗口函数(高频面试点)

sql 复制代码
-- 按部门排薪资名次
SELECT EmpName, DeptID, Salary,
       ROW_NUMBER() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS 行号,
       RANK()       OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS 排名,
       DENSE_RANK() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS 稠密排名
FROM dbo.Employee;

-- 累计求和
SELECT EmpName, Salary,
       SUM(Salary) OVER (ORDER BY EmpID
                         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 累计薪
FROM dbo.Employee;
函数 并列时行为
ROW_NUMBER() 1,2,3,4(不重复,必有唯一序号)
RANK() 1,2,2,4(并列后跳号)
DENSE_RANK() 1,2,2,3(并列后不跳号)

5.2 NULL 兜底:ISNULL vs COALESCE

sql 复制代码
SELECT ISNULL(Salary, 0)        AS 薪1,   -- SQL Server 专有,两参数
       COALESCE(Salary, Bonus, 0) AS 薪2;   -- 标准 SQL,可多参数,取第一个非空

COALESCE 是标准函数、参数个数不限、可跨数据库;ISNULL 只接两参但略快。写可移植代码用 COALESCE,追求极致性能用 ISNULL


六、T-SQL 实战:一个完整的存储过程

把上面所有知识点揉进一个真实场景------"按部门发奖金":

sql 复制代码
CREATE OR ALTER PROCEDURE dbo.usp_GrantBonus
    @DeptID     INT,
    @RaiseRate  DECIMAL(4,2) = 0.10,    -- 默认涨 10%
    @Affected   INT OUTPUT              -- 输出参数:影响行数
AS
BEGIN
    SET NOCOUNT ON;                     -- 不返回受影响行数提示,减少网络流量

    DECLARE @DeptName NVARCHAR(50);
    SELECT @DeptName = DeptName FROM dbo.Department WHERE DeptID = @DeptID;

    IF @DeptName IS NULL
    BEGIN
        RAISERROR('部门 %d 不存在', 16, 1, @DeptID);   -- 16 级错误抛出
        RETURN -1;                                       -- 退出并返回错误码
    END

    BEGIN TRY
        BEGIN TRAN;
            UPDATE e
            SET    e.Salary = e.Salary * (1 + @RaiseRate)
            FROM   dbo.Employee e
            WHERE  e.DeptID = @DeptID;

            SET @Affected = @@ROWCOUNT;

            -- 用 OUTPUT 把变更留痕
            INSERT INTO dbo.BonusLog (EmpID, OldSal, NewSal, OpTime)
            SELECT EmpID, OldSal, NewSal, GETDATE()
            FROM (
                UPDATE e
                SET    e.Salary = e.Salary * (1 + @RaiseRate)
                OUTPUT inserted.EmpID, deleted.Salary AS OldSal,
                       inserted.Salary AS NewSal
                FROM   dbo.Employee e
                WHERE  e.DeptID = @DeptID
            ) AS chg;
        COMMIT TRAN;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK TRAN;
        PRINT '发放奖金失败:' + ERROR_MESSAGE();
        RETURN ERROR_NUMBER();
    END CATCH

    PRINT '部门 [' + @DeptName + '] 共 ' + CAST(@Affected AS VARCHAR) + ' 人涨薪';
    RETURN 0;
END
GO

-- 调用
DECLARE @N INT;
EXEC dbo.usp_GrantBonus @DeptID=1, @RaiseRate=0.15, @Affected=@N OUTPUT;
SELECT @N AS 影响人数;

这段代码同时用到:变量、IFTRY/CATCH、事务、@@ROWCOUNTOUTPUTRAISERRORRETURN、输出参数、GO 批分隔------是 T-SQL 语法能力的综合体检。


七、T-SQL 高频坑与最佳实践

# 坑点 / 建议 说明
1 变量跨批失效 DECLARE @xGO 后失效,跨批需重新声明或用临时表/参数传递
2 SET vs SELECT 赋值 SELECT @x=col 多行时取最后一行且不报错,易踩坑;单值用 SET
3 SCOPE_IDENTITY vs @@IDENTITY 触发器里又插了别的表时,@@IDENTITY 返回的是触发器表的 ID;SCOPE_IDENTITY() 更安全
4 ISNULL vs COALESCE 前者专有两参略快,后者标准可移植;注意 COALESCE 返回类型按优先级推导
5 字符串用 N 前缀 中文/Unicode 字符串字面量必须 N'张三',否则会乱码
6 GO 不能放程序代码里 GO 是工具指令,ADO.NET/JDBC 里发 SQL 用 GO 会语法报错
7 WITH 语句前必须加分号 CTE 前若还有语句,需 ;WITH ... 防止语法歧义
8 TOP 不带 ORDER BY 不可靠 ORDER BYTOP 行序不保证,生产环境必须加排序
9 写操作必包事务 + TRY/CATCH 防止中途失败产生脏数据,CATCH 里先判 @@TRANCOUNT 再回滚
10 SET NOCOUNT ON 存储过程开头加它,减少 DONE_IN_PROC 消息,降低网络开销

字符串前缀 N 的坑

sql 复制代码
-- ❌ 不加 N:中文可能乱码(非 Unicode 列时)
INSERT INTO t VALUES ('张三');

-- ✅ 加 N:明确 Unicode
INSERT INTO t VALUES (N'张三');

八、T-SQL 学习路线建议

复制代码
入门 ─────────────── 进阶 ─────────────── 高阶
  │                  │                    │
  ▼                  ▼                    ▼
SELECT/INSERT    事务+TRY/CATCH       窗口函数
WHERE/JOIN       变量+流程控制        递归CTE
GROUP BY         存储过程+函数        执行计划调优
ORDER BY         CTE/APPLY           并行/批次模式
TOP              OUTPUT/PIVOT        扩展事件追踪
阶段 目标 验证标准
入门 能写增删改查 独立完成多表 JOIN + 聚合查询
进阶 能写存储过程 能用事务+错误处理封装业务逻辑
高阶 能调优与排查 看懂执行计划,能用窗口/CTE 解决复杂分析

九、T-SQL 语法速查表

类别 关键字 一句话
DDL CREATE/ALTER/DROP/TRUNCATE 建改删结构
DML SELECT/INSERT/UPDATE/DELETE/MERGE 查改增删
DCL GRANT/REVOKE/DENY 权限控制
TCL BEGIN/COMMIT/ROLLBACK/SAVE TRAN 事务控制
变量 DECLARE/SET/SELECT @@ 声明与赋值
流程 IF/WHILE/CASE/BEGIN-END 条件与循环
跳转 BREAK/CONTINUE/RETURN/GOTO/WAITFOR 流程跳转
错误 TRY...CATCH/RAISERROR/THROW 异常处理
批次 GO [n] 批次分隔
取前N TOP n [PERCENT] [WITH TIES] 取前 N 行
输出 OUTPUT inserted/deleted 返回变更数据
临时表 #t / ##t 局部/全局临时表
CTE WITH ... AS (...) 通用表表达式
行列转换 PIVOT/UNPIVOT 行列互转
联接 CROSS/OUTER APPLY 关联表值函数
窗口 ROW_NUMBER/RANK/SUM OVER() 分组排名累计
字符串 STRING_AGG/STRING_SPLIT/CONCAT 拼接与拆分

十、与标准 SQL / 其他方言对比

特性 T-SQL (SQL Server) PL/SQL (Oracle) MySQL
变量前缀 @(局部)/@@(全局) 无前缀 / v_ 命名 @
流程块 BEGIN...END BEGIN...END; BEGIN...END
错误处理 TRY...CATCH EXCEPTION DECLARE HANDLER
取前 N TOP n FETCH FIRST n ROWS / ROWNUM LIMIT n
批分隔 GO / ;
自增列 IDENTITY SEQUENCE/触发器 AUTO_INCREMENT
存储过程 CREATE PROC CREATE PROCEDURE CREATE PROCEDURE
字符串拼接 + / CONCAT `

多方言 DBA 最大的困扰不是语法本身,而是细节差异 :取前 N 行 Oracle 用 ROWNUM、MySQL 用 LIMIT、SQL Server 用 TOP,写代码前先确认目标库的方言。


DBA 夜话 :T-SQL 的语法看着庞杂,拆开就三块------标准 SQL 打地基、过程式扩展盖楼、专属语法做装修 。很多人卡在"会写 SELECT 但写不出存储过程",差的不是语法,是没把事务、错误处理、批次这三样当成肌肉记忆。建议拿本文第六节那个存储过程当靶子,照着敲一遍、改一遍、调一遍------当你能闭眼写出"事务 + TRY/CATCH + OUTPUT + 输出参数"的组合,T-SQL 这门"母语"就算真正入门了。记住一句话:写 SQL 是声明"要什么",写 T-SQL 是掌控"怎么要"------前者是查询,后者是工程。

相关推荐
easyeye1231 小时前
【gc随笔】免费 AI 编程助手 Agnes Code上手指南
人工智能
人才瘾大1 小时前
大模型四层推理缓存体系深度拆解:KV Cache、Prefix Cache、Prompt Cache与Semantic Cache
人工智能·prompt·ai编程
做萤石二次开发的哈哈1 小时前
路由器管理应用不用逐个啃协议了:海康无线路由器接入萤石蓝海AIoT,五类技能组合生成多端网管系统
人工智能·物联网·低代码·萤石开放平台·蓝海aiot一站式工作台·aiot开发
渡我白衣1 小时前
Util工具类功能设计与类设计
linux·服务器·网络·c++·人工智能·目标检测·机器学习
塔望品牌咨询1 小时前
食品品牌战略预算的决策框架:如何根据经营瓶颈安排研究、产品、渠道与传播
大数据·人工智能·塔望消费战略·食品
EatFan1 小时前
我为什么把患者与病例从 1:1 改成 1:N?一次真实数据库模型重构记录
数据库·后端·重构·健康医疗·全栈
羊羊小栈1 小时前
基于「YOLO目标检测 + 多模态AI分析」的公共场所暴力安全智能检测分析预警系统
人工智能·算法·面试·毕业设计·大作业
weixin_435208161 小时前
pi agent 扩展与 hook 机制浅析
人工智能·agent
土星云SaturnCloud1 小时前
ResNet-50 图像分类算法在边缘微服务器上的部署与性能评测
服务器·人工智能·算法·边缘计算·resnet-50