sql编程接收一个集合

介绍 (Introduction)

Most IT professionals started their studies or careers by learning programming languages like Basic, Cobol, C, Pascal, Java and so on. Those languages produce results using a sequence of operations or procedures. For this reason, this approach is called procedural programming.

大多数IT专业人员通过学习诸如Basic,Cobol,C,Pascal,Java等编程语言来开始他们的研究或职业。 这些语言使用一系列操作或过程来产生结果。 因此,这种方法称为过程编程 。

In SQL Server, we can find an equivalent language called Transact SQL, also known as T-SQL. But SQL Server is a database engine and we can do a lot more than just tell him how to produce results: with data management instructions at our disposal like SELECT statement or Common Tabular Expressions feature, we can tell SQL Server what we want to get instead and let it deduct the « how ».

在SQL Server中,我们可以找到一种称为Transact SQL的等效语言,也称为T-SQL。 但是SQL Server是数据库引擎,我们不仅可以告诉他如何产生结果,还可以做更多的事情:利用诸如SELECT语句或Common Tabular Expressions功能之类的数据管理指令,我们可以告诉SQL Server我们想要得到什么并扣除“如何”。

As an example, if we want to list customers who bought something last week, in T-SQL, we will write a SELECT query on a Customers table, join it to an Invoices table and filter on an InvoiceDate column. In regular programming language, we would have to write a program which does everything that is performed by SQL Server database engine plus what we want to get: open Invoices and Customers list files, read it one row at a time and create the results set then close it.

举个例子,如果我们想谁买了东西上周,在T-SQL表的客户,我们将编写一个客户表的SELECT查询,它加入到发票表和过滤上InvoiceDate列。 使用常规编程语言,我们将必须编写一个程序,该程序执行SQL Server数据库引擎执行的所有工作以及我们想要获得的一切:打开“ 发票和客户”列表文件,一次读取一行并创建结果集,然后关闭它。

This means that operations in SQL Server are performed on a complete set of rows and returns a subset of the rows it manipulated.

这意味着SQL Server中的操作是在一组完整的行上执行的,并返回它所处理的行的子集。

As a SQL Server professional, we must be aware of the power of a database engine and get the best out of it, not simply see Transact SQL as another procedural language! Furthermore, if T-SQL is designed for set manipulation, we could expect performance improvement using this « set-based » approach.

作为SQL Server专业人员,我们必须意识到数据库引擎的功能并充分利用它,而不仅仅是将Transact SQL视为另一种过程语言! 此外,如果T-SQL是为集合操作而设计的,则可以期望使用这种“基于集合”的方法来提高性能。

This article is the first part of a series of three articles that will deal with set-based programming. In this article, we will focus on the simple “problem” of getting the minimum and maximum values of a column, so as its sum. We will first discuss about different T-SQL instructions and objects that we will use to actually implement solutions using both approaches. Then we will have a look at details of these implementations. While this “problem” can be easily solved by a complete T-SQL beginners, even not aware of set-based programming approach, it will help us to reveal some points of interest in building a deeper knowledge on set-based approach.

本文是有关基于集合的编程的三篇文章系列的第一部分。 在本文中,我们将重点介绍获取列的最小值和最大值及其总和的简单“问题”。 我们将首先讨论用于实际使用这两种方法实现解决方案的不同T-SQL指令和对象。 然后,我们将看一下这些实现的细节。 尽管一个完整的T-SQL初学者可以轻松地解决这个“问题”,即使他们不了解基于集合的编程方法,它也将帮助我们揭示一些兴趣点,以便对基于集合的方法进行更深入的了解。

T-SQL对象和指令 (T-SQL objects and instructions)

In this section, we will consider the instructions to be used to implement the example of this article. As explained above, this example is totally silly but it is there to pinpoint the power of SQL Server database engine, even for simple operations. By the way, this reflects what could be done applications that do not use a Database Engine.

在本节中,我们将考虑用于实现本文示例的说明。 如上所述,该示例完全是愚蠢的,但即使在进行简单操作时也可以精确地确定SQL Server数据库引擎的功能。 顺便说一句,这反映了不使用数据库引擎的应用程序可以做什么。

