Select语句的SQL错误处理

时间:2013-01-24 16:26:06

标签: sql-server-2008

我使用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.

我是否有困难来确定导致问题的列/行是否有很多列,并且错误没有具体说明。有些人可以给我一个例子,我可以追踪错误。提前谢谢!!!

1 个答案:

答案 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
*/