sql >> データベース >  >> Database Tools >> SSMS

1列内の不明な数のコンマ区切りのvarcharを複数の列に変換します

    この回答を作成する際に、1つの仮定を立てました。これは、別個のストアドプロシージャとして必要であるということです。

    ステップ1

    データ型 を作成します テーブル値パラメーター(TVP)をストアード・プロシージャーに渡すことができるようにします。

    use db_name
    GO
    create type axisTable as table 
        (
            axis1 varchar(max)
        )
    GO
    

    ステップ2

    値を解析するためのプロシージャを作成します。

    USE [db_name]
    GO
    
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE PROCEDURE [dbo].[usp_util_parse_out_axis] 
        (
            @axis_tbl_prelim axisTable readonly
        )
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        declare @axis_tbl axisTable
    
        --since TVP's are readonly, moving the data in the TVP to a local variable
        --so that the update statement later on will work as expected
        insert into @axis_tbl
        select *
        from @axis_tbl_prelim
    
        declare @comma_cnt int
            , @i int 
            , @sql_dyn nvarchar(max)
            , @col_list nvarchar(max)
    
        --dropping the global temp table if it already exists
        if object_id('tempdb..##axis_unpvt') is not null
            drop table ##axis_unpvt
    
        create table ##axis_unpvt
            (
                axis_nbr varchar(25)
                , row_num int
                , axis_val varchar(max)
            )
    
        --getting the most commas
        set @comma_cnt = (select max(len(a.axis1) - len(replace(a.axis1, ',', '')))
                            from @axis_tbl as a)
    
        set @i = 1
        while @i <= @comma_cnt + 1
        begin --while loop
    
            --insert the data into the "unpivot" table one parsed value at a time (all rows) 
            insert into ##axis_unpvt
            select 'axis' +  cast(@i as varchar(3))
            , row_number() over (order by (select 100)) as row_num --making sure the data stays in the right row
            , case when charindex(',', a.axis1, 0) = 0 and len(a.axis1) = 0 then NULL
                    when charindex(',', a.axis1, 0) = 0 and len(a.axis1) > 0 then a.axis1
                    when charindex(',', a.axis1, 0) > 0 then replace(left(a.axis1, charindex(',', a.axis1, 0)), ',', '')
                    else NULL
            end as axis1
            from @axis_tbl as a
    
            --getting rid of the value that was just inserted from the source table
            update a
            set a.axis1 = case when charindex(',', a.axis1, 0) = 0 and len(a.axis1) > 0 then NULL
                               when charindex(',', a.axis1, 0) > 0 then rtrim(ltrim(right(a.axis1, (len(a.axis1) - charindex(',', a.axis1, 0)))))
                               else NULL
                          end
            from @axis_tbl as a
            where 1=1
            and (charindex(',', a.axis1, 0) = 0 and len(a.axis1) > 0
                 or charindex(',', a.axis1, 0) > 0) 
    
            --incrementing toward terminating condition
            set @i += 1
    
        end --while loop
    
        --getting list of what the columns will be after pivoting
        set @col_list = (select stuff((select distinct ', ' + axis_nbr
                                from ##axis_unpvt as a
                                for xml path ('')),1,1,''))
    
        --building the pivot statement
        set @sql_dyn = '
        select '
        + @col_list + 
        '
        from ##axis_unpvt as a
        pivot (max(a.axis_val)
                for a.axis_nbr in ('
                                    + @col_list + 
                                    ')) as p'
    
        --executing the pivot statement
        exec(@sql_dyn);
    
    END
    

    ステップ3

    手順1で作成したデータ型をパラメータとして使用してプロシージャコールを作成します。

    use db_name
    go
    
    declare @tvp as axisTable
    
    insert into @tvp values ('296.90, 309.4')
    insert into @tvp values ('296.32, 309.81')
    insert into @tvp values ('296.90')
    insert into @tvp values ('300.11, 309.81, 311, 313.89, 314.00, 314.01, V61.8, V62.3')
    
    exec db_name.dbo.usp_util_parse_out_axis @tvp
    

    例の結果は次のとおりです。




    1. SQL ServerManagementStudioのテーブルからCRUDストアドプロシージャを生成するにはどうすればよいですか

    2. PHPバージョンによるApacheのPHPMyAdmin500内部サーバーエラー

    3. UTF-8照合を使用したphpMyAdminのラテン文字

    4. phpmyadminがExcel用のcsvにエクスポート