Procedural objects and instructions in T-SQL

T-SQL中的过程对象和指令

There are a few procedural objects and instructions that can be used by a developer to perform a given task.

开发人员可以使用一些程序对象和指令来执行给定的任务。

Firstly, we have control-flow operators that we can find in regular programming languages: WHILE, BREAK, CONTINUE, IF…ELSE, TRY…CATCH…

首先,我们有可以在常规编程语言中找到的控制流运算符: WHILE , BREAK , CONTINUE , IF ... ELSE , TRY ... CATCH ...

Secondly, there are cursors. Cursors are especially useful for applications that need to process one row at a time. It can be seen as a double linked list.

其次,有游标 。 游标对于需要一次处理一行的应用程序特别有用。 可以将其视为双链表。

Microsoft defines a T-SQL cursor as:

Microsoft将T-SQL游标定义为:

They are based on the DECLARE CURSOR syntax and are used mainly in Transact-SQL scripts, stored procedures, and triggers. Transact-SQL cursors are implemented on the server and are managed by Transact-SQL statements sent from the client to the server. They may also be contained in batches, stored procedures, or triggers.

它们基于 DECLARE CURSOR 语法,主要用于Transact-SQL脚本,存储过程和触发器中。 Transact-SQL游标在服务器上实现,并由从客户端发送到服务器的Transact-SQL语句管理。 它们也可能包含在批处理,存储过程或触发器中。

Like INT, VARCHAR and other data types, Cursors are declared in T-SQL batches. SQL Server comes with associated instructions to manage it:

与INT , VARCHAR和其他数据类型一样,游标在T-SQL批处理中声明。 SQL Server附带了相关的说明来对其进行管理:

  • OPEN to tell SQL Server to run the query and populate cursor with results set; OPEN告诉SQL Server运行查询并使用结果集填充游标;
  • CLOSE to tell SQL Server to release resources used by cursor; CLOSE指示SQL Server释放游标使用的资源;
  • FETCH to tell SQL Server to retrieve a specific row from cursor. When we use this function, we can get the outcome of FETCH instruction in @@FETCH_STATUS variable. If it’s set to 0, this means that the instruction succeeded.
  • 指示SQL Server从游标中检索特定行的FETCH 。 使用此函数时,可以在@@ FETCH_STATUS变量中获取FETCH指令的结果。 如果将其设置为0,则表示指令成功。

Set-based instructions in T-SQL

T-SQL中基于集合的指令

In T-SQL, for this set-based approach, we will use so called « aggregate functions ». These functions perform a calculation on a set of values and produce a single value.

在T-SQL中,对于这种基于集合的方法,我们将使用所谓的“ 聚合函数 ”。 这些函数对一组值执行计算并产生单个值。

Functions we will use in following example (sum, max, min) are good candidates as aggregate functions. Actually, they are implemented in SQL Server and optimized so that we could get the best out of SQL Server database engine.

我们将在以下示例中使用的函数(sum,max,min)是合计函数的良好候选者。 实际上,它们是在SQL Server中实现并进行了优化,以便我们可以充分利用SQL Server数据库引擎。

If you were to find, for instance, the total amount of time they spent on SQLShack (with the assumption that there is a table populated to keep track of user activity), you would need to use the GROUP BY instruction to tell SQL Server that you want the return of SUM aggregate function per user.

例如,如果要查找他们在SQLShack上花费的总时间(假设已填充一个表来跟踪用户活动),则需要使用GROUP BY指令来告诉SQL Server您想要每个用户返回SUM聚合函数。

Summary

摘要

As a summary, you will find below a table with the instructions and objects at our disposal to write procedural or set-based code. This table will be reviewed at the end of following articles.

作为总结,您将在下面的表格中找到说明和对象,以编写程序或基于集合的代码。 该表将在以下文章结尾处进行审核。

Procedural Approach Set-Based Approach
SELECT and other DML operations,

WHILE,
BREAK,
CONTINUE,
IF…ELSE,
TRY…CATCH…
Cursors (OPEN, FETCH, CLOSE)
DECLARE

