建立sql数组的一个函数

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go


-- =============================================

-- Author:      netcorner

-- Create date:   3/10/2008

-- Description: Split string variant with type of ntext

-- =============================================

Create FUNCTION [dbo].[split]

(

   @text ntext,

   @delimiter char(1)

)

RETURNS @arrayTable TABLE(Idx bigint, [Value] nvarchar(200))

AS

BEGIN

     DECLARE @splitlen int
DECLARE @tmp varchar(1024)

    SET @splitlen = 4000

    DECLARE @Idx int SET @Idx = 0

    -- 定义取子串的起始位置

    DECLARE @textsplit bigint

    SET @textsplit = 1

    WHILE( @textsplit <= DATALENGTH(@text) )

    BEGIN

        -- 由于许多字符串处理函数无法用于ntext数据类型

        -- 所以需要循环按批处理ntext字符串,一批取出

        -- 个字符放入nvarchar(4000)类型的变量中.

        DECLARE @string nvarchar(4000)

        SELECT @string = SUBSTRING(@text,@textsplit,@splitlen)

        -- 能够取出满个字符

        IF LEN(@string) = @splitlen

        BEGIN

            -- 确保取出的个字符是完整的由分隔符隔开的字符串组合

            DECLARE @lastcomma int

            SELECT @lastcomma = CHARINDEX(@delimiter,REVERSE(@string),1)

            -- 最后一个分隔符后面的字符串不完整,应抛弃

            IF @lastcomma > 0

            BEGIN

                SELECT @string = SUBSTRING(@string,1,@splitlen - @lastcomma)

                -- 设置下一次从@text取字符的起始位置

                SELECT @textsplit = @textsplit + @splitlen - @lastcomma + 1

            END

            -- 最后一个分隔符后面的字符串完整.

            ELSE

            BEGIN

                SELECT @textsplit = @textsplit + @splitlen + 1

            END

        END

        -- 取出不满个字符

        ELSE

        BEGIN

            SELECT @textsplit = @textsplit + @splitlen + 1

        END

      

        -- 解析@string,取出以分隔符为界限的子字符串

        DECLARE @i1 int SET @i1 = 1

        DECLARE @i2 int SET @i2 = 1

        WHILE @i1 <= LEN(@string)

        BEGIN

            SET @i2 = CHARINDEX(@delimiter,@string,@i1)
            IF @i2 = 0
                SET @i2 = LEN(@string) + 1
    set @tmp=SUBSTRING(@string,@i1,@i2-@i1)
    if(@tmp='')
     INSERT @arrayTable (Idx) select @Idx
    else
    begin
     INSERT @arrayTable (Idx, Value)
     SELECT @Idx, @tmp
    end
            SET @i1 = @i2 + 1

            SET @Idx = @Idx + 1

        END

    END

    RETURN

END


### Oracle SQL数组类型的使用方法与定义 #### 定义数组类型 在 PL/SQL 中,虽然不存在直接称为“数组”的数据结构,但可以通过 `TYPE` 和表记录来实现类似的功能。对于一维数组,可以利用集合类型如 VARRAY 或者嵌套表 (Nested Table),而对于索引表(Index-by 表),则更接近于传统意义上的数组。 - **VARRAY 类型** 当需要固定长度的一维数组时,可以选择使用 VARRAY。创建这种类型的对象前,需先通过 `CREATE TYPE` 声明其结构并指定期望容纳的最大数量以及元素的数据类型[^4]: ```sql -- 创建名为 dept_array 的 varray 类型,最多可保存 10 个部门名称字符串 CREATE OR REPLACE TYPE dept_array AS VARRAY(10) OF VARCHAR2(30); / ``` - **嵌套表(Nested Table)** 如果不确定所需空间的确切大小,则应考虑采用嵌套表形式。这允许动态增加成员数目而不必预先设定上限。同样地,在应用之前要声明相应的类型[^5]: ```sql -- 创建一个无界整数列表作为嵌套表类型 CREATE OR REPLACE TYPE int_list_type IS TABLE OF NUMBER; / ``` - **索引表(Index-by Table)** 也被称为关联数组或稀疏数组,这类表格提供了基于键值对的方式访问元素的能力,并且支持任意顺序插入新项。它们通常用于临时存储中间计算结果或其他不适合其他两种方式处理的情况: ```plsql DECLARE -- 定义一个以二进制整数为下标的变长字符集 TYPE str_indexed_by_int IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; BEGIN NULL; -- 示例中未具体操作该变量 END; / ``` #### 使用数组类型 一旦建立了上述任何一种自定义复合类型之后,就可以像常规标量那样对其进行初始化、赋值及其他各种运算了。下面给出几个简单的例子展示这些功能的应用场景[^3]。 ##### 初始化 & 赋值 无论是哪种类型的数组,都可以按照如下模式完成初始设置工作: ```plsql DECLARE -- 实例化前面提到过的几种不同风格的容器 v_dept_names DEPT_ARRAY := DEPT_ARRAY('HR', 'Finance'); nt_numbers INT_LIST_TYPE := INT_LIST_TYPE(); BEGIN -- 向已存在的集合追加更多条目 IF NOT v_dept_names.EXISTS(3) THEN v_dept_names.EXTEND(); -- 扩展容量以便加入第三个元素 v_dept_names(v_dept_names.COUNT):= 'Sales'; END IF; FOR i IN 1..v_dept_names.COUNT LOOP DBMS_OUTPUT.PUT_LINE(i||': ' || v_dept_names(i)); END LOOP; -- 对于嵌套表而言可以直接调用内置函数批量加载多个数值 nt_numbers:=INT_LIST_TYPE(1,2,3); END; / ``` ##### 迭代遍历 为了逐一遍历所有成员,推荐借助游标(CURSOR)或者显式的FOR循环语句来进行迭代。这里提供一段针对先前建立好的两个实体执行此动作的小程序片段[^2]: ```plsql BEGIN -- 输出 VARRAY 内容 FOR idx IN 1 .. v_dept_names.COUNT LOOP DBMS_OUTPUT.PUT_LINE('Department Name at position ' || TO_CHAR(idx) || ': ' || v_dept_names(idx)); END LOOP; -- 处理 NESTED TABLE 数据 FOR num IN nt_numbers.FIRST .. nt_numbers.LAST LOOP EXIT WHEN nt_numbers(num) IS NULL; DBMS_OUTPUT.PUT_LINE('Number value: ' || TO_CHAR(nt_numbers(num))); END LOOP; END; / ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值