我使用UNION ALL将多个select语句组合在一起。 对于Eg:
Select col1,col2,...,coln from A
UNION ALL
Select Col1,Col2,...,coln from B
第二个表中的一个列具有错误的值,并且在执行查询时我得到以下错误。
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
我是否有困难来确定导致问题的列/行是否有很多列,并且错误没有具体说明。有些人可以给我一个例子,我可以追踪错误。提前谢谢!!!
答案 0 :(得分:0)
您可以尝试使用此脚本来比较这两个SELECT的元数据。为了获取元数据信息,我使用了sp_describe_cursor_columns系统过程(不太好用 - 是真的;在SQL Server 2008中可用),因为sp_describe_first_result_set从SQL Server 2012开始可用。
SET NOCOUNT ON;
DECLARE @Metadata TABLE (
select_num tinyint NOT NULL,
check (select_num IN (1,2)),
ordinal_position int not null,
primary key (select_num, ordinal_position),
column_name sysname,
column_size int,
data_type_sql smallint,
column_precision tinyint,
column_scale tinyint
)
DECLARE
@column_name sysname,
@ordinal_position int,
@column_characteristics_flags int,
@column_size int,
@data_type_sql smallint,
@column_precision tinyint,
@column_scale tinyint,
@order_position int,
@order_direction varchar(1),
@hidden_column smallint,
@columnid int,
@objectid int,
@dbid int,
@dbname sysname
DECLARE @ReturnSelect CURSOR
-- Metadata for the first query
DECLARE CursorSelect1 CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT TOP(0) ...
FROM A ...
OPEN CursorSelect1
EXEC sp_describe_cursor_columns @cursor_return=@ReturnSelect OUTPUT, @cursor_source='local', @cursor_identity=N'CursorSelect1'
WHILE (1=1)
BEGIN
FETCH NEXT FROM @ReturnSelect INTO
@column_name,
@ordinal_position,
@column_characteristics_flags,
@column_size,
@data_type_sql,
@column_precision,
@column_scale,
@order_position,
@order_direction,
@hidden_column,
@columnid,
@objectid,
@dbid,
@dbname
IF @@FETCH_STATUS=0
BEGIN
INSERT @Metadata (select_num, ordinal_position, column_name, data_type_sql, column_size, column_precision, column_scale)
VALUES (1, @ordinal_position, @column_name, @data_type_sql, @column_size, @column_precision, @column_scale); -- First SELECT
END
ELSE
BEGIN
BREAK
END
END
CLOSE CursorSelect1
DEALLOCATE CursorSelect1
CLOSE @ReturnSelect
DEALLOCATE @ReturnSelect
-- End of Metadata for the first query
-- Metadata for the second query
DECLARE CursorSelect2 CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT TOP(0) ...
FROM B ...
OPEN CursorSelect2
EXEC sp_describe_cursor_columns @cursor_return=@ReturnSelect OUTPUT, @cursor_source='local', @cursor_identity=N'CursorSelect2'
WHILE (1=1)
BEGIN
FETCH NEXT FROM @ReturnSelect INTO
@column_name,
@ordinal_position,
@column_characteristics_flags,
@column_size,
@data_type_sql,
@column_precision,
@column_scale,
@order_position,
@order_direction,
@hidden_column,
@columnid,
@objectid,
@dbid,
@dbname
IF @@FETCH_STATUS=0
BEGIN
INSERT @Metadata (select_num, ordinal_position, column_name, data_type_sql, column_size, column_precision, column_scale)
VALUES (2, @ordinal_position, @column_name, @data_type_sql, @column_size, @column_precision, @column_scale); -- Second SELECT
END
ELSE
BEGIN
BREAK
END
END
CLOSE CursorSelect2
DEALLOCATE CursorSelect2
-- End of Metadata for the second query
CLOSE @ReturnSelect
DEALLOCATE @ReturnSelect
SELECT s1.*, s2.*
FROM (
SELECT m.*, t.name AS user_type_name
FROM @Metadata m JOIN sys.types t ON m.data_type_sql=t.user_type_id
WHERE select_num=1
) s1 -- metadata for the first SELECT
INNER JOIN (
SELECT m.*, t.name AS user_type_name
FROM @Metadata m JOIN sys.types t ON m.data_type_sql=t.user_type_id
WHERE select_num=2
) s2 -- metadata for the second SELECT
ON s1.ordinal_position=s2.ordinal_position
WHERE s1.data_type_sql<>s2.data_type_sql -- It compares the data type for every column from these two SELECT queries
/*
-- or
SELECT s1.*, s2.*
FROM (SELECT m.*, t.name AS user_type_name FROM @Metadata m JOIN sys.types t ON m.data_type_sql=t.user_type_id WHERE select_num=1) s1 -- metadata for the first SELECT
FULL OUTER JOIN (SELECT m.*, t.name AS user_type_name FROM @Metadata m JOIN sys.types t ON m.data_type_sql=t.user_type_id WHERE select_num=2) s2 -- metadata for the second SELECT
ON s1.ordinal_position=s2.ordinal_position
WHERE s1.ordinal_position=s2.ordinal_position
AND s1.data_type_sql<>s2.data_type_sql -- It compares the data type for every column from these two SELECT queries
OR s1.ordinal_position IS NOT NULL AND s2.ordinal_position IS NULL
OR s1.ordinal_position IS NULL AND s2.ordinal_position IS NOT NULL
*/