SELECT and other DML operations,

Aggregate functions (MIN, MAX, AVG, SUM…)

程序方法 基于集合的方法
SELECT和其他DML操作,

当 ,
BREAK ,
继续 ,
如果...否则 ,
试着抓…
游标 ( OPEN , FETCH , CLOSE )
宣布

SELECT和其他DML操作,

汇总函数 (MIN,MAX,AVG,SUM…)

示例实现 (Example implementations)

In this section, we will use the instructions and objects defined above to implement a solution to the problem of getting values for min, max and sum of a given column.

在本节中,我们将使用上面定义的指令和对象来实现解决方案,以获取给定列的最小值,最大值和总和的值。

We will fist create a table and populate it with some data. Then review an example of implementation for a procedural approach and its noticeable aspects and we will do the same for set-based approach implementation. Finally, compare results and conclude.

我们将首先创建一个表,并用一些数据填充它。 然后,回顾一下过程方法及其明显方面的实现示例,对于基于集合的方法实现,我们将做同样的事情。 最后,比较结果并得出结论。

Example setup

设置示例

Let’s say we have the following table:

假设我们有下表:


CREATE TABLE #Example1 (ValueInt    INT
) ;

and populate it with random data

并用随机数据填充


INSERT INTO #Example1
SELECT ABS(CHECKSUM(NewId())) % 20
GO 10

If we take a look at its content, we will get something like this:

如果我们看一下它的内容,我们将得到如下内容:

A procedural implementation

程序执行

In regular languages, we would get the data set and loop on values to set results into variables then display these results. This is what is done in following T-SQL statement.

在常规语言中,我们将获取数据集并循环使用值以将结果设置为变量,然后显示这些结果。 这是在下面的T-SQL语句中完成的。


-- To display some timing info:
SELECT CONVERT(VARCHAR(32),GETDATE(),121) as StartTimeStamp ;
DECLARE intValues CURSOR LOCAL
FORSELECT * FROM #Example1
;DECLARE @TotalVals INT = 0;
DECLARE @MinValue  INT;
DECLARE @MaxVal    INT;
DECLARE @CurVal    INT;OPEN intValues;-- init
FETCH NEXT FROM intValues INTO @CurVal;
SET @MinValue = @CurVal;
SET @MaxVal   = @CurVal;WHILE(@@FETCH_STATUS = 0)
BEGINSET @TotalVals = @TotalVals + @CurVal;SET @MinValue  = CASE WHEN @MinValue > @CurVal THEN @CurVal ELSE @MinValue END;SET @MaxVal    = CASE WHEN @MaxVal   < @CurVal THEN @CurVal ELSE @MaxVal END;-- Carry on the loopFETCH NEXT FROM intValues INTO @CurVal;
END;CLOSE intValues;-- Display results
SELECT @TotalVals as SumOfValues,@MinValue  as MinValue,@MaxVal    as MaxValue
;-- To display some timing info:
SELECT CONVERT(VARCHAR(32),GETDATE(),121) as EndTimeStamp ;

The results should look like as follows.

结果应如下所示。

We can see that this code took 3 ms to run and provide its results. If we want to have a look on timed and IO statistics, we might run the following statement:

我们可以看到这段代码花了3毫秒来运行并提供结果。 如果要查看定时和IO统计信息,可以运行以下语句:


set statistics io on
set statistics time on

We won’t list all the output when running again the code that implements our example, but we will focus on some points that are taken out of this output. As you will see when you execute the code, there is a lot of stuff that is performed by SQL Server.

当再次运行实现示例的代码时,我们不会列出所有输出,但是我们将重点介绍从该输出中提取的一些要点。 正如您将在执行代码时看到的那样,SQL Server执行了很多工作。

First of all, SQL Server had to use CPU time to parse and compile this code.

首先,SQL Server必须使用CPU时间来解析和编译此代码。

Then, we see that, as we use a cursor, SQL Server creates a Worktable that will be scanned during execution.

于是,我们看到,当我们使用游标,SQL Server创建一个工作台 ,将在执行过程中被扫描。

Alternately, we could have used another implementation that consists in replacing cursor usages by the following query:

