跳至内容

什么是 T-SQL?面向 SQL Server 的 Transact-SQL 新手指南

了解什么是 T-SQL、它如何扩展 SQL,以及如何在 SQL Server 中用于查询、自动化与过程化逻辑(含实践示例)。
更新 2026年5月4日  · 13分钟

T‑SQL(Transact-SQL)是微软对标准 SQL 的扩展,专为 Microsoft SQL Server 而设计。它不仅包含用于查询和管理数据的所有 SQL 核心功能,还新增了过程式编程特性,使您能够编写更强大、更动态的数据库逻辑。

在本指南中,我将向您展示 T-SQL 的工作原理,以及如何在真实场景中高效使用它。我还将结合实际示例,介绍查询数据库、编写存储过程和自动化日常流程等常见用例。

如果您是 SQL 新手,请从我们的SQL 入门课程开始;如果已有一定经验,可学习SQL 进阶课程。另外,我认为可下载的 SQL 基础速查表很有用,因为它汇总了最常用的 SQL 函数,便于查阅。

什么是 T-SQL,与 SQL 有何不同

为了更好地理解 T-SQL,可以将 SQL 视为通用语言,而 T-SQL 则是某一职业领域的专业方言。

SQL(结构化查询语言)是与关系型数据库交互的标准语言。它是声明式的,也就是说,您只需指定想要的结果(例如选择或筛选数据),数据库引擎将决定如何执行查询。

而 T-SQL 是微软在 Microsoft SQL Server 中使用的 SQL 扩展。它在标准 SQL 之上增加了过程式编程能力,使您可以按步骤控制操作的执行方式。

由此可见,T-SQL 引入了多项超越基础查询的强大功能,包括:

  • 变量: 您可以使用 DECLARESET 关键字在内存中存储数据,并在脚本中复用

  • 控制流:可以使用 IFWHILEBEGIN...END 等逻辑来控制执行并决定运行哪些代码。

  • 错误处理:T-SQL 引入了 TRY...CATCH 块,允许数据库捕获错误并优雅地处理,而不会导致整个操作崩溃。

  • 存储过程:您可以创建在数据库内部运行的可复用逻辑块。

如果您正在使用 SQL Server,DataCamp 提供了大量优质资源可供学习。建议从 DataCamp 的SQL Server 入门课程开始,掌握用于数据分析的 SQL Server 基础。

T-SQL 的基本语法与结构

T-SQL 使用与标准 SQL 相同的核心语法,如果您已经熟悉 SQL,将很容易上手。本节将通过简明的实用示例带您了解 T-SQL 最常见的语句。

SELECT、INSERT、UPDATE、DELETE

这些命令在大多数 SQL 方言中都是通用的,T-SQL 面向的 Microsoft SQL Server 亦然。

SELECT

用于从特定表中检索数据。例如,以下查询从 Customers 表中检索 FirstNameLastName

-- Retrieve data from the Customers table
SELECT FirstName, LastName
FROM Customers
WHERE Country = ‘USA’;  -- Filters rows to only customers in the USA

INSERT

用于向表中插入新数据。下面的查询向 customers 表插入一行新记录。

-- Insert a new row into a table
INSERT INTO customers (FirstName, city)
VALUES (‘Alice’, ‘Nairobi’);

UPDATE

用于修改数据库中的现有数据。例如,下面的查询将用户“Alice”的城市名称改为“Mombasa”。

-- Update existing data
UPDATE customers
SET city = ‘Mombasa’
WHERE FirstName= ‘Alice’; -- Always use WHERE to avoid updating all rows

DELETE

用于从数据库中删除数据。例如,下面的查询删除 FirstName 为“Alice”的那一行。

-- Delete data from a table
DELETE FROM customers
WHERE FirstName= ‘Alice’; -- Filters which rows to remove

建议您学习我们的SQL Server 基础技能路径,进一步了解如何使用 SQL Server 函数汇总与分析数据。

批处理执行

T-SQL 的一大特色在于其按批处理执行代码。批处理是一次发送到 SQL Server 的一组一个或多个 SQL 语句。

GO 关键字用于分隔批处理:

-- First batch
SELECT * FROM Customers;
GO  

-- Second batch (executed separately)
SELECT * FROM Orders;
GO

