zoukankan      html  css  js  c++  java
  • 组合、拆分字符串,通过事务执行批量操作

    从数据的组合拆分入手,逐渐引申到事务:

    首先列表页选中一系列字符串,准备批量操作:

                $('#btnCheck').click(function () {

                    var i = 0;

                    var tmpSelAsset = '';

                    //获取所有被选中的标签元素

                    var checked = $("input[name='defaultAssetInfo']:checked");

                    //将所有被选中的标签的值保存成一个字符串,以“$”隔开

                    for (i = 0; i < checked.length; i++) {

                        if (i < checked.length - 1)

                            tmpSelAsset += checked[i].value + '$';

                        else

                            tmpSelAsset += checked[i].value;

                    }

                    var revalue = "";

                    var ajaxUrl = "";

                    var mContractCode = document.getElementById("ContractCode").value;

                    ajaxUrl = "<%=RequestHelper.GetParentUrlOfCurrentPage() %>SaveShopInfo.aspx?Action=add&ContractCode=" + mContractCode + "&ShopCodes=" + tmpSelAsset;

                    revalue = doSubmitForm("curForm", ajaxUrl);

                    if (retValue.length > 0) {

                        var arrMsg = retValue.split('|');

                        var status = arrMsg[0];

                        var strmsg = arrMsg[1];

                      

                        if (status == '100' || status == '103') {

                            location.href = "<%=Request.Url.ToString()%>";

                        }

                    }

                    parent.closeDialog();

                });

    //保存相对应字符串,并将合同编号和选中的商铺编号传值传过去:

      if(mAction=="add")

        {

           

            mDicInputParam.Add(new DbParam("Action", "add"));

            mDicInputParam.Add(new DbParam("ShopCodes", mShopCodes));

            mDicInputParam.Add(new DbParam("ContractCode", mContractCode));

            int rValue = AgileCorpDataService.ExecuteDataFunction("contract100111", mDicInputParam, out mDicSysParam);

            mStatus = DbParamHelper.DbParamValue<int>(mDicSysParam, "Status", -1);

            mRetValue = DbParamHelper.DbParamValue<String>(mDicSysParam, "Status","");

     

        }

        else

        {

            mDicInputParam.Add(new DbParam("Action", "delete"));

            mDicInputParam.Add(new DbParam("ShopCodes", mShopCodes));

            mDicInputParam.Add(new DbParam("ContractCode", mContractCode));

            int rValue = AgileCorpDataService.ExecuteDataFunction("contract100111", mDicInputParam, out mDicSysParam);

            mStatus = DbParamHelper.DbParamValue<int>(mDicSysParam, "Status", -1);

            mRetValue = DbParamHelper.DbParamValue<String>(mDicSysParam, "Status", "");

        }

    重点还是在存储过程当中:

    注:1.在理解的过程中,便于讲解,我将类似于“@pi_arrCount的值等于N”简写成“arrCount的值是N

       2.解释一般在执行语句之前,所以,执行语句执行的结果我在解释当中就已经阐述了

    Contract100111:

    单看Add的这个操作

    CREATE PROCEDURE Asset_spExecuteContractShopInfo

    (

             @pi_Action VARCHAR(100),

        @pi_ShopCodes varchar(8000),

             @pi_ContractCode varchar(100),

             @po_Status int output,

        @po_RetValue varchar(200) output

    )

      

    as  

    --声明三个变量

                       DECLARE @pt_arrCount INT

                       DECLARE @pt_Index INT

                       DECLARE @pt_ShopCode VARCHAR(100)

    --最后得到的@pt_arrCount肯定是个值,这个值的由来通过标量值函数得到的,详解请看

    --操作1,通过操作1之后,这里的arrCount的值是3

                       SELECT @pt_arrCount = dbo.App_S_funcGetArrayLength(@pi_ShopCodes, '$')

    if @pi_Action='add'

    begin

    --开始执行事务,事务执行两种情况:要么里面的语句全部执行,要么全部不执行!个人理解这样是为了防止数据关联,删除部分数据之后造成系统局部功能瘫痪

                       BEGIN TRANSACTION

                       SET @pt_Index = 1

    --第一次:Index的值小于当前arrCount的值3

    --第二次:index的值为2,小于当前arrCount,继续循环

    --第三次:Index的值为3,等于当前arrCount,继续循环

                       WHILE @pt_Index <= @pt_arrCount

                       BEGIN

    --开始执行,得到商铺编号,怎么得到,这里又涉及到另外一个标量值函数,详解请看

    --操作2,在执行第一次的操作之后,shopCode的值是‘a’,再执行以下语句,先添加,后更新

    --第二次操作,返回ShopCode的值是‘b’

    --第三次操作,返回ShopCode的值是‘c’

                                SELECT @pt_ShopCode = dbo.App_S_funcGetValueOfArrayIndex(@pi_ShopCodes,'$', @pt_Index)

                                Insert into Asset_ContractShopInfo(ContractCode,ShopCode) values(@pi_ContractCode,@pt_ShopCode)      

                                update Asset_ShopInfo set RentStatus=2 where ShopCode=@pt_ShopCode

    --执行一次之后,Index的值变为2

    --再次执行之后,Index的值变为3

                       SET @pt_Index = @pt_Index + 1

                       END

    if @@error <> 0

    --如果事务执行失败,回滚事务,操作失败

    begin

    rollback transaction

    set @po_status = 900

    set @po_RetValue = '添加失败'

    end

    else

    --事务执行成功,操作成功

    begin

    commit transaction

    set @po_status = 100

    set @po_RetValue = '添加成功'

    end

    end

    --结果 a b c

    操作1【拿‘a$b$c’这样一个字符串来举例】

    dbo.App_S_funcGetArrayLength

    set ANSI_NULLS ON

    set QUOTED_IDENTIFIER ON

    go

    ALTER FUNCTION [dbo].[App_S_funcGetArrayLength]

    (

             @pi_Str VARCHAR(1000), --字符【这里就是‘a$b$c’】

             @pi_spliter VARCHAR(10) --分割符【‘$’】

    )

    RETURNS INT

    AS

    --这里开始

    BEGIN

    --首先声明三个需要的变量

             DECLARE @pt_Location INT

             DECLARE @pt_Start INT

             DECLARE @pt_Length INT

             --将获取的字符串两端空格去除,因为在执行的过程中会涉及到位置,空格亦算字符位置

             SET @pi_Str = LTRIM(RTRIM(@pi_Str))

    --接下来的就比较重要了,关于‘CHARINDEX’的相关用法,这里穿插一下其用法:

    【1.SQL CHARINDEX函数主要是返回字符或者字符串在另一个字符串中的起始位置

    2.函数方法:CHARINDEX(expression1,expression2[,start_location])

    解释一下:expression1是要到expression2中找的字符,strat_location是CHARINDEX函数开始在expression2中找expression1的位置

    3. SQL CHARINDEX函数返回一个整数,返回的整数是要找的字符串在被找的字符串中的位置。假如SQL CHARINDEX函数没有找到要找的字符串,那么函数整数“0”

    4.先来简单理解一下在我们这个存储过程中紧接着的这句话:

    CHARINDEX(@pi_spliter,@pi_str)就是要在传过来的’a$b$c’这个字符串当中找出‘$’的位置,即2,也就是说这里的@pi_Location的值就是2.(注意一下,这里的字符不是像数组当中的一样从0开始,而是从1开始!)

             SET @pt_Location = CHARINDEX(@pi_spliter,@pi_str)

            

             SET @pt_Length = 1

    --第一次:location的值是2,<>0条件成立,开始执行

    --第二次:location的值是4,<>0仍然成立,开始执行

    --第三次:location的值是0,<>0不成立,结束执行

             WHILE @pt_Location <> 0

             BEGIN

    --第一次:strat值为3

    --第二次;start值为5

                       SET @pt_Start = @pt_Location + 1

    --第一次:好,接下来看,这里的CHARINDEX的参数变成3个了,再返回看下,最后的Start是啥意思,通过例子说一下:找出‘$’在‘a$b$c’中从第3个开始往后的第1个‘$’的位置!也就是第二个‘$’的位置,就是4,(注意一下:此时的location已经变成4了)

    --第二次:找出‘$’在‘a$b$c’中从第5个开始往后的第1个‘$’的位置!即字符串当中‘c’的位置往后的‘$’显然,不存在了,这时候再看一下上面CHARINDEX函数当中的第3点:没有之后,返回给这里location的值就是0!

                       SET @pt_Location = CHARINDEX(@pi_spliter, @pi_str, @pt_Start)

    --第一次:执行结束,length变为2

    --第二次:执行结束,length变为3

                       SET @pt_Length = @pt_Length + 1

             END

    --第三次:返回length的长度:3        

             RETURN @pt_length

    操作2【这里一样用的是‘a$b$c’这样一个字符串来举例】

    dbo.App_S_funcGetValueOfArrayIndex

    set ANSI_NULLS ON

    set QUOTED_IDENTIFIER ON

    go

    ALTER FUNCTION [dbo].[App_S_funcGetValueOfArrayIndex]

    (

    --同样,先定义需要的变量,含义和之前的一样

             @pi_Str VARCHAR(1000), --字符

             @pi_spliter VARCHAR(10), --分割符

             @pi_index INT

    )

    RETURNS VARCHAR(1000)

    AS

    BEGIN

             DECLARE @pt_start INT

             DECLARE @pt_next INT

             DECLARE @pt_Seed INT

             DECLARE @pt_location INT

    --去除字符串空格

             SET @pi_Str = LTRIM(RTRIM(@pi_Str));         

             SET @pt_start = 1

             SET @pt_next = 1

    --获得spliter的长度值,即‘$’的长度,类似于有规律的一串数字,就说123$23$aa$89,两个字符中间共有的是$,所以想办法拆分的时候需要将其长度知晓,再截去这部分长度

    这里的Seed的值就是1

             SET @pt_Seed = LEN(@pi_spliter)

    --这里就不用多解释了,location的值就是2

             SET @pt_location = CHARINDEX(@pi_spliter, @pi_str)

    --第一次:location的值是2<>0成立,但是Index等于1不大于next,所以不执行

    --第二次:index的值为2,大于1,开始执行

    --第三次:Index的值为3,继续执行

             WHILE @pt_location <> 0 AND @pi_Index > @pt_next

             BEGIN

    --第一次:start的值变为3

    --第二次:start的值仍然为3

    --第三次:start的值变为5

                       SET @pt_start = @pt_location + @pt_seed

    --第二次:获取从第三个位置往后第一个$的位置:4,location为4

    --第三次:获取从第五个位置往后第一个$的位置:不存在,即location为0

                       SET @pt_location = CHARINDEX(@pi_spliter, @pi_str, @pt_start)

    --第二次:next的值变为2

    --第三次:next的值变为3

                       SET @pt_next = @pt_next + 1

             END

    --第一次:location值为2,不执行

    --第二次:location值为4,不执行

    --第三次:location值为0,执行语句

             IF @pt_location = 0

             BEGIN

    --第三次:location的值为6

                       SELECT @pt_location = LEN(@pi_str) + 1

             END

    --第一次:返回SUBSTRING,好,这里我们再看SUBSTRING的相关用法,第一次的结果是‘a

     

    【1.功能:返回字符、二进制、文本或图像表达式的一部分

    2.语法:SUBSTRING ( expression, start, length ),怎么理解?

    3.含义:expression 字符串、二进制字符串、文本、图像、列或包含列的表达式。请勿使用包含聚合函数的表达式。

    start 整数或可以隐式转换为 int 的表达式,指定子字符串的开始位置。

    length 整数或可以隐式转换为 int 的表达式,指定子字符串的长度。

    4.再看我们这句话:返回的结果就是在‘a$b$c’(str)中第一个位置(strat),截取长度为1的字符串(location-strat),即结果就是‘a

    --第二次:返回的结果就是在‘a$b$c’(str)中第3个位置(strat),截取长度为1的字符串(location-strat),即结果就是‘b’

    --第三次:返回的结果就是在‘a$b$c’(str)中第5个位置(strat),截取长度为1的字符串(location-strat),即结果就是‘c’

             RETURN SUBSTRING(@pi_str, @pt_start, @pt_location - @pt_start)

    END

    两个标量值函数的使用固然方便,在dbo.App_S_funcGetArrayLength中,最终得到的只是一个length的长度值,其他没有什么参数了,这是我开始时不解的地方,给定一个很大的length值就可以直接执行dbo.App_S_funcGetValueOfArrayIndex函数,但是,也是我思维局限的地方:假如字符串只是a$b,而我给定length的长度为100000000…,程序执行的时间可想而知,而且是浪费时间,通过dbo.App_S_funcGetArrayLength执行之后,length的值是动态的,就直接减少了时间的消耗。裨益一目了然!

     

  • 相关阅读:
    HTML总结
    js五角星评分特效
    正则表达式
    C#文件路径的写法
    vs2010发布网站
    INI文件阅读器
    .net读取xml文件中文乱码问题解决办法
    js利用定时器动态改变层大小
    c#中ref和out的用法
    分享一篇关于C#对文件操作的日志,方法很全
  • 原文地址:https://www.cnblogs.com/howie/p/2549078.html
Copyright © 2011-2022 走看看