【发布时间】:2019-01-23 19:07:47
【问题描述】:
我有以下插入查询,它从 OriginalData 表中选择记录,其中所有数据类型均为 nvarchar(max),并将其插入到具有特定列定义的临时表中,即 MainAccount 的类型为 INT。
我正在逐行插入,因为如果OriginalData 表中有一条记录,其中MainAccount 的值为“测试”,那么它显然会导致转换错误并且插入将失败。 begin try 块用于更新出现错误的表。
但是,如果同一行有多个错误,我希望能够同时捕获它们,而不仅仅是第一个。
TRUNCATE TABLE [Temp]
DECLARE @RowId INT, @MaxRowId INT
SET @RowId = 1
SELECT @MaxRowId = MAX(RowId)
FROM [Staging].[FactFinancialsCoded_Abbas_InitialValidationTest]
WHILE(@RowId <= @MaxRowId)
BEGIN
BEGIN TRY
INSERT INTO [Temp] (ExtractSource, MainAccount,
RecordLevel1Code, RecordLevel2Code, RecordTypeNo,
TransDate, Amount, PeriodCode, CompanyCode)
SELECT
ExtractSource, MainAccount,
RecordLevel1Code, RecordLevel2Code, RecordTypeNo,
TransDate, Amount, PeriodCode, DataAreaId
FROM
[Staging].[FactFinancialsCoded_Abbas_InitialValidationTest]
WHERE
RowId = @RowId;
PRINT @RowId;
END TRY
BEGIN CATCH
Update [Staging].[FactFinancialsCoded_Abbas_InitialValidationTest]
Set ValidationErrors = ERROR_MESSAGE()
where RowId = @RowId
END CATCH
SET @RowId += 1;
END
【问题讨论】:
-
你为什么要通过痛苦的行来插入每个数据行? SQL Server 的强项是处理数据集,而不是自己处理每一行。
-
如果我正确理解了您的问题,那么您尝试做的事情几乎是不可能的。如果同一行中有多个错误,SQL 将在找到 first 的那一行时将其踢出。它不会继续寻找是否还有更多。您似乎希望您的查询成为一个数据验证应用程序,但这对您来说行不通。
-
"我正在逐行插入,因为如果 OriginalData 表中有一条 MainAccount 值为 'Test' 的记录,它显然会导致转换错误并且插入将失败。开始try 块用于更新出现错误的表。”为什么不能只使用
WHERE子句:INSERT INTO [Temp] (MainAccount, ...) select convert(int, MainAccount),... FROM [Staging].[FactFinancialsCoded_Abbas_InitialValidationTest] WHERE ISNUMERIC(MainAccount) = 1 -
你可以看看 TRY_PARSE 而不是通过痛苦的行来做这一行。
-
正要建议使用
TRY_PARSE而不是IS_NUMERIC。 :)
标签: sql sql-server tsql while-loop