或者,我们可以使用另一种实现,包括通过以下查询替换游标用法:


SELECT TOP 1 @CurVal  = ValueInt
FROM #Example1
WHERE ValueInt > @ CurVal

But this won’t produce the good value for sum if table #Example1 contains multiple occurrences of a value.

但是,如果表#Example1包含多次出现的值,则这不会产生合计的好的值。

Set-based implementation

基于集合的实现

Now, let’s do it using a set-based approach and aggregate functions:

现在,让我们使用基于集合的方法和聚合函数来完成此操作:


SELECT CONVERT(VARCHAR(32),GETDATE(),121) as StartTimeStamp ;select SUM(ValueInt) as SumOfValues,MIN(ValueInt) as MinValue,MAX(ValueInt) as MaxValue
FROM #Example1
;SELECT CONVERT(VARCHAR(32),GETDATE(),121) as EndTimeStamp ;

This results to something like following screen capture:

这导致如下屏幕截图所示:

Results comparison

结果比较

And let’s compare time and IO statistics:

让我们比较时间和IO统计信息:

When comparing screenshots, we see that the actual execution time is 3 times higher in the procedural version than in set-based approach. This can be explained when we take a look at the number of operations performed by SQL Server in procedural version to produce the exact same results as in set-based version.

在比较屏幕截图时,我们发现过程版本的实际执行时间比基于集合的方法的执行时间长3倍。 当我们查看过程版本中SQL Server执行的操作数以产生与基于集的版本完全相同的结果时,可以解释这一点。

To get a better overview of performance, we could generate a bigger table than with just ten rows and compare timing and resources consumption for both implementations provided above.

为了更好地了解性能,我们可以生成比只有十行的表更大的表,并比较上述两种实现的时序和资源消耗。

Cleanups

清理工作

This ends the example and following statement will clean the temporary table we created:

到此示例结束,以下语句将清除我们创建的临时表:


DROP TABLE #Example1

结论 (Conclusion)

This article provides us further reasons to get interested in set-based programming:

本文为我们提供了更多对基于集合的编程产生兴趣的原因:

  • It’s concise and easier to read; 简洁明了,易于阅读;
  • It avoids unnecessary resource consumption, so looks promising in regards to performance. We can see in this simple example that procedural version leads to worktable creation and a lot more I/O and CPU operations than in set-based version. 它避免了不必要的资源消耗,因此在性能方面看起来很有希望。 我们可以在这个简单的示例中看到,与基于集合的版本相比,过程版本可以导致工作表的创建以及更多的I / O和CPU操作。

Now, let’s dive into real set based programming techniques and build solutions that can be very helpful!

现在,让我们深入研究基于实际集的编程技术,并构建可能非常有用的解决方案!

进一步阅读 (Further readings)

As explained in the introduction, this article is part of a series of article. Next article will consider the concept of “set” and provide an overview of the implementation of this concept in T-SQL.

如引言中所述,本文是一系列文章的一部分。 下一篇文章将考虑“集合”的概念,并概述该概念在T-SQL中的实现。

Next articles in this series:

本系列的下一篇文章:

  • From mathematics to SQL Server, a fast introduction to set theory 从数学到SQL Server,对集合论的快速介绍
  • T-SQL as an asset to set-based programming approach T-SQL是基于集合的编程方法的资产

翻译自: https://www.sqlshack.com/introduction-set-based-vs-procedural-programming-approaches-t-sql/

sql编程接收一个集合

