zoukankan      html  css  js  c++  java
  • 根据提供的原始数据,生成测试数据表

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * 功能:根据提问者提供的原始数据,生成测试数据表。                          *
     * 说明:1.单个/多个测试表一起生成。                                         *
     *       2.表类型:变量表/临时表/实体表,可控。                              *
     *       3.如无表名:T1...Tn;如无列名:c1...cn。                            *
     *       4.列填充:数据列不足填充NULL值;字段列不足以sql_variant填充cm...cn。*
     *       5.数据类型解析:自动解析最恰当的数据类型/长度。                     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /*
     --> 多表测试:
    cs '@var
    id data
    1 表变量
    
    #tmp
    id data
    2 临时表
    
    $tab
    id,data
    3 实体表'
    go
    
    /*
    --> 测试数据: @var
    declare @var table (id int,data varchar(6))
    insert into @var
    select 1,'表变量'
    --> 测试数据: #tmp
    if object_id('tempdb.dbo.#tmp') is not null drop table #tmp
    create table #tmp (id int,data varchar(6))
    insert into #tmp
    select 2,'临时表'
    --> 测试数据: [tab]
    if object_id('[tab]') is not null drop table [tab]
    create table [tab] (id int,data varchar(6))
    insert into [tab]
    select 3,'实体表'
    
    select * from @var
    select * from #tmp
    select * from [tab]
    */
    
    --> 无表名/无列名测试:
    cs '@
    id data
    1 无表名
    
    0#tmp
    2 无列名
    
    0$
    3 双无'
    go
    
    /*
    --> 测试数据: @T1
    declare @T1 table (id int,data varchar(6))
    insert into @T1
    select 1,'无表名'
    --> 测试数据: #tmp
    if object_id('tempdb.dbo.#tmp') is not null drop table #tmp
    create table #tmp (c1 int,c2 varchar(6))
    insert into #tmp
    select 2,'无列名'
    --> 测试数据: [T3]
    if object_id('[T3]') is not null drop table [T3]
    create table [T3] (c1 int,c2 varchar(4))
    insert into [T3]
    select 3,'双无'
    
    select * from @T1
    select * from #tmp
    select * from [T3]
    */
    
    --> 保留原NULL值,字段数据分隔线忽略:
    cs '@null
    a    b
    ---- ----
    11   null
    null 22'
    go
    /*
    --> 测试数据: @null
    declare @null table (a int,b int)
    insert into @null
    select 11,null union all
    select null,22
    
    select * from @null
    */
    
    --> 数据列不足,NULL值填充,数据左边对齐原则:
    cs '@fill_null
    a b c d
    11 12 13
       21 22
          31'
    go
    
    /*
    --> 测试数据: @fill_null
    declare @fill_null table (a int,b int,c int,d sql_variant)
    insert into @fill_null
    select 11,12,13,null union all
    select 21,22,null,null union all
    select 31,null,null,null
    
    select * from @fill_null
    */
    
    --> 字段名不足,动态添加字段,以cm...cn命名:
    cs '@add_column
    a
    11 12 13
       21 22
          31'
    go
    
    /*
    --> 测试数据: @add_column
    declare @add_column table (a int,c2 int,c3 int)
    insert into @add_column
    select 11,12,13 union all
    select 21,22,null union all
    select 31,null,null
    
    select * from @add_column
    */
    
    --> 占位符分号的作用——控制数据的位置,用NULL代替效果一样:
    cs '@semicolon
    a b c
    11 12 13
    ;  22 23
    ;  ;  33'
    go
    
    /*
    --> 测试数据: @semicolon
    declare @semicolon table (a int,b int,c int)
    insert into @semicolon
    select 11,12,13 union all
    select null,22,23 union all
    select null,null,33
    
    select * from @semicolon
    */
    
    -->时间解析一:
    cs '@time
    id date boy
    1 2001-1-1 Mark
    2 20020101 John
    3 23:15:39 Paul'
    go
    
    /*
    --> 测试数据: @time
    declare @time table (id int,date datetime,boy varchar(4))
    insert into @time
    select 1,'2001-1-1','Mark' union all
    select 2,'20020101','John' union all
    select 3,'23:15:39','Paul'
    
    select * from @time
    */
    
    -->时间解析二:
    cs '@time
    id date boy
    1 2001-1-1 12:28:47 Mark
    2 20020101 17:30:00 John
    3 2003/1/1 23:15:39 Paul'
    go
    
    /*
    --> 测试数据: @time
    declare @time table (id int,date datetime,boy varchar(4))
    insert into @time
    select 1,'2001-1-1 12:28:47','Mark' union all
    select 2,'20020101 17:30:00','John' union all
    select 3,'2003/1/1 23:15:39','Paul'
    
    select * from @time
    */
    
    -->时间解析三——不支持:
    cs '@time
    id date boy
    1 2001-1-1 12:28:47 Mark
    2 20020101 John
    3 2003/1/1 Paul'
    go
    
    /*
    --> 测试数据: @time
    declare @time table (id int,date datetime,boy varchar(8),c4 varchar(4))
    insert into @time
    select 1,'2001-1-1','12:28:47','Mark' union all
    select 2,'20020101','John',null union all
    select 3,'2003/1/1','Paul',null
    
    select * from @time
    */
    
    -->时间解析三——正确解析需要手工添加占位符:
    cs '@time
    id date boy
    1 2001-1-1 12:28:47 Mark
    2 20020101 ; John
    3 2003/1/1 ; Paul'
    go
    
    /*
    --> 测试数据: @time
    declare @time table (id int,date datetime,boy varchar(4))
    insert into @time
    select 1,'2001-1-1 12:28:47','Mark' union all
    select 2,'20020101','John' union all
    select 3,'2003/1/1','Paul'
    
    select * from @time
    */
    */
    
    
    CREATE PROCEDURE cs @input VARCHAR(MAX)
    AS 
        SET nocount ON
        IF PATINDEX('%[@#$]%', @input) = 0 
            RETURN
        SELECT  @input = REPLACE(@input, ' ', ' '), @input = LTRIM(RTRIM(@input))
        SELECT TOP 94
                code = IDENTITY( TINYINT,33,1), m = CAST(NULL AS VARCHAR(2)),
                w = CAST(NULL AS VARCHAR(1))
        INTO    #
        FROM    syscolumns
        SELECT  @input = REPLACE(@input COLLATE chinese_prc_cs_as_ks_ws,
                                 NCHAR(code + 65248), CHAR(code))
        FROM    #
        TRUNCATE TABLE #
        INSERT  INTO #
                SELECT  CHAR(13), CHAR(10)
        INSERT  INTO #
                SELECT  CHAR(9), ','
        INSERT  INTO #
                SELECT  ' ', ','
        INSERT  INTO #
                SELECT  '|', ','
        INSERT  INTO #
                SELECT  '¦', ','
        INSERT  INTO #
                SELECT  '。', '.'
        INSERT  INTO #
                SELECT  '·', '.'
        INSERT  INTO #
                SELECT  CHAR(39), ''
        SELECT  @input = REPLACE(@input COLLATE chinese_prc_cs_as_ks_ws, m, w)
        FROM    #
        DROP TABLE #
        WHILE PATINDEX('%[^,][;]%', @input) > 0 
            SET @input = STUFF(@input, PATINDEX('%[^,][;]%', @input) + 1, 1, ',;')
        WHILE PATINDEX('%[;][^,]%', @input) > 0 
            SET @input = STUFF(@input, PATINDEX('%[;][^,]%', @input), 1, ';,')
        SET @input = REPLACE(@input, ';', 'null')
        WHILE CHARINDEX(',,', @input) > 0 
            SET @input = REPLACE(@input, ',,', ',')
        SET @input = REPLACE(@input, CHAR(10) + ',', CHAR(10))
        SET @input = REPLACE(@input, ',' + CHAR(10), CHAR(10))
        WHILE CHARINDEX(CHAR(10) + CHAR(10), @input) > 0 
            SET @input = REPLACE(@input, CHAR(10) + CHAR(10), CHAR(10))
        IF LEFT(@input, 1) = CHAR(10) 
            SET @input = RIGHT(@input, LEN(@input) - 1)
        IF RIGHT(@input, 1) <> CHAR(10) 
            SET @input = @input + CHAR(10)
        DECLARE @tab SYSNAME -- 表名:@=变量表;#=临时表;$=实体表
        DECLARE @tid TINYINT
        DECLARE @yes BIT
        DECLARE @cid SMALLINT
        DECLARE @col VARCHAR(1000)
        DECLARE @max SMALLINT
        DECLARE @type SYSNAME
        DECLARE @lenp SMALLINT
        DECLARE @lens SMALLINT
        DECLARE @sql VARCHAR(8000)
        DECLARE @tabs TABLE
            (
              id INT IDENTITY ,
              name SYSNAME
            )
        DECLARE @data TABLE
            (
              id INT IDENTITY ,
              data VARCHAR(8000)
            )
        DECLARE @temp TABLE
            (
              id INT ,
              temp VARCHAR(1000)
            )
        DECLARE @code TABLE
            (
              id INT ,
              code VARCHAR(8000)
            )
        IF CHARINDEX('$', @input) > 0 
            BEGIN
                SET @tab = SUBSTRING(@input, CHARINDEX('$', @input) + 1,
                                     CHARINDEX(CHAR(10), @input,
                                               CHARINDEX('$', @input))
                                     - CHARINDEX('$', @input) - 1)
                IF OBJECT_ID(@tab) IS NOT NULL 
                    BEGIN
                        RAISERROR(N'数据库中已存在名为 ''%s'' 的对象。',16,1,@tab)
                        RETURN
                    END
            END
        WHILE PATINDEX('%[@#$]%', @input) > 0 
            BEGIN
                SELECT  @tab = LEFT(@input, CHARINDEX(CHAR(10), @input) - 1),
                        @tid = ISNULL(@tid, 0) + 1, @yes = 1, @cid = 1,
                        @input = RIGHT(@input,
                                       LEN(@input) - CHARINDEX(CHAR(10), @input))
                IF LEFT(@tab, 1) = '0' 
                    SELECT  @tab = STUFF(@tab, 1, 1, ''), @yes = 0
                IF LEN(@tab) = 1 
                    SET @tab = @tab + 'T' + LTRIM(@tid)
                IF LEFT(@tab, 1) = '$' 
                    SET @tab = QUOTENAME(STUFF(@tab, 1, 1, ''))
                INSERT  INTO @tabs
                VALUES  ( @tab )
                IF @yes = 0 
                    SET @col = NULL
                ELSE 
                    SELECT  @col = LEFT(@input, CHARINDEX(CHAR(10), @input) - 1)
                            + ',',
                            @input = RIGHT(@input,
                                           LEN(@input) - CHARINDEX(CHAR(10),
                                                                  @input)),
                            @col = REPLACE(@col, ',', ':')
                WHILE CHARINDEX(CHAR(10), @input) > 0 
                    BEGIN
                        INSERT  INTO @data
                                SELECT  LEFT(@input,
                                             CHARINDEX(CHAR(10), @input) - 1)
                        SET @input = RIGHT(@input,
                                           LEN(@input) - CHARINDEX(CHAR(10),
                                                                  @input))
                        IF LEFT(@input, 1) IN ( '@', '#', '$' )
                            OR LEFT(@input, 2) IN ( '0@', '0#', '0$' ) 
                            BREAK
                    END
                DELETE  FROM @data
                WHERE   PATINDEX('%[^,-]%', data) = 0
                SELECT  @max = MAX(LEN(data) - LEN(REPLACE(data, ',', '')))
                FROM    @data
                UPDATE  @data
                SET     data = data + REPLICATE(',null',
                                                @max - LEN(data)
                                                + LEN(REPLACE(data, ',', '')))
                        + ','
                SET @max = ISNULL(LEN(@col) - LEN(REPLACE(@col, ':', '')), 0)
                INSERT  INTO @code
                        SELECT  id, NULL
                        FROM    @data
                        ORDER BY id
                WHILE EXISTS ( SELECT   1
                               FROM     @data
                               WHERE    CHARINDEX(',', data) > 0 ) 
                    BEGIN
                        INSERT  INTO @temp
                                SELECT  id,
                                        NULLIF(LEFT(data, CHARINDEX(',', data) - 1),
                                               'null')
                                FROM    @data
                                ORDER BY id
                        UPDATE  @data
                        SET     data = RIGHT(data,
                                             LEN(data) - CHARINDEX(',', data))
                        IF EXISTS ( SELECT  1
                                    FROM    @temp a
                                            INNER JOIN @data b ON a.id = b.id
                                                                  AND a.temp IS NOT NULL
                                                                  AND LEFT(b.data,
                                                                  4) NOT IN ( '',
                                                                  'null' ) )
                            AND NOT EXISTS ( SELECT 1
                                             FROM   @temp a
                                                    INNER JOIN @data b ON a.id = b.id
                                                                  AND a.temp IS NOT NULL
                                                                  AND LEFT(b.data,
                                                                  4) NOT IN ( '',
                                                                  'null' )
                                                                  AND ISDATE(a.temp
                                                                  + SPACE(1)
                                                                  + LEFT(b.data,
                                                                  CHARINDEX(',',
                                                                  b.data) - 1)) = 0 ) 
                            BEGIN
                                UPDATE  a
                                SET     a.temp = a.temp + SPACE(1) + LEFT(b.data,
                                                                  CHARINDEX(',',
                                                                  b.data) - 1)
                                FROM    @temp a
                                        INNER JOIN @data b ON a.id = b.id
                                WHERE   a.temp IS NOT NULL
                                        AND LEFT(b.data,
                                                 CHARINDEX(',', b.data) - 1) <> 'null'
                                UPDATE  @data
                                SET     data = RIGHT(data,
                                                     LEN(data) - CHARINDEX(',',
                                                                  data))
                            END
                        IF NOT EXISTS ( SELECT  1
                                        FROM    @temp
                                        WHERE   temp IS NOT NULL ) 
                            SET @type = ' sql_variant'
                        ELSE 
                            IF NOT EXISTS ( SELECT  1
                                            FROM    @temp
                                            WHERE   temp IS NOT NULL
                                                    AND ISNUMERIC(temp) = 0 ) 
                                BEGIN
                                    IF EXISTS ( SELECT  1
                                                FROM    @temp
                                                WHERE   PATINDEX('%[Ee]%', temp) > 0 ) 
                                        SET @type = ' float'
                                    ELSE 
                                        IF EXISTS ( SELECT  1
                                                    FROM    @temp
                                                    WHERE   CHARINDEX('.', temp) > 0 ) 
                                            BEGIN
                                                SELECT  @lenp = MAX(CHARINDEX('.',
                                                                  CASE
                                                                  WHEN LEFT(temp,
                                                                  1) = '-'
                                                                  THEN RIGHT(temp,
                                                                  LEN(temp) - 1)
                                                                  ELSE temp
                                                                  END)) - 1,
                                                        @lens = MAX(CHARINDEX('.',
                                                                  REVERSE(temp)))
                                                        - 1
                                                FROM    @temp
                                                WHERE   CHARINDEX('.', temp) > 0
                                                IF @lenp + @lens > @@max_precision 
                                                    SET @type = ' float'
                                                ELSE 
                                                    SET @type = ' numeric('
                                                        + LTRIM(@lenp + @lens)
                                                        + ',' + LTRIM(@lens) + ')'
                                            END
                                        ELSE 
                                            IF EXISTS ( SELECT  1
                                                        FROM    @temp
                                                        WHERE   LEN(temp) > 1
                                                                AND LEFT(temp, 1) = '0' ) 
                                                SELECT  @type = ' varchar('
                                                        + LTRIM(MAX(DATALENGTH(temp)))
                                                        + ')'
                                                FROM    @temp
                                                WHERE   temp IS NOT NULL
                                            ELSE 
                                                IF EXISTS ( SELECT
                                                                  1
                                                            FROM  @temp
                                                            WHERE temp IS NOT NULL
                                                                  AND LEN(temp) <> 8
                                                                  OR ISDATE(temp) = 0 ) 
                                                    BEGIN
                                                        SELECT  @lenp = ISNULL(MAX(LEN(temp)),
                                                                  0)
                                                        FROM    @temp
                                                        WHERE   LEFT(temp, 1) <> '-'
                                                        SELECT  @lens = -ISNULL(MAX(LEN(temp)
                                                                  - 1), 0)
                                                        FROM    @temp
                                                        WHERE   LEFT(temp, 1) = '-'
                                                        IF @lenp <= ABS(@lens) 
                                                            SELECT
                                                                  @lenp = @lenp
                                                                  + @lens,
                                                                  @lens = @lenp
                                                                  - @lens,
                                                                  @lenp = @lenp
                                                                  - @lens
                                                        IF ABS(@lenp) > 38 
                                                            SET @type = ' varchar('
                                                                + LTRIM(CASE
                                                                  WHEN @lenp > 0
                                                                  THEN @lenp
                                                                  ELSE ABS(@lenp)
                                                                  + 1
                                                                  END) + ')'
                                                        ELSE 
                                                            IF EXISTS ( SELECT
                                                                  1
                                                                  FROM
                                                                  @temp
                                                                  WHERE
                                                                  CAST(temp AS NUMERIC(38,
                                                                  0)) NOT BETWEEN -9223372036854775808
                                                                  AND
                                                                  9223372036854775807 ) 
                                                                SET @type = ' numeric('
                                                                  + LTRIM(ABS(@lenp))
                                                                  + ',0)'
                                                            ELSE 
                                                                IF EXISTS ( SELECT
                                                                  1
                                                                  FROM
                                                                  @temp
                                                                  WHERE
                                                                  CAST(temp AS NUMERIC(38,
                                                                  0)) NOT BETWEEN -2147483648
                                                                  AND
                                                                  2147483647 ) 
                                                                  SET @type = ' bigint'
                                                                ELSE 
                                                                  SET @type = ' int'
                                                    END
                                                ELSE 
                                                    SET @type = ' datetime'
                                END
                            ELSE 
                                IF NOT EXISTS ( SELECT  1
                                                FROM    @temp
                                                WHERE   temp IS NOT NULL
                                                        AND ISDATE(temp) = 0 ) 
                                    SET @type = ' datetime'
                                ELSE 
                                    SELECT  @type = ' varchar('
                                            + LTRIM(MAX(DATALENGTH(temp))) + ')'
                                    FROM    @temp
                                    WHERE   temp IS NOT NULL
                        IF CHARINDEX(':', @col) > 0 
                            SET @col = STUFF(@col, CHARINDEX(':', @col), 1,
                                             @type + CASE WHEN @cid = @max THEN ''
                                                          ELSE ','
                                                     END)
                        ELSE 
                            SET @col = ISNULL(@col + ',', '') + 'c' + LTRIM(@cid)
                                + @type
                        UPDATE  a
                        SET     a.code = ISNULL(a.code + ',', 'select ')
                                + CASE WHEN SUBSTRING(@type, 2, 3) IN ( 'flo',
                                                                  'num', 'big',
                                                                  'int' )
                                       THEN ISNULL(b.temp, 'null')
                                       ELSE ISNULL(QUOTENAME(b.temp, CHAR(39)),
                                                   'null')
                                  END
                        FROM    @code a
                                INNER JOIN @temp b ON a.id = b.id
                        DELETE  FROM @temp
                        SET @cid = @cid + 1
                    END
                IF @max > @cid - 1 
                    BEGIN
                        SELECT  @col = STUFF(@col, LEN(@col), 1, ' sql_variant'),
                                @col = REPLACE(@col, ':', ' sql_variant,')
                        UPDATE  @code
                        SET     code = code + REPLICATE(',null', @max - @cid + 1)
                    END
                SET @sql = NULL
                SELECT  @sql = ISNULL(@sql + ' union all' + CHAR(13) + CHAR(10),
                                      '') + code
                FROM    @code
                ORDER BY id
                PRINT '--> 测试数据: ' + @tab
                PRINT CASE LEFT(@tab, 1)
                        WHEN '@' THEN 'declare ' + @tab + ' table'
                        WHEN '#'
                        THEN 'if object_id(''tempdb.dbo.' + @tab
                             + ''') is not null drop table ' + @tab + CHAR(13)
                             + CHAR(10) + 'create table ' + @tab
                        ELSE 'if object_id(''' + @tab
                             + ''') is not null drop table ' + @tab + CHAR(13)
                             + CHAR(10) + 'create table ' + @tab
                      END + ' (' + @col + ')'
                PRINT 'insert into ' + @tab
                PRINT @sql
                DELETE  FROM @data
                DELETE  FROM @code
            END
        SET @sql = NULL
        SELECT  @sql = ISNULL(@sql + CHAR(13) + CHAR(10), CHAR(13) + CHAR(10))
                + 'select * from ' + name
        FROM    @tabs
        ORDER BY id
        PRINT @sql
        SET nocount OFF
    go
    
    
  • 相关阅读:
    WPF中ListBoxItem绑定一个UserControl的学习
    Server.Transfer和Response.Redirect的区别
    4个程序员的一天
    (转)让ADO.NET Entity Framework支持Oracle数据库
    IIS操作类
    HttpHandler与HttpModule区别
    网站性能优化的34条黄金法则
    oracle9i/10g/11g各种下载
    WCF简要介绍
    软件系统的稳定性
  • 原文地址:https://www.cnblogs.com/ToddLai/p/2287384.html
Copyright © 2011-2022 走看看