2011-08-03 34 views
0

我想找到一个调试insert-select语句的快速方法。 实施例:Sql select插入调试

Create table tbl_int (
     tabid int identity, 
     col1 bigint) 

Create table tbl_char(
     tabid int identity, 
     col2 nvarchar(255)) 


insert into tbl_char(col2) 
    select '1' union 
    select '2' union 
    select 'a' 

insert into tbl_int(col1) 
    select col2 
    from tbl_char 

当然,插入件选择上述运行失败并且显而易见的是,“A”不能被转换为bigint。但是当我在tbl_char中有1千万条记录时会发生什么。有没有找到错误源值的方法: “将数据类型nvarchar转换为bigint时出错。” P.s.使用转换或转换函数并用top扫描表,直到找到正确的值是有点太昂贵。

+0

是否要提取数字部分(如果存在)或忽略包含字符数据的所有行? – niktrs

+0

不,我只是想找到导致错误的值。在上面的例子'a'。 –

回答

2

你为什么不换行抛出异常到try/catch块的SQL有更多的信息关于它

BEGIN TRY 
    SELECT * 
     FROM sys.messages 
     WHERE message_id = 21; 
END TRY 
GO 
-- The previous GO breaks the script into two batches, 
-- generating syntax errors. The script runs if this GO 
-- is removed. 
BEGIN CATCH 
    SELECT ERROR_NUMBER() AS ErrorNumber; 
END CATCH; 
GO 

下都是错误的信息,您可以检查

ERROR_NUMBER() returns the error number. 

ERROR_MESSAGE() returns the complete text of the error message. The text includes the values supplied for any substitutable parameters such as lengths, object names, or times. 

ERROR_SEVERITY() returns the error severity. 

ERROR_STATE() returns the error state number. 

ERROR_LINE() returns the line number inside the routine that caused the error. 

ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred. 

http://msdn.microsoft.com/en-us/library/ms179296.aspx

如果这还不够,你甚至可以编写一个查询来选择所有记录,其中某些领域是无法转换为数字(在你的情况是有NVarChar不可兑换)

以下示例使用ISNUMERIC返回非数值的所有邮政编码。

SELECT City, PostalCode 
FROM Person.Address 
WHERE ISNUMERIC(PostalCode)<> 1 

http://msdn.microsoft.com/en-us/library/ms186272.aspx

+0

这是一个好的开始,但不幸的是,它仍然不能帮助我确定导致错误的价值。我可以找到关于错误的更多信息,但没有任何关于价值的信息。 –

+0

我已编辑我的答案 –

+0

我明白你的观点。但这并不是我期待的。即使使用isnumeric过滤数据,也可能会在转换时发生错误。我给你举个例子 select convert(bigint,'1e100') where isnumeric('1e100')= 1 –

-1

当你理解,转化为当你执行insert..select BIGINT char值。 因此,我们不能避免转换,但我们可以尝试避免第二个表扫描。 我建议为表tbl_int创建INSTEAD OF INSERT触发器。 在此触发器的主体中,您可以将char值转换为bigint,并且如果接收到错误,则可以将此char值插入登台表中。如果收敛时没有错误,则可以将此bigint值插入到tbl_int表中。

0

让我们从为什么要将不同数据类型的数据发送到另一个表开始?如果您不希望列中存在非整数数据,为什么要让它成为字符串数据呢?所以首先你需要看看是否有一个影响数据完整性的设计问题。

如果您正在从其他系统导入并且无法控制数据类型的使用,那么您需要在插入前清理数据。没有一个适合所有人的解决方案。您将不得不编写代码来查找所有不符合表格条件的数据,并按字段逐个数据类型将其移至数据类型。这可能比使用isnumeric(可能有误报,特别是如果里面还有小数信息)和isdate()更复杂,您可能需要编写特定于您的需求的函数。清理正确可能需要很长时间。您可能需要将这些值限制为某个子集,或者拥有一个转换表,将它们放入表中的内容转换为您的系统将接受的内容。建议先识别不良数据,将其移至异常表,然后根据不在异常表中的记录进行插入。