一位在IT行业拥有20年工作经验的顾问,并且具有Web,数据库和云服务的独特知识,可以将您的业务提升到一个新的水平
  • 商务解决方案
  • 数据库咨询服务
    • 报告
      • Claytabase Server Disk IOPs Calculator
      • SQL代码备份
      • SQL打印机
    • 技术文章
      • SQL-Server
      • SQL Server 2008的维护计划
      • 使用SQL Server函数
      • 使用SQL Server日期
      • 使用SQL Server透视-取消透视
  • 网站设计
    • 怀特岛
    • 技术文章
      • ASP-NET
      • CSS
    • 网站安全
  • 产品展示
  • 社交媒体
  • 关于我们
    • 投资组合
    • 球队
      • 切斯特Copperpot
  • 学院
عربى (AR)čeština (CS)Deutsch (DE)English (EN-GB)English (EN-US)Español (ES)فارسی (FA)Français (FR)हिंदी (HI)italiano (IT)日本語 (JA)polski (PL)Português (PT)русский (RU)Türk (TR)中国的 (ZH)

SQL Server函数简介,其优缺点

任何编写良好的数据库都将具有多种功能,大多数情况下它们都是有用的,但是如果在错误的上下文中使用它们,则实际上会损害性能。

什么是SQL函数?

使用SQL Server函数

使用T-SQL或CLR(公共语言运行时)例程,SQL Server函数可用于返回单个(定标)值或表,并且执行的计算量通常会比一般代码中要复杂的多。

什么时候使用函数而不是内联代码是一个好主意?

善用

函数可用于替换视图(返回表),作为表中的计算列,执行一致的查找操作或仅用于模块化代码以帮助减少所需的更改。

不良使用

我们一直在看到它,但是当您处理大型数据集时,不应使用函数代替联接来返回查找数据。即使每一行都已经遇到了该值,它也会调用相同的函数。在这些情况下,请使用联接。

定标器功能示例

Scaler函数最适合用于执行诸如基于行的重新格式化或计算之类的逻辑,因为按其性质,每行都会调用它们,它们可用于在另一个表中查找数据,但是通常,通过使用,可以获得更好的性能一个联接。为此,我们可以在以下链接上查看我们的年龄函数。

在他们填写表格时存储某人的年龄是没有意义的,因为稍后查询数据时将过时。更好的选择是捕获出生日期并即时对其进行计算。在我们的函数中,我们添加了一个字段直到,可以用来追溯计算的日期,或者更确切地说,可以计算出死亡的时间(此功能已扩展为NHS合同)。

更多:获取年龄

Example