sql编程接收一个集合_T-SQL中基于集合的程序编程方法简介相关推荐

  1. sql编程接收一个集合_T-SQL是基于集合的编程方法的资产

    sql编程接收一个集合 介绍 (Introduction) This article is the third and last one of a series of articles that ai ...

  2. [PL/SQL] 请教大家一个问题,存储过程中需要几个commit?

    查看: 10357|回复: 17 收藏    [PL/SQL] 请教大家一个问题,存储过程中需要几个commit? [复制链接]     yi888long 注册会员 精华贴数 0 专家积分 1 技术 ...

  3. 用SQL语句查询一个特定老师学生中男生女生各多少人

    用SQL语句查询一个指定老师学生中男生女生各多少人 一 表结构 学生表 教师表 关系表 SQL语句 结果 涉及知识 一 表结构 学生表 教师表 关系表 SQL语句 select count(case ...

  4. 4.编程打印一个二维数组中所有元素的和,并打印最大值,最小值(以及它们所在的行号和列号)

    /*晕呀,竟然做了一天,还不知道怎样做出来的.....*/ package HomeWork; import java.util.Arrays; /*4.编程打印一个二维数组中所有元素的和,并打印最大 ...

  5. c语言 输入n*n矩阵,C语言函数 编程输入一个n*n矩阵中各元素的值,找出两条对角线上的元素之和...

    题目: C语言函数 编程输入一个n*n矩阵中各元素的值,找出两条对角线上的元素之和 用函数怎么写 解答: #include #define N 5 void main() { \x09int matr ...

  6. 自动售货机编程_Rosmaro中基于视觉自动机的编程简介

    自动售货机编程 by Łukasz Makuch 通过ŁukaszMakuch Rosmaro中基于视觉自动机的编程简介 (An introduction to visual automata-bas ...

  7. java中的集合框架_JAVA中的集合框架(上)List

    第一节 JAVA中的集合框架概述 集合的概念,现实生活中:很多事物凑在一起就是一个集合:数学中的集合:具有相同属性事物的总体:JAVA中的集合:是一种工具类,就像是容器,储存任意数量的具有共同属性的对 ...

  8. SLAM--PL-SLAM中基于线特征的初始化方法(LSD算法,LBD描述子,计算R和t)

    SLAM中基于线特征的初始化方法 线特征的初始化 直线段检测算法---LSD:a Line Segment Detector 描述子---LBD:Line detection and descript ...

  9. linux关闭无响应文件夹,4种强制关闭Ubuntu中无响应应用程序的方法

    4种强制关闭Ubuntu中无响应应用程序的方法 在使用Ubuntu时,我们的一个或多个进程和应用程序可能会经常挂起.重新启动我们的系统并不总是最佳解决方案,我们发现自己在寻找能够快速.轻松和安全地摆脱 ...

最新文章

  1. 如何强制除法为浮点数? 除数一直舍入到0?
  2. 会计基础第一章模拟试题(1)
  3. CentOS6网卡静态IP设置
  4. Mybatis一级缓存和二级缓存 Redis缓存
  5. ORA-07445 ERROR on auto execute of job 8913
  6. 经常吃番茄对身体有什么影响?
  7. android 动态改变listview的内容
  8. python做图片浏览器_保护隐私,用Python打造自己的照片浏览器
  9. 安卓mysql类库_Android 链接mysql数据库
  10. Intel Optane P4800X评测(序):不用缓存和电容保护的SSD?
  11. Win11系统使用DISM命令备份驱动程序的方法
  12. 傻瓜攻略(二)——MATLAB数据挖掘之Apriori算法实现
  13. 利用Python进行数据分析(Ⅳ)
  14. php frameset不显示,php加载frameset页面时显示空白怎么办_后端开发
  15. react 打包体积过大_create-react-app andt 打包的 js 文件过大
  16. 威廉.大内的Z理论(1981)--轉載
  17. 前辈们的网络攻城狮心得
  18. 【UmiJS 3.x入门】
  19. 一、在PyCharm上直接调试py脚本
  20. 史上最详细的自动驾驶汽车技术介绍【硬件+软件】

热门文章

  1. java 多线程,线程安全等定义
  2. Spring Cloud入门一 Eureka Server
  3. 数据库管理软件的由来
  4. 小股神助A股股民畅享经济发展红利
  5. .net系统自学笔记——数组
  6. 算法题003 斐波那契(Fibonacci)数列
  7. ASP.NET AjaxPro的应用 .AjaxPro使用中“XXX未定义”的一种解决方法(转载的)
  8. 疯狂的Web应用开源项目
  9. 零基础带你学习计算机网络—(四)
  10. diybox路由器设置教程_家庭无线路由器怎么设置 家庭无线路由器设置教程【详细方法】...