需要注意:

  • GO 不是 T-SQL 命令,但会被 SQL Server Management Studio 等工具识别。

  • 它用于标记一个批处理的结束和另一个批处理的开始。

  • 变量不会在批处理之间保留。同一会话中的临时对象实际上会在批处理之间保留。

注释与格式

您可以在 T-SQL 中使用注释,让 SQL 代码更易读、易维护。既可使用单行注释,也可使用多行注释,如下所示:

-- This query retrieves all customers
SELECT * FROM Customers;
/* This query retrieves customers
   from the USA and Canada */
SELECT * 
FROM Customers
WHERE Country IN ('USA', 'Canada');

T-SQL 中的变量与数据类型

T-SQL 允许您将值存储在变量中并在查询中使用,使脚本更灵活、更动态。下面看看如何创建这些变量。

声明变量

创建变量需使用 DECLARE 关键字。按照惯例,所有 T-SQL 变量名都必须以 @ 符号开头。

 -- Declares a variable to store text
DECLARE @CustomerName VARCHAR(50); 

赋值

可以使用 SET(推荐用于单一值)或 SELECT(从表中取值时很有用)来赋值。

-- Assign using SET 
SET @CustomerName = 'Alice';

-- Assign using SELECT 
SELECT @Age = 30;

例如,下面的查询使用变量而非硬编码,返回居住在伦敦的客户列表。

-- Assign the variable city 
DECLARE @City VARCHAR(50);
SET @City = 'London';

-- Use the variable in a query
SELECT name, city
FROM customers
WHERE city = @City; -- Filters results based on variable value

常见数据类型

以下是一些常用的 T-SQL 数据类型,这些类型在SQL 数据类型中也较为标准:

  • INT:整数,例如 1、100。

  • VARCHAR(n):可变长度文本,如姓名和邮箱。

  • DATETIME:日期和时间值。

  • DECIMAL(p, s):定点精度数字,如货币。

T-SQL 中的控制流(IF、WHILE、BEGIN...END)

T-SQL 的优势之一是可以为查询添加编程逻辑。您不仅能检索数据,还能控制代码的执行方式和时机。以下是控制流逻辑的示例。

IF...ELSE(条件执行)

IF 语句允许仅在满足特定条件时执行代码块。如果条件为假,可使用 ELSE 提供备用操作。

例如,下面的查询统计订单总数;若超过 100,则打印“High order volume”,否则打印“Low order volume”。

DECLARE @TotalOrders INT;

SELECT @TotalOrders = COUNT(*) 
FROM Orders;  -- Count total number of orders

IF @TotalOrders > 100
BEGIN
    PRINT 'High order volume';  -- Runs if condition is true
END
ELSE
BEGIN
    PRINT 'Low order volume';  -- Runs if condition is false
END

WHILE 循环(迭代逻辑)

WHILE 循环会在条件为真时重复执行代码块。它适用于分批执行的任务或生成测试数据。

下面的查询将计数器初始化为 1,并通过循环打印当前数字,每次加 1,直到达到 5。

DECLARE @Counter INT = 1;

WHILE @Counter <= 5
BEGIN
    PRINT @Counter;  -- Prints numbers from 1 to 5
    SET @Counter = @Counter + 1;  -- Increment counter
END

BEGIN...END(语句分组)

BEGIN...END 用于将多条语句分组为一个代码块,确保成组代码原子性地一起执行。

例如,下面的查询将同时打印“Customers found in USA”和“Proceeding with operation.”。若不使用 BEGIN...END,则仅会执行 IF 之后的第一条语句。

IF EXISTS (SELECT 1 FROM Customers WHERE Country = 'USA')
BEGIN
    PRINT 'Customers found in USA';
    PRINT 'Proceeding with operation';  -- Both statements run together
END

控制流何时有用?

T-SQL 中的控制流常用于:

  • 自动化:运行计划脚本或维护任务
  • 数据校验:在插入或更新数据前检查条件
  • 批处理:分步骤或循环处理数据
  • 业务逻辑:将规则直接应用于数据库内部

T-SQL 中的存储过程

存储过程是一组保存下来的 T-SQL 语句,您可以反复复用。与其每次都从应用程序发送大量代码到服务器,不如将代码保存在服务器上,随后只需调用其名称即可。

存储过程之所以有用,是因为它们可多次复用。预编译的执行计划可提升效率,并将复杂逻辑隐藏在简单接口之后。