CREATE FUNCTION [Dates].[GetAge](@Date DATETIME2,@Until DATETIME2) RETURNS INT AS BEGINIF @Until IS NULL SET @Until=CONVERT(DATE,GETDATE())DECLARE @Age INT=DATEDIFF(YEAR,@Date,@Until)+(CASE WHEN DATEPART(DAYOFYEAR,@Date)>(DATEPART(DAYOFYEAR,@Until)+(CASE WHEN dbo.GetLeapYear(@Date)=1 AND DATEPART(DAYOFYEAR,@Date)>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END)RETURN @AgeEND

定标器功能示例

要从虚构表中使用此表,我们只需使用该表即可提供当前年龄或死亡年龄。

Use in a select statement

SELECT [PersonID],[DateOfBirth],[dbo].[GetAge]([DateOfBirth],[DeceasedDate]) AgeAsFunction,--Simpler code to understand!DATEDIFF(YEAR,[DateOfBirth],[DeceasedDate])+(CASE WHEN DATEPART(DAYOFYEAR,[DateOfBirth])>(DATEPART(DAYOFYEAR,[DeceasedDate])+(CASE WHEN dbo.GetLeapYear([DateOfBirth])=1 AND DATEPART(DAYOFYEAR,[DateOfBirth])>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END) AgeAsScript,[DeceasedDate]FROM [Person]

定标器功能示例

优点:一致,模块化,更紧凑,有可能减少更改次数

缺点:要查看代码,您需要在函数中查找

尽管通常有用,但此功能也非常精确,因为它利用了year年功能。它本质上是不确定的,因此永远不应将其存储为持久性数据。

表格栏示例

可以将已计算的列添加为持久性(数据时发生更改)或不持久性(每次选择该行时计算)。我们可以看看在内容管理系统中使用它们的两种方式。

注意:持久数据可能很难实现,因为它需要满足一组约束

非持久性:年龄

使用上面的age函数,我们可以将它添加到表中并从其他列中传递值。然后,我们只需将其选择为列即可。

Add to a table

CREATE TABLE [Person]([PersonID] [int] IDENTITY(1,1) NOT NULL,[DateOfBirth] [datetime] NULL,[Age] AS ([dbo].[GetAge]([DateOfBirth],[DeceasedDate])),[DeceasedDate] [datetime] NULL)

Select Statement

SELECT [PersonID],[DateOfBirth],[Age] AgeAsColumn,--Even simpler code to understand!DATEDIFF(YEAR,[DateOfBirth],[DeceasedDate])+(CASE WHEN DATEPART(DAYOFYEAR,[DateOfBirth])>(DATEPART(DAYOFYEAR,[DeceasedDate])+(CASE WHEN dbo.GetLeapYear([DateOfBirth])=1 AND DATEPART(DAYOFYEAR,[DateOfBirth])>59 THEN 1 ELSE 0 END))THEN -1 ELSE 0 END) AgeAsScript,[DeceasedDate]FROM [Person]

非持久性:年龄

优点:一致,模块化

缺点:不需要时会降低查询速度。

持续:精简的CSS

我们有一个功能,可将CSS所需的空间减少多达30%。定期调用它会减慢表的选择速度,并且由于很少更新数据,因此在插入/更新时执行计算是有意义的。通过将列创建为函数,我们也无需将这些操作作为触发器执行。

更多:SQL中的CSS预处理器

Add to a Table

CREATE TABLE CSS(CSSID INT IDENTITY(1,1) NOT NULL,CSSText NVARCHAR(MAX),CSSMin AS (ous.CSSProcessor([CSSText])) PERSISTED)

持续:精简的CSS

可以像选择普通列一样选择它,并且数据存储在表中。它还避免了使用大量的replace语句使我们的代码code肿。

优点:一致,模块化,更快的选择速度,无需扳机!

缺点:增加了桌子所需的空间,降低了插入速度

更换视图

除了在多个地方定期使用相同的联接之外,我们通常不使用视图。

即使在这些情况下,也没有理由不能更有效地使用表函数。我们使用的表可以在下面的链接上找到,我们有两个用法示例,一个通过函数,另一个通过视图。

更多:使用SQL Server日期

Create a function

CREATE FUNCTION Dates.GetCalender(@DateFrom DATETIME2,@DateTo DATETIME2,@Function INT) RETURNS @D TABLE (CalenderDate DATETIME2(7) NOT NULL PRIMARY KEY,CalenderCA INT NULL,CalenderCD INT NULL,WeekDayID INT NULL,WeekDayName VARCHAR(9) NULL,HolidayType NVARCHAR(100)) AS BEGININSERT INTO @DSELECT c.*,HolidayTypeFROM [Utilities].[Dates].[Calender] cLEFT JOIN Utilities.Dates.CalenderHolidays h ON h.CalenderDate=c.CalenderDate AND CalenderFunction=@FunctionWHERE c.CalenderDate BETWEEN @DateFrom AND @DateTo RETURNENDGO

Create a view

CREATE VIEW Dates.GetCalenderView ASSELECT c.CalenderDate, CalenderCA, CalenderCD, WeekDayID, WeekDayName,h.HolidayType,c.CalenderFunctionFROM (SELECT CalenderDate, CalenderCA, CalenderCD, WeekDayID, WeekDayName, CalenderFunction FROM [Utilities].[Dates].[Calender],(SELECT DISTINCT CalenderFunction FROM Dates.CalenderHolidays) x) cLEFT JOIN Utilities.Dates.CalenderHolidays h ON h.CalenderDate=c.CalenderDate AND h.CalenderFunction=c.CalenderFunction

Usage

SELECT * FROM Dates.GetCalender('2018-01-01','2018-12-31',0) --England & WalesSELECT * FROM Dates.GetCalender('2018-01-01','2018-12-31',1) --Scotland----OR----SELECT * FROM Dates.GetCalenderView WHERE CalenderDate BETWEEN '2018-01-01' AND '2018-12-31' AND CalenderFunction=0

更换视图

好处:调用紧凑,带有主键(非常适合进一步联接)返回,可以在代码的早期使用参数。

缺点:要构建的代码较多,灵活性较差

用于申请联接

表函数非常适合在“应用联接”中使用,因为可以逐行传递数据。我们使用TextToRows函数在SQL Server中将字符串分开。在下面的示例中,我们使用了double apply来使用不同的定界符将数据拆分两次。

更多:SQL Server函数将文本拆分为数据行

SQL Code

DECLARE @TestText TABLE(TextToSplit NVARCHAR(100))INSERT INTO @TestText SELECT 'Text,To,Tows:Split,One'INSERT INTO @TestText SELECT 'Text,To,Tows:Split,Two'SELECT t.TextToSplit,s1.WordInt,s1.WordStr,s2.WordInt,s2.WordStrFROM @TestText tOUTER APPLY dbo.TextToRows(':',TextToSplit) s1OUTER APPLY dbo.TextToRows(',',WordStr) s2

Further detail

Some of the functions we have written can be found below.

दो अक्षांश अक्षांश निर्देशांक के बीच की दूरी की गणना करें

创建一个SQL函数,以英里或公里为单位计算纬度/经度坐标之间的距离

串联列

灵活且可重复使用的SQL Server函数,用于从一组列或变量中返回格式化和定界的文本字符串

函数返回月份的特定日期

SQL Server 2008,返回特定日期的功能

列的最小值和最大值

创建一个函数,以通过串联字符串,将它们拆分为行然后返回正确的值来返回列的最小值和最大值

功能拆分成文本行的数据在SQL Server 2008

SQL Server函数,用于将由任何字符分隔的文本字符串列表拆分为数据行。用作许多其他功能的基础

在SQL卸妆文本字符串保存字母和数字

创建一个函数来清除不在SQL Server中的0-9或AZ之间的所有字符的文本字符串

检查电话号码是正确的英国格式与SQL Server 2008

创建一个SQL Server函数以检查和清除基于国际或英国的电话号码字符串

添加文字填充

这个简单的小函数在我们的各种数据库中广泛使用,并为我们提供了一种保证字符串格式的好方法。

英国地址邮政编码在SQL Server 2008中的清洁

创建一个SQL Server函数以清除,替换常见错误并使用正确的空格位置重新格式化UK邮政编码
Copyright Claytabase Ltd 2020

Registered in England and Wales 08985867

RSSLoginLink 联系我们Cookie政策网站地图

Social Media

facebook.com/Claytabaseinstagram.com/claytabase/twitter.com/Claytabaselinkedin.com/company/claytabase-ltd

Get in Touch

+442392064871info@claytabase.comClaytabase Ltd, Unit 3d, Rink Road Industrial Estate, PO33 2LT, United Kingdom
此网站上的设置设置为允许所有Cookie。 这些可以在我们的Cookie政策和设置页面上更改。继续使用本网站即表示您同意使用Cookie。
Ousia Logo
Logout
Ousia CMS Loader