根据提供的原始数据,生成测试数据表
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 功能:根据提问者提供的原始数据,生成测试数据表。 *
* 说明: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
浙公网安备 33010602011771号