例如,下面的存储过程会根据您提供的 ID 返回客户的名与姓。

-- Create a stored procedure named GetCustomerByID
CREATE PROCEDURE GetCustomerByID
    @CustomerID INT  -- Input parameter to pass a customer ID
AS
BEGIN
    -- Select the first and last name of a customer
    SELECT FirstName, LastName
    FROM Customers
    WHERE CustomerID = @CustomerID; -- Filter to match the given ID
END;

随后,您可通过下面的查询来执行该存储过程:

-- Calls the procedure
EXEC GetCustomerByID @CustomerID = 1;  

T-SQL 中的函数

T-SQL 包含内置函数和用户自定义函数(UDF),用于转换数据。

内置函数

这些函数已在 SQL Server 中提供,可直接在查询中使用。

字符串函数

用于转换字符串数据类型。例如,下面的查询从 Customers 表中检索所有名字,并将其转换为大写。

-- Converts text to uppercase
SELECT UPPER(FirstName)  
FROM Customers;

日期函数

用于处理日期函数。下面的查询返回当前系统日期和时间。

-- Returns current date and time
SELECT GETDATE();  

聚合函数

用于对表中的值进行聚合。例如,下面的查询统计 Customers 表中的总行数(客户数)。

-- Counts rows
SELECT COUNT(*) AS TotalCustomers
FROM Customers;  

用户自定义函数(UDF)

您也可以创建自己的函数,在多条查询中复用逻辑。

标量函数

标量函数返回单个值,适用于需要单一计算结果(如格式化或计算)的场景。下面的函数以名字和姓氏为输入,并返回合并后的全名。

-- Create a function that combines the first and last name
CREATE FUNCTION GetFullName 
(@FirstName VARCHAR(50), @LastName VARCHAR(50))
RETURNS VARCHAR(100)
AS
BEGIN
    RETURN @FirstName + ' ' + @LastName; -- Concatenates the two values
END;

表值函数

表值函数返回一个表。例如,下面的函数返回属于指定国家的所有客户组成的表。

-- Create a table-valued function named GetCustomersByCountry
CREATE FUNCTION GetCustomersByCountry (@Country VARCHAR(50))
RETURNS TABLE -- Specifies that the function returns a table
AS
RETURN
(
    -- Select all columns from the Customers table
    SELECT *
    FROM Customers
    WHERE Country = @Country -- Filter rows by the given country
);

建议您学习完整的SQL Server 开发者职业路径,不仅能掌握创建、更新与执行存储过程的技能,还将学习聚合函数、连接、插入与删除表等诸多内容。

T-SQL 中的错误处理

T-SQL 使用 TRY...CATCH 块处理错误,而不致使整个脚本停止。这一点很重要,可防止脚本意外崩溃,并便于返回有用的信息用于调试或日志记录。

例如,下面的查询尝试运行会触发错误的计算,捕获错误后打印可读的错误信息,而不是直接崩溃。

BEGIN TRY
    -- Attempt to run this code
    SELECT 1 / 0;  -- This causes a divide-by-zero error
END TRY
BEGIN CATCH
    -- Runs if an error occurs in the TRY block
    PRINT 'An error occurred: ' + ERROR_MESSAGE(); -- Displays the error message
END CATCH;

T-SQL 中的事务

事务确保一组操作要么全部成功、要么全部失败。这遵循 ACID 原则,即使在更新中途断电,也能保证数据库保持一致性。

在下面的示例中,事务在两个账户之间转账,并将两项更改一起保存。

BEGIN TRANSACTION; -- Start the transaction

-- Deduct money from Account 1
UPDATE Accounts
SET Balance = Balance - 100
WHERE AccountID = 1;

-- Add money to Account 2
UPDATE Accounts
SET Balance = Balance + 100
WHERE AccountID = 2;

COMMIT; -- Save all changes permanently

如果出现问题,您可以使用 ROLLBACK 回滚事务,将数据还原至之前的状态。

-- Undo all changes made in the current transaction
ROLLBACK; 

T-SQL 中的事务十分重要,它们可确保数据完整性,尤其在金融等关键系统中,部分更新可能导致数据不一致。

您可以学习我们的SQL Server 中的事务与错误处理职业路径,系统掌握 SQL Server 的事务与错误处理。

