zoukankan      html  css  js  c++  java
  • SQL Server表值函数

    GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
    https://cnsendnet.taobao.com
    来自森大科技官方博客
    http://www.cnsendblog.com/index.php/?p=1966

    表值函数

    表值函数提供强大的结果集生成能力。它可以在查询内部表或视图允许的任何地方使用。表值函数在使用上比返回一个结果集的存储过程更灵活,因为函数的结果集可以联接到查询中的其他表。

    SQL Server中有两种表值函数。内联表值函数在概念上与带参数的视图类似。多语句表值函数允许多条语句在表变量中创建结果集来返回。

    1. 内联表值函数

    创建内联表值函数很简单。内联表值函数的内容是一条带参数的SELECT语句。返回数据类型永远是表,不过返回表的结构由SELECT语句的结构来定义。下面是内联表值函数的一个例子,检索给定CustomerID的商品销售总量。

    1. USE AdventureWorks2008; 
    2. GO 
    3. CREATE FUNCTION Sales.ufnSalesByCustomer (@CustomerID int) 
    4. RETURNS TABLE 
    5. AS 
    6. RETURN 
    7.  SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS Total  
    8. FROM Production.ProductAS P     

    10.JOIN Sales.SalesOrderDetailAS SD  

    1. ON SD.ProductID = P.ProductID     

    12.JOIN Sales.SalesOrderHeaderAS SH     

    13.ON SH.SalesOrderID = SD.SalesOrderID  

    14.WHERE SH.CustomerID = @CustomerID  

    15.GROUP BY P.ProductID, P.Name 

    16.); 

    17.GO

    注意,函数体由一条RETURN语句组成。使用这个函数的一个例子如下所示:

    1. SELECT * FROM Sales.ufnSalesByCustomer(30052);

    内联表值函数功能强大,在要求参数化查询的情况下值得考虑。它们在结果集如何使用上提供更多的灵活性。

    2. 多语句表值函数

    多语句表值函数允许多条语句来创建表的内容。多语句表值函数可以用来替换使用多个步骤来构建结果集的存储过程。

    多语句表值函数允许开发人员使用多个步骤动态地填充表,这一点与存储过程类似,不过它们可以在SELECT语句中像表那样被引用。

    使用多语句表值函数时,表的结构必须在函数头定义。要为表使用一个变量名,并且所有修改数据的操作只能引用表变量。

    下面的例子是一个函数,类似上一节中创建的ufnSalesByCustomer。首先创建表变量,然后使用刚才创建的标量函数来更新表变量,让它包含总的存货清单。创建函数的语句如下所示:

    1. USE AdventureWorks2008; 
    2. GO 
    3. CREATE FUNCTION Sales.ufnSalesByCustomerMS (@CustomerID int) 
    4. RETURNS @table TABLE 
    5. ( ProductID int PRIMARY KEY NOT NULL,  
    6. ProductName nvarchar(50) NOT NULL, 
    7.  TotalSales numeric(38,6) NOT NULL, 
    8.  TotalInventory int NOT NULL ) 
    9. AS 

    10.BEGIN 

    11. INSERT INTO @table 

    12. SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS Total, 0  

    13.FROM Production.ProductAS P  

    14.JOIN Sales.SalesOrderDetailSD ON SD.ProductID = P.ProductID  

    15.JOIN Sales.SalesOrderHeader SH ON SH.SalesOrderID = SD.SalesOrderID  

    16.WHERE SH.CustomerID = @CustomerID  

    17.GROUP BY P.ProductID, P.Name;  

    18.

    19.UPDATE @table  

    20.SET TotalInventory = dbo.ufnGetTotalInventoryStock(ProductID);  

    21.

    22.RETURN; 

    23.END;

    执行这个函数与执行前面的内联函数一样:

    1. SELECT * FROM Sales. ufnSalesByCustomerMS (30052);

    -------------------------------------------------------------------------------------

    表值函数和标量值函数的不同是 表值函数是返回一个Table类型 Table类型相当与一张存储在内存中的一张虚拟表.

    表值函数的语法:

    CREATE FUNCTION [ schema_name. ] function_name
    ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
        [ = default ] }
        [ ,...n ]
    ]
    )
    RETURNS TABLE
        [ WITH <function_option> [ ,...n ] ]
        [ AS ]
        RETURN [ ( ] select_stmt [ ) ]
    [ ; ]

    现在来写一个比较实用的表值函数..

    写一个切割字符串的表值函数

    view plaincopy to clipboardprint?
    --------------------------这个函数用来切割字符串的-----------------  
    --函数的参数 第一个是要切割的字符串 第二个是要以什么字符串切割  
    CREATE FUNCTION Split(@Text NVARCHAR(4000),@Sign NVARCHAR(4000))  
    RETURNS @tempTable TABLE(id INT IDENTITY(1,1) PRIMARY KEY,[VALUE] NVARCHAR(4000))  
    AS  
    BEGIN  
        DECLARE @StartIndex INT                --开始查找的位置  
        DECLARE @FindIndex INT                --找到的位置  
        DECLARE @Content    VARCHAR(4000)    --找到的值  
        --初始化一些变量  
        SET @StartIndex = 1 --T-SQL中字符串的查找位置是从1开始的  
        SET @FindIndex=0  
          
        --开始循环查找字符串逗号  
        WHILE(@StartIndex <= LEN(@Text))  
        BEGIN  
            --查找字符串函数 CHARINDEX 第一个参数是要找的字符串  
            --                            第二个参数是在哪里查找这个字符串  
            --                            第三个参数是开始查找的位置  
            --返回值是找到字符串的位置  
            SELECT @FindIndex = CHARINDEX(@Sign,@Text,@StartIndex)  
            --判断有没找到 没找到返回0  
            IF(@FindIndex =0 OR @FindIndex IS NULL)  
            BEGIN
                --如果没有找到者表示找完了  
                SET @FindIndex = LEN(@Text)+1  
            END
            --截取字符串函数 SUBSTRING 第一个参数是要截取的字符串  
            --                            第二个参数是开始的位置  
            --                            第三个参数是截取的长度  
            --@FindIndex-@StartIndex 表示找的的位置-开始找的位置=要截取的长度  
            --LTRIM 和 RTRIM 是去除字符串左边和右边的空格函数  
            SET @Content = LTRIM(RTRIM(SUBSTRING(@Text,@StartIndex,@FindIndex-@StartIndex)))  
            --初始化下次查找的位置  
            SET @StartIndex = @FindIndex+1  
            --把找的的值插入到要返回的Table类型中  
            INSERT INTO @tempTable ([VALUE]) VALUES (@Content)   
        END  
        RETURN  
    END
    --------------------------这个函数用来切割字符串的-----------------
    --函数的参数 第一个是要切割的字符串 第二个是要以什么字符串切割
    CREATE FUNCTION Split(@Text NVARCHAR(4000),@Sign NVARCHAR(4000))
    RETURNS @tempTable TABLE(id INT IDENTITY(1,1) PRIMARY KEY,[VALUE] NVARCHAR(4000))
    AS
    BEGIN
         DECLARE @StartIndex INT                --开始查找的位置
         DECLARE @FindIndex INT                --找到的位置
         DECLARE @Content    VARCHAR(4000)    --找到的值
         --初始化一些变量
         SET @StartIndex = 1 --T-SQL中字符串的查找位置是从1开始的
         SET @FindIndex=0
        
         --开始循环查找字符串逗号
         WHILE(@StartIndex <= LEN(@Text))
         BEGIN
             --查找字符串函数 CHARINDEX 第一个参数是要找的字符串
             --                            第二个参数是在哪里查找这个字符串
             --                            第三个参数是开始查找的位置
             --返回值是找到字符串的位置
             SELECT @FindIndex = CHARINDEX(@Sign,@Text,@StartIndex)
             --判断有没找到 没找到返回0
             IF(@FindIndex =0 OR @FindIndex IS NULL)
             BEGIN
                 --如果没有找到者表示找完了
                 SET @FindIndex = LEN(@Text)+1
             END
             --截取字符串函数 SUBSTRING 第一个参数是要截取的字符串
             --                            第二个参数是开始的位置
             --                            第三个参数是截取的长度
             --@FindIndex-@StartIndex 表示找的的位置-开始找的位置=要截取的长度
             --LTRIM 和 RTRIM 是去除字符串左边和右边的空格函数
             SET @Content = LTRIM(RTRIM(SUBSTRING(@Text,@StartIndex,@FindIndex-@StartIndex)))
             --初始化下次查找的位置
             SET @StartIndex = @FindIndex+1
             --把找的的值插入到要返回的Table类型中
             INSERT INTO @tempTable ([VALUE]) VALUES (@Content)
         END
         RETURN
    END

    这个函数的作用就是类似.Net中的string类的Split方法

    现在来测试这个函数

    这个函数返回的是Table类型   所以可以用下面的语法来调用

    view plaincopy to clipboardprint?
    SELECT * FROM dbo.Split('a,b,c,d,e,f,g',',')
    SELECT * FROM dbo.Split('a,b,c,d,e,f,g',',')

    得到的结果

    GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
    https://cnsendnet.taobao.com
    来自森大科技官方博客
    http://www.cnsendblog.com/index.php/?p=1966

  • 相关阅读:
    Java IO流
    博客园禁止pc端以及手机端选中复制粘贴
    eclipse debug模式出现 source not found
    Winform之跨线程访问控件(在进度条上显示字体)
    WPF中DataGrid的ComboBox的简单绑定方式(绝对简单)
    WPF制作QQ列表(仿qq列表特效)
    WPF柱状图(支持数据库动态更新)之组件的数据动态化
    WPF柱状图(支持数据库动态更新)
    WPF仿微软事件和属性窗体,效果更炫!
    DataGrid缓冲加载数据
  • 原文地址:https://www.cnblogs.com/cnsend/p/15415352.html
Copyright © 2011-2022 走看看