精华内容
下载资源
问答
  • public DataSet ExcuteQuery(string sql,SqlParameter[]paras,CommandType ct) { DataSet ds=new DataSet(); using (SqlDataAdapter sda=new ...我是传入一个paras的参数数组,请问怎么修改这个代码.谢谢..
  • 接到这个需求,本以为简单。...方法一 分割例:通过SQL Server存储过程传送数组参数删除多条记录eg. ID 值为'1,2,3' 以下存储过程就是删除表中id号为1,2,3的记录:CREATE PROCEDURE DeleteNews@ID ...

    接到这个需求,本以为简单。谁知道SQL不支持数组。于是想用','分割传进去,哪知道SQL居然没有split()函数,还得用substring & charindex,坑爹啊。

    方法一 分割

    例:通过SQL Server存储过程传送数组参数删除多条记录

    eg. ID 值为'1,2,3' 以下存储过程就是删除表中id号为1,2,3的记录:

    CREATE PROCEDURE DeleteNews

    @ID nvarchar(500)

    as

    DECLARE @PointerPrev int

    DECLARE @PointerCurr int

    DECLARE @TId int

    Set @PointerPrev=1

    while (@PointerPrev < LEN(@ID))

    Begin

    Set @PointerCurr=CharIndex(',',@ID,@PointerPrev)

    if(@PointerCurr>0)

    Begin

    set @TId=cast(SUBSTRING(@ID,@PointerPrev,@PointerCurr-@PointerPrev) as int)

    Delete from News whereID=@TIDSET @PointerPrev = @PointerCurr+1

    End

    else

    Break

    End

    --删除最后一个,因为最后一个后面没有逗号,所以在循环中跳出,需另外再删除

    set @TId=cast(SUBSTRING(@ID,@PointerPrev,LEN(@ID)-@PointerPrev+1) as int)

    Delete from News whereID=@TIDGO

    这个方法麻烦不?于是又有另外一种方法——临时表

    方法二 Table对象

    传3个参数,都是数组形式还有时间类型用存储过程更新

    @Oid = 1,2,3,4

    @Did = 111,222,333,444

    @DateArr = '2007-1-1,2007-1-2,2007-1-3,2007-1-4'

    CREATE proc Test999

    @Oid nvarchar(1000)    --ID1

    ,@Did nvarchar(1000)  --ID2

    ,@DateArr nvarchar(1000) --日期

    AS

    DECLARE @id1s varchar(8000), @id2s varchar(8000), @dates varchar(8000)

    set @id1s=@Oid

    set @id2s=@Did

    set @dates = @DateArr

    -- 调用函数实现处理

    SELECT @id1s=@id1s, @id2s=@id2s,@dates = @dates

    UPDATE A SET terminate_time = B.dt

    FROM [Table] A,(

    SELECT

    id1 = CONVERT(int, Desk_id.value),

    id2 = CONVERT(int, room_id.value),

    dt = CONVERT(datetime, terminate_time.value)

    FROM dbo.f_splitstr(@id1s) Desk_id, dbo.f_splitstr(@id2s) room_id, dbo.f_splitstr(@dates) terminate_time

    WHERE Desk_id.id = room_id.id

    AND Desk_id.id = terminate_time.id

    ) B

    WHERE A.Desk_id = B.ID1 AND A.room_id = B.ID2

    GO这个还用到一个函数f_splitstr

    CREATE FUNCTION dbo.f_splitstr(

    @str varchar(8000)

    )RETURNS @r TABLE(id int IDENTITY(1, 1), value varchar(5000))

    AS

    BEGIN

    DECLARE @pos int

    SET @pos = CHARINDEX(',', @str)

    WHILE @pos > 0

    BEGIN

    INSERT @r(value) VALUES(LEFT(@str, @pos - 1))

    SELECT

    @str = STUFF(@str, 1, @pos, ''),

    @pos = CHARINDEX(',', @str)

    END

    IF @str > ''

    INSERT @r(value) VALUES(@str)

    RETURN

    END

    这个方法更加可怕~~~辗转百度,找到了一个还不错的方法,用OPENXML,这个SQL2000就支持了。

    方法三 xml

    应该用SQL2000 OpenXML更简单,效率更高,代码更可读:

    CREATE Procedure [dbo].[ProductListUpdateSpecialList]

    (

    @ProductId_Array NVARCHAR(2000),

    @ModuleId INT

    )

    AS

    delete from ProductListSpecial whereModuleId=@ModuleId

    -- If empty, return

    IF (@ProductId_Array IS NULL OR LEN(LTRIM(RTRIM(@ProductId_Array))) = 0)

    RETURN

    DECLARE @idoc int

    EXEC sp_xml_preparedocument @idoc OUTPUT, @ProductId_Array

    Insert into ProductListSpecial (ModuleId,ProductId)

    Select

    @ModuleId,C.[ProductId]

    FROM

    OPENXML(@idoc, '/Products/Product', 3)

    with (ProductId int ) as C

    where

    C.[ProductId] is not null

    EXEC sp_xml_removedocument @idoc

    哇,看起来还是很复杂的说。有木有更好的办法呢?

    既然是OPENXML,为啥不用XML呢?于是查到,SQL2005以上都支持XML。Good,找到一片天了。

    利用SQL2005的XML/XQuery功能,可以很方便的解决传数组参数的问题。

    declare @xml xml

    set @xml = '<?xml version="1.0"?>

    1

    2

    3

    '

    select N.value( '(text())[1]','int' ) RoomId from @xml.nodes('/ArrayOfInt/int') V(N)

    结果就是

    e8c02935185eba868e5609f3aa84d9e3.png

    注:上面的数据类型为XML

    这样就可以给存储过程传一个集合了,一般是数组,比如主键的集合。然后可用通过主键集合来查询记录。

    客户端可用使用序列化,把list转化成xml。不过在序列化过程中,遇到了一些小麻烦。

    1. .net默认是utf-16,SQL只认识utf-8

    2. 出现很讨厌的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    可以用我这个类

    public static classSerializeHelper

    {private static readonly XmlSerializerNamespaces Namespaces = newXmlSerializerNamespaces();staticSerializeHelper()

    {//去掉 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    Namespaces.Add(string.Empty, string.Empty);

    }public static string SerializeXml(T obj)

    {

    XmlSerializer serializer= new XmlSerializer(typeof(T));using (MemoryStream stream = newMemoryStream())

    {

    serializer.Serialize(stream, obj, Namespaces);returnEncoding.UTF8.GetString(stream.ToArray());

    }

    }public static T DeserializeXml(stringobj)

    {

    XmlSerializer serializer= new XmlSerializer(typeof(T));using (StringReader reader = newStringReader(obj))

    {return(T)serializer.Deserialize(reader);

    }

    }

    }

    SQL与XML,XQuery结合起来,功能会很强大的。

    从这个事件也看出,我应该多关注SQL各个版本之间新增功能,比如SQL2008新增功能。否则遇到问题,找不到比较好的解决方案。

    OK,问题以完美的方式解决了,用最妙的方法解决问题,好开森哦~~~O(∩_∩)O!

    展开全文
  • MySql存储过程传数组参数

    千次阅读 2018-09-17 10:38:40
    第二版想法为,把所有参数传入到存储过程,循环参数为一个数组,mysql存储过程里没有split函数, 取数组中的值通过substring截出,通过截的id值作为条件查询数据,查询到的数据有可能是 多条记录,所有想通过游标...

    项目中遇到批量数据的处理,使用hibernate的出来太慢,修改为存储过程。

    第一版修改为应用循环调存储过程,发现效果不理想。可能是频繁的打开session和关闭。

    第二版想法为,把所有参数传入到存储过程,循环参数为一个数组,mysql存储过程里没有split函数,

    取数组中的值通过substring截出,通过截的id值作为条件查询数据,查询到的数据有可能是

    多条记录,所有想通过游标(CURSOR)进行结果集的循环进行处理,但是,

    游标(cursor)的特性

    1,只读的,不能更新的。
    2,不滚动的
    3,不敏感的,不敏感意为服务器可以活不可以复制它的结果表

    游标(cursor)必须在声明处理程序之前被声明,并且变量和条件必须在声明游标或处理程序之前被声明。

    第三版想法为,建立俩个存储过程,第一个为截窜并调起第二个实际处理的存储过程。

    已下截窜存储过程来自网络:

    drop procedure if exists Pro_DeleteLog; -- 存在即删除
    create procedure Pro_DeleteLog( Qualification varchar(100)) -- 定义参数
    begin
    declare i int ; 
    declare Start1 int; 
    declare Length int ;
    declare TotalLenght int ;
    declare filed varchar(100) ;
    declare sqlStr varchar(2000) ;
    declare stmtNovelSearch varchar(2000) ;
    set i=1;
    set Start1=1;
    set Length=0;
    set TotalLenght=length(Qualification); -- 计算输入参数长度
    select TotalLenght; 
    while i <=TotalLenght do -- i=1 开始
    -- select SUBSTRING(Qualification,i,1);
    if(SUBSTRING(Qualification,i,1)=',') -- 注意 mysql 的substring函数截取字符串是从1开始的,而不是0 与java JavaScript不同。
    -- 从第i位开始截取一个字符,看是否等于,
    then 
    set filed=SUBSTRING(Qualification,Start1,Length);-- 从start1开始截取length长度的字符 
    select filed; 
    call pro_do(filed); -- 具体要循环执行的存储过程
    set Start1=i+1; 
    set Length=0;
    else
    set Length=Length+1; -- 如果不是, 则截取的长度加1 
    end if;
    set i=i+1; 
    end while;
    end
    -- 调用存储过程 字段名以,分隔 注意最后 , 结尾
    call Pro_DeleteLog('payload,backresult,dataset,effectrow,clientuser,loginuser,clientprg,')

    转载:http://www.cnblogs.com/bigcelestial/archive/2013/09/05/3303329.html

     

    --经测试可用。

    展开全文
  • 问题来自于通过存储过程保存数据时出现以下错误 java.sql.SQLException: 对列来说插入的值太大:"............" 省略号内容超过500个字符。 出错的JAVA程序语句如下: ParameterArray pArray = ...
    问题来自于通过存储过程保存数据时出现以下错误
    java.sql.SQLException: 对列来说插入的值太大:"............"
    省略号内容超过500个字符。
    出错的JAVA程序语句如下:
    ParameterArray pArray = getParameterArray(context, base, pro, eid);
    cstmt = conn.prepareCall("CALL PKG_GETBUSINESSDATA.ADD_PAYOUTITEM(?, ?, ?)");
    cstmt.setObject(1, pArray.getOracleARRAY(conn));
    ...
    程序将要保存的数据放在pArray对象中,然后将pArray对象重新构造成ORACLE的数组类型,过程中的第一个参数是自动定义的数据组类型,其中有个字段content数据特别大,数据库中该content字段长度设置为varchar2(4000)(具我所知),但是在存储过程中却只能保存500个字符,超出就异常。
    经检查,原因是ORACLE中自定义的类型有问题,如下:
    CREATE OR REPLACE TYPE YSBZ.TYPE_PARAMETER
    AS OBJECT(
    NAME VARCHAR2(100), STRVALUE VARCHAR2(1000))
    /
    后将STRVALUE改成VARCHAR2(4000)就好了,同时需要调整过程中对应的v_content字段,不然会出现ORA-06502:PL/SQL:数字或值错误:character string buffer too smal
    意思是:字符串缓冲区太小
    ORACLE的自定义类型修改不了,只好删除重建。
    展开全文
  • -SELECT * FROM #temp_delete DROP TABLE #temp_insert DROP TABLE #temp_delete END 这是我写的一个MSSQL的存储过程 参数@XML_ARRAY的数据格式是: '' 用openXML解析 想问下如果用mysql解决应该怎么做,如何传递一个...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

    ALTER PROCEDURE [dbo].[Proce_Building_Relation_RP]

    -- Add the parameters for the stored procedure here

    @RID BIGINT, -- 角色id

    @XML_Array varchar(500), -- 代表权限的id序列化字符串

    @Rowcount INT=0 OUTPUT

    AS

    BEGIN

    -- SET NOCOUNT ON added to prevent extra result sets from

    -- interfering with SELECT statements.

    --SET NOCOUNT ON;

    DECLARE @IdHandel INT

    CREATE TABLE #temp_insert(RID BIGINT,Nums BIGINT)

    CREATE TABLE #temp_delete(RID BIGINT,Nums BIGINT)

    EXEC sp_xml_preparedocument @IdHandel OUTPUT, @XML_Array

    -- 填充与源数据不重复的数值的表

    INSERT INTO #temp_insert(RID,Nums)

    SELECT @RID,N.Nums

    FROM OPENXML(@IdHandel,'/Array/PA') WITH(Nums BIGINT) AS N

    WHERE N.[Nums] IS NOT NULL

    AND (Nums not in (select pid from Sys_User_Relation_RP where rid=@RID) )

    -- 填充与源数据重复的数值的表

    INSERT INTO #temp_delete(RID,Nums)

    SELECT @RID,N.Nums

    FROM OPENXML(@IdHandel,'/Array/PA') WITH(Nums BIGINT) AS N

    WHERE N.[Nums] IS NOT NULL

    AND (Nums in (select pid from Sys_User_Relation_RP where rid=@RID) )

    -- 向表插入与数组参数不重复的数值

    INSERT INTO Sys_User_Relation_RP(rid,pid) SELECT RID,Nums FROM #temp_insert

    SET @Rowcount=@@ROWCOUNT

    -- 删除表中与数组参数重复的数值

    DELETE FROM Sys_User_Relation_RP WHERE rid=@RID and pid in (SELECT Nums FROM #temp_delete WHERE RID=@RID)

    SET @Rowcount=@Rowcount+@@ROWCOUNT

    EXEC sp_xml_removedocument @IdHandel

    --SELECT * FROM #temp_insert

    --SELECT * FROM #temp_delete

    DROP TABLE #temp_insert

    DROP TABLE #temp_delete

    END

    这是我写的一个MSSQL的存储过程

    参数@XML_ARRAY的数据格式是:

    ''

    用openXML解析

    想问下如果用mysql解决应该怎么做,如何传递一个序列化字符串然后解析

    展开全文
  • 今天做OA程序用到sql server存储过程,需要传递数组参数,但是sql server本身不支持数组,于是从网上找了一些资料. 方法一、利用SQL Server强大的字符串处理数组格式化为类似"1,2,3,4,5,6"  然后在存储过程...
  • 最近在做开发过程中碰到这么一个纠结的问题,...利用SQL Server强大的字符串处理数组格式化为类似"3500320083208#3500600520890#3500741122924#3500790143280#3501010510869#3500741129750", 然后在存储过程中用S
  • * 调用存储过程批量插入照片 * @param jwxhs 照片名字(不带后缀)数组集合,也就是学生教务学号集合(eg.123 不是123.jpg) * @param undirectoryPath 照片对应的文件夹路径 */ private void synaZp(String...
  • ssh c3po oracle存储过程传数组

    千次阅读 2010-09-21 15:42:00
    java代码调用存储过程,在传入数组参数的时候用到多种取数据库连接的方式,这里我用的是:  c3p0连接池,Spring 2.5,Hibernate 3.2.3 但是却一直有这种异常,   java.lang....
  • 接到这个需求,本以为简单。谁知道SQL不支持数组。...例:通过SQL Server存储过程传送数组参数删除多条记录 eg. ID 值为'1,2,3' 以下存储过程就是删除表中id号为1,2,3的记录: CREATE PROCEDURE Delete...
  • oracle 向存储过程传入数组类型参数

    千次阅读 2012-04-20 13:14:49
    最近想试试给存储过程传数组参数,破费周折,在这里与大家分享下: 我用的plsql, 打开plsql,在type目录下面,可以创建自定义的数据类型, 于是用 create or replace type tab_str as table of varchar2(30); ...
  • 方法一、利用SQL Server强大的字符串处理数组格式化为类似"1,2,3,4,5,6"然后在存储过程中用SubString配合CharIndex把分割开来。存储过程如下: 1CREATEPROCEDUREdbo.ProductListUpdateSpecialList2@ProductId_...
  • 这次记的是一个给sql的存储过程传数组参数的问题..大家都知道sql是不支持数组的,所以需要用特殊方法来处理.. 在大多数项目中,都会有全选/删除这样的操作..一般的解决办法是在后台代码里循环执行sql语句.. 昨天在我...
  • 最近一直在做Dnn模块的开发,过程中碰到这么一个问题,需要同时插入N条数据,不想在程序里控制,但是SQL Sever又不支持数组参数.所以只能用变通的办法了.利用SQL Server强大的字符串处理数组格式化为类似"1,2,3,4,5,...
  • 现在想用ibatis调用存储过程存储过程里有个字符串数组输入参数,在ibatis SQL MAP 应该怎么配置,数组类型的jdbcType填什么,java类型填什么? <strong>问题补充:</strong><br />你这是2个参数进去,...
  • mysql5.5传入一个数组去调用存储过程修改其他表的状态 因为mysql不能直接对数组进行处理,所以只能定义字符串形式进行接收参数。 写这个储存过程是为了解决在工作中,避免重复调用触发器去修改其他表的数据,如果...
  • 这个是一位印度朋友的,我在我们项目里用了,感觉不错,大家也可以用  首先,create 一个函数[dbo].[Split] 作用是把以分隔符分割的字符串分割开来,然后存储在一个表中返回 代码,我直接把这...
  • 在很多的情况下,在编写存储过程中往往会用到数组,但是mysql中存储过程传入参数并没有可以直接传入数组的方法。在这种情况下我们只能退而求之或者说换个方式以字符串形式传入参数,然后在过程体中把字符串再转成数...
  • 3个参数,都是数组形式还有时间类型用存储过程更新 @Oid = 1,2,3,4 @Did = 111,222,333,444 @DateArr = 2007-1-1,2007-1-2,2007-1-3,2007-1-4 CREATE proc Test999@Oid nvarchar(1000) --ID1,@Did nvarchar(1000)
  • 数组名作函数参数

    2015-08-07 11:51:01
    /*在用变量作函数参数时,只能将实参变量的值给形参,在调用函数的过程中,如果改变了形参变量的值,对实参没有影响,即实参的值不因形参的改变而改变。而用数组名作函数参数时,如果改变了形参数组的元素的值将...
  • 开发过程中碰到这么一个问题,需要同时插入N条数据,不想在程序里控制,但是SQL Sever又不支持数组参数.... 然后在存储过程中用SubString配合CharIndex把分割开来 详细的存储过程 CREATE PROCEDURE dbo.ProductListU
  • 在很多的情况下,在编写存储过程中往往会用到数组,但是mysql中存储过程传入参数并没有可以直接传入数组的方法。在这种情况下我们只能退而求之或者说换个方式以字符串形式传入参数,然后在过程体中把字符串再转成数...

空空如也

空空如也

1 2 3 4 5
收藏数 83
精华内容 33
关键字:

存储过程传参数数组