用于数据分析的常见 T-SQL 功能

T-SQL 包含一些对数据专业人士尤为有用的工具。下面看看示例以及如何在数据分析中应用它们。

窗口函数

窗口函数可在不将多行聚为单一结果的情况下跨行进行计算,多用于排名、运行总计和高级分析。

在下面的示例中,查询根据 CustomerID 为每位客户分配唯一的行号。

-- Assigns row numbers to customers
SELECT 
    FirstName,
    ROW_NUMBER() OVER (ORDER BY CustomerID) AS RowNum -- Assigns row numbers
FROM Customers;

在该查询中:

  • ROW_NUMBER():分配唯一行号

  • RANK():为并列值分配有间隙的名次

  • OVER():定义窗口(排序/分区)

建议查看我们的SQL 窗口函数速查表(可下载),它提供各类 SQL 窗口函数的便捷参考。另外,欢迎学习我们的SQL Server 进阶课程,了解更多在数据分析中使用 T-SQL 的方法,包括使用窗口函数汇总数据。

公用表表达式(CTE)

CTE(公用表表达式)可创建临时结果集,便于在一个查询中复用。下面的查询创建了一个美国客户的临时列表,然后从中检索数据。

-- Define a CTE
WITH CustomerCTE AS (
    SELECT FirstName, Country
    FROM Customers
    WHERE Country = 'USA' -- Filter only USA customers
)

-- Query the CTE
SELECT *
FROM CustomerCTE;

另一方面,递归 CTE 是一种特殊类型的 CTE,它在定义中引用自身,从而能够执行重复性操作。这使其非常适合处理组织架构等层级数据。

建议学习我们的SQL Server 中的层级与递归查询课程,掌握编写包含 CTE 和递归 CTE 的高级查询(含实用示例)。

临时表

临时表用于在会话期间短期存储数据。它们适合用于数据分阶段处理、简化多步转换,或在复杂查询中提升性能。

为演示 t-SQL 中临时表的工作方式,请参考以下三个查询块。第一个创建临时表,然后插入客户数据,最后在同一会话中对其进行查询。

-- Create a temporary table
CREATE TABLE #TempCustomers (
    FirstName VARCHAR(50),
    Country VARCHAR(50)
);
-- Insert data into the temporary table
INSERT INTO #TempCustomers
SELECT FirstName, Country
FROM Customers;
-- Retrieve data from the temporary table
SELECT * FROM #TempCustomers;

需要注意的是,临时表以 # 为前缀,并会在会话结束时自动删除。

T-SQL 与其他 SQL 方言对比

各 SQL 方言具有共同基础,但每种数据库系统都会加入各自的语法与功能。T-SQL 专为 Microsoft SQL Server 而设计,这也影响了它的工作方式及最佳适用场景。

T-SQL 与 PostgreSQL(PL/pgSQL)

PostgreSQL 使用 PL/pgSQL 实现过程式逻辑,与 T-SQL 相似,但语法与优势不同。下表概述了这些差异:

类别

T-SQL(SQL Server)

PostgreSQL(PL/pgSQL)

过程式语言

内置于 T-SQL

使用 PL/pgSQL

变量语法

DECLARE @count INT;

SET @count = 10;

DECLARE count INT := 10;

变量命名

