第十四篇 SQL游标、函数的使用方法

游标的的使用有日常的开发和维护的过程不使用的并不多,但是碰到一些棘手的问题的时候,游标时常是个非常好的帮手,下面就说下游标的使用方法,方法自己以后查阅,和加深一些印象,下面以一个存储过程为例

 T-SQL中的游标定义在MSDN中如下:

DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
     [ FORWARD_ONLY | SCROLL ]
     [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
     [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
     [ TYPE_WARNING ]
     FOR select_statement
     [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
ALTER PROCEDURE [dbo]. [XXXX]
    @ProcessName NVARCHAR (20) ---流程名
AS
    DECLARE @tempIncident INT
    DECLARE @tempCode NVARCHAR( 20)
    DECLARE @incident NVARCHAR( 100) ---实例号
    DECLARE @bicode NVARCHAR( 200)--- 单号
    DECLARE @taskCnt INT ---task为的数量
    DECLARE @flag INT
    DECLARE @bflag INT
    SET @flag = 0
    SET @bflag = 0

    ----定义一个游标--
    ----定义游标和定义一个变量是差不多的,不过后面要指定一个的查询语句,
    DECLARE mycur CURSOR
    FOR
        ( SELECT     bic. BI_Code ,----这时两个的数据是要使用的数据
                    bic.BI_Incident
          FROM    xxxxx AS inc ,
                    bic AS bic
          WHERE     inc .PROCESSNAME = bic .BI_ProcessName
                    AND INCIDENT = bic.BI_Incident
                    AND PROCESSNAME = @ProcessName
                    AND inc .STATUS = 2
                    AND ( bic. BI_AuditState = 4010
                          OR bic .BI_AuditState = 4040
                        )
        )
    OPEN mycur--打开这个游标

    FETCH NEXT FROM mycur INTO @tempCode, @tempIncident ---把值放到变量中
      --循环这个值
      --这是一个系统的取游标值的一个变量
    WHILE @@FETCH_STATUS = 0
        BEGIN
            SELECT  @taskCnt = COUNT(*)
            FROM    xxxxx
            WHERE   INCIDENT = @tempIncident
                    AND PROCESSNAME = @ProcessName
                    AND STATUS = 1

            IF @taskCnt > 0 ---有task=1 的数据则是可以自动处理的
                BEGIN
                    IF @flag = 0
                        BEGIN
                            SET @incident = CAST(@tempIncident AS NVARCHAR)
                        END
                    ELSE
                        SET @incident = @incident + ‘,‘
                            + CAST (@tempIncident AS NVARCHAR )
                    SET @flag = 1
                END

            ELSE
                BEGIN
                    IF @bflag = 0
                        SET @bicode = @tempCode
                    ELSE
                        SET @bicode = @bicode + ‘,‘ + @tempCode
                    SET @bflag = 1
                END
             ---这里的是把数据再次放到变量里面,以便循环的使用
            FETCH NEXT FROM mycur INTO @tempCode, @tempIncident
        END
    CLOSE mycur
    DEALLOCATE mycur
    IF @bicode IS NULL
        SET @bicode = ‘NULL‘
    IF @incident IS NULL
        SET @incident = ‘NULL‘
    ELSE
        UPDATE  xxxxx
        SET     STATUS = 1
        WHERE   PROCESSNAME = @ProcessName
                AND INCIDENT IN ( SELECT     value
                                  FROM      dbo .fn_Split( @incident, ‘,‘) )

SQL 函数的使用:

函数在SQL中的使用提高了SQL代码的重复利用,也方便我们更高效的去用SQL做更多的事:下面我就对标量的函数进行说明,其它的东西也基本上是大同小异.

1、标量函数

Create function 函数名(参数)

Returns 返回值数据类型

[with {Encryption | Schemabinding }]

[as]

begin

SQL语句(必须有return 变量或值)

例如:

ALTER FUNCTION [dbo]. [fn_Split](@sText varchar( 8000), @sDelim varchar(20 ) = ‘ ‘)
RETURNS @retArray TABLE (idx smallint Primary Key, value varchar(8000 ) COLLATE SQL_Latin1_General_CP1_CI_AS )

这样就是把一个函数的基本形式定义好了 如同在代码中写出 public string get(){}

后面的代码也就是日常的sql查询或者是一些的特殊的处理

ALTER   FUNCTION [dbo]. [fn_Split](@sText varchar( 8000), @sDelim varchar(20 ) = ‘ ‘)
 RETURNS @retArray TABLE (idx smallint Primary Key, value varchar(8000 ) COLLATE SQL_Latin1_General_CP1_CI_AS )
 AS
 BEGIN
 DECLARE @idx smallint ,
  @value varchar(8000 ),
  @bcontinue bit,
  @iStrike smallint,
  @iDelimlength tinyint

IF @sDelim = ‘Space‘
 BEGIN
 SET @sDelim = ‘ ‘
 END

SET @idx = 0
SET @sText = LTrim(RTrim (@sText))
SET @iDelimlength = DATALENGTH(@sDelim )
SET @bcontinue = 1

IF NOT ((@iDelimlength = 0 ) or (@sDelim = ‘Empty‘))
 BEGIN
 WHILE @bcontinue = 1
  BEGIN
  --If you can find the delimiter in the text, retrieve the first element and
   --insert it with its index into the return table.
    IF CHARINDEX (@sDelim, @sText)> 0
    BEGIN
    SET @value = SUBSTRING(@sText ,1, CHARINDEX( @sDelim,@sText )-1)
     BEGIN
     INSERT @retArray (idx , value )
     VALUES (@idx , @value )
     END

    --Trim the element and its delimiter from the front of the string.
    --Increment the index and loop.
    SET @iStrike = DATALENGTH(@value ) + @iDelimlength
    SET @idx = @idx + 1
    SET @sText = LTrim(Right(@sText ,DATALENGTH( @sText) - @iStrike ))

    END
   ELSE
    BEGIN
    --If you can’t find the delimiter in the text, @sText is the last value in
    --@retArray.
      SET @value = @sText
     BEGIN
     INSERT @retArray (idx , value )
     VALUES (@idx , @value )
     END
    --Exit the WHILE loop.
    SET @bcontinue = 0
    END
   END
  END
 ELSE
  BEGIN
  WHILE @bcontinue=1
   BEGIN
   --If the delimiter is an empty string, check for remaining text
   --instead of a delimiter. Insert the first character into the
   --retArray table. Trim the character from the front of the string.
   --Increment the index and loop.
   IF DATALENGTH(@sText )>1
    BEGIN
    SET @value = SUBSTRING(@sText ,1, 1)
     BEGIN
     INSERT @retArray (idx , value )
     VALUES (@idx , @value )
     END
    SET @idx = @idx+1
    SET @sText = SUBSTRING(@sText ,2, DATALENGTH(@sText )-1)

    END
   ELSE
    BEGIN
    --One character remains.
    --Insert the character, and exit the WHILE loop.
    INSERT @retArray (idx , value )
    VALUES (@idx , @sText )
    SET @bcontinue = 0
    END
  END

 END

 RETURN
 END
时间: 2024-11-10 01:16:22

第十四篇 SQL游标、函数的使用方法的相关文章

解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

原文:解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) 解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究vardecimals 是怎麽存储在磁盘上的. 作为一般的介绍vardecimals 是怎样的,什么时候应该使用,怎样使用,参考这篇文章 vardecimal 存储格式启用了吗? 首先,我们需要看一下vardecim

第十四篇 Integration Services:项目转换

本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业智能工具(SSDT-BI)或Visual Studio 2012将我们的第一个SSIS项目转换为SSIS 2012.为什么你想升级我们的SSIS项目到2012?你可能想使用SSIS 2012中的新特性.你可能还希望利用SSIS 2012目录.要使用目录,你的项目必须遵循项目部署模型,我们也将在这篇文

NHibernate 存储过程 第十四篇

NHibernate 存储过程 第十四篇 NHibernate也是能够操作存储过程的,不过第一次配置可能会碰到很多错误. 一.删除 首先,我们新建一个存储过程如下: CREATE PROC DeletePerson @Id int AS DELETE FROM Person WHERE PersonId = @Id; 修改映射文件,添加删除对象的存储过程: <?xml version="1.0" encoding="utf-8" ?> <hiber

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

Egret入门学习日记 --- 第六十四篇(书中 19.4 节 内容)

第六十四篇(书中 19.4 节 内容) 昨天的问题,是 images 库自己本身的问题. 我单独使用都报错. 这是main.js文件代码: let images = require("images"); console.log(images); 这是cmd运行命令历史: Microsoft Windows [版本 10.0.16299.15] (c) 2017 Microsoft Corporation.保留所有权利. C:\Users\Administrator\Desktop\a&

第十四篇 现象

第十四篇  现象 "现象"的产生是由宇宙当中各种因素交汇的结果.现象是万物在宇宙中的展现,它可以被人为创造,也可以由宇宙规律自行产生.现象能帮助人类逐步地了解宇宙的本质,也能帮助人类更好地了解自己. 当一个生命对宇宙有足够高度的认识之后就会留意所有的现象,并从这些现象当中去探索自身以及宇宙的奥秘.可以说,生命的成长过程就是不断地分析与探索各种现象,从而总结经验,让自身不断提高探索宇宙奥秘能力的一个历练过程. 随着对各种现象的不断分析与探索,人类会越来越深刻地认识到现象背后的本质,而不会

第二十四节,自定义函数

第二十四节,自定义函数函数是将要实现的功能写在函数里,在要使用此功能的地方调用此函数即可实现功能,这样大大减少编程重复书写同样的代码,在多个要使用同样功能的地方调用函数即可不需要重复写同样的代码函数式编程最重要的是增强代码的重用性和可读性 函数的定义主要有如下要点: def:表示函数的关键字函数名:函数的名称,日后根据函数名调用函数函数体:函数中进行一系列的逻辑计算,如:发送邮件.计算出 [11,22,38,888,2]中的最大数等...参数:为函数体提供数据return:返回值:当函数执行完毕

mysql第四篇--SQL逻辑查询语句执行顺序

mysql第四篇--SQL逻辑查询语句执行顺序 一.SQL语句定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condition&g

Egret入门学习日记 --- 第二十四篇(书中 9.12~9.15 节 内容)

第二十四篇(书中 9.12~9.15 节 内容) 开始 9.12节 内容. 重点: 1.TextInput的使用,以及如何设置加密属性. 操作: 1.TextInput的使用,以及如何设置加密属性. 创建exml文件,拖入组件,设置好id. 这是显示密码星号处理的属性. 创建绑定类. 实例化,并运行. 但是焦点在密码输入框时,密码是显示的. 暂时不知道怎么设置 “焦点在密码框上时,还是显示为 * 号” 的方法. 至此,9.12节 内容结束. 开始 9.13节 . 这个,和TextInput的使用