使用 @ 前缀(如 @var

无前缀(如 var

块结构

更简洁,常为隐式或 BEGIN…END

显式:需要 DODECLAREBEGIN

示例代码块

标准 T-SQL 批处理

包裹于 DO $ ... $

高级数据类型

相对有限

原生支持更丰富(JSONB、数组、几何)

工具与集成

与 SQL Server 工具深度集成

跨平台更灵活

生态

优化面向 Windows、Azure、SSMS 与 Power BI

开源、跨平台

查看我们的数据库管理员的 SQL技能路径,学习如何设计关系型数据库并优化查询结构以提升性能。

T-SQL 与 MySQL

MySQL 也支持过程式 SQL,但实现更为简洁、功能相对有限。下表比较了两种方言的语法与特性差异。

类别

T-SQL(Microsoft)

MySQL

行数限制

SELECT TOP 5 * FROM Table

SELECT * FROM Table LIMIT 5

错误处理

健全的 TRY...CATCH

较为受限的 DECLARE HANDLER 语法

过程式逻辑

丰富、结构化、可编程性强

更简单、过程式功能较少

分析能力

支持窗口函数与 CTE

基础分析功能(新版本在改进)

生态系统

与 SQL Server 与企业级工具深度绑定

轻量级;LAMP 堆栈核心(Linux、Apache 等)

最佳适用场景

复杂业务逻辑与数据仓库

Web 应用与高速读操作

T-SQL 的真实世界用例

T-SQL 的应用远不止简单的数据查询。以下是我在数据工作中发现它很有用的一些场景。

报表查询

T-SQL 常用于直接从数据库生成报表。例如,您可以按区域汇总销售额,或使用窗口函数对高绩效产品进行排名。

ETL 流程(抽取、转换、加载)

数据工程师在数据管道中使用 T-SQL 准备与搬运数据。例如,从暂存表抽取数据、转换格式、清理不一致项,并加载到最终的报表表中。

数据清洗脚本

当数据库中有数百万行且地址格式不一致时,您可以使用包含 WHILE 循环或 CTE 的 T-SQL 脚本,识别重复、填补缺失值或标准化格式。

应用的后端逻辑

许多应用依赖 T-SQL 在数据库内部处理业务逻辑。您可以用存储过程执行 CRUD 操作、在插入数据前进行校验,或在关键操作中使用事务处理。

常见错误与最佳实践

尽管 T-SQL 对高级数据库查询很有帮助,但您可能会遇到一些常见问题。以下是我在使用 T‑SQL 时见到的常见错误:

  • 过度使用循环而非基于集合的逻辑: 使用 WHILE 等循环逐行处理会拖慢性能。SQL 的设计初衷是一次性处理数据集合。

  • 忽视索引: 未正确使用索引会使查询变慢,尤其在大表上。

  • 不正确使用事务: 将多个相关操作不放入事务中执行,一旦中途失败,可能导致数据不一致。

  • 忽略错误处理: 若跳过 TRY...CATCH 块,将加大调试难度,且在生产环境中可能导致脚本无声失败或出现不可预期的错误。

以下是我建议的最佳实践,可帮助您编写更高效、更可靠的查询:

  • 优先采用基于集合的查询: 尽可能使用 JOINGROUP BY 和窗口函数代替循环处理,这与 SQL Server 的高效数据处理方式相契合。

  • 编写可读、可维护的代码: 使用清晰的命名规范、保持一致的格式,并在必要处添加注释。这能提升代码的可读性,便于调试与协作。

  • 测试过程: 始终使用不同输入测试存储过程与查询,确保其正确运行并妥善处理边界情况。

结语

T-SQL 在标准 SQL 的基础上增加了编程能力,使其成为用于自动化、数据处理与分析的灵活而强大的工具。借助变量、存储过程与错误处理等功能,您可以构建更为动态高效的数据库解决方案。

接下来,我建议您学习SQL 方向的助理数据分析师职业路径,成为熟练的数据分析师。我们的SQL 报表课程也将帮助您熟练构建复杂报表。最后,建议获取我们的SQL 助理认证,展示您运用 SQL 解决业务问题的能力,从众多专业人士中脱颖而出。

T-SQL 常见问答

T-SQL 与标准 SQL 有何不同?

SQL 主要是声明式的,而 T-SQL 将声明式查询与过程式编程相结合,使您可以控制操作的执行方式。

学习 T-SQL 之前需要先学 SQL 吗?

是的,了解 SQL 的基础很重要,因为 T-SQL 直接建立在 SELECTINSERTUPDATEDELETE 等核心概念之上。

所有 SQL 方言都提供 T-SQL 吗?

不需要。T-SQL 属于微软生态,主要用于 Microsoft SQL Server 及 Azure SQL 等相关工具。

什么是存储过程?为何有用?

存储过程是在数据库内部运行的可复用 T-SQL 代码块。它们有助于提升性能、确保一致性,并简化应用逻辑。

T-SQL 中的窗口函数用于做什么?

窗口函数用于高级分析任务,如排名、运行总计,以及在不分组数据的情况下跨行比较数值。

主题

使用 DataCamp 学习 SQL

Tracks

SQL for Database Administrators

16小时
Gain the database skills you need to become a confident, high-earning SQL DBA. Learn how to create, grow, and manage your PostgreSQL database.
查看详情Right Arrow
开始课程
查看更多Right Arrow