Sql server sql错误处理和输出
我有下面的代码,它遍历每一行,并为行中的每个值运行存储的过程。某些值失败,代码继续执行下一个值,直到为整个表运行SP为止 我需要知道的是,如何生成一个列表,列出它尝试和失败的所有行。我不希望它在失败时停止,因为它应该完成,但它应该让我知道它不适用于的rowsID,这样我就可以针对失败的行再次运行它Sql server sql错误处理和输出,sql-server,stored-procedures,error-handling,Sql Server,Stored Procedures,Error Handling,我有下面的代码,它遍历每一行,并为行中的每个值运行存储的过程。某些值失败,代码继续执行下一个值,直到为整个表运行SP为止 我需要知道的是,如何生成一个列表,列出它尝试和失败的所有行。我不希望它在失败时停止,因为它应该完成,但它应该让我知道它不适用于的rowsID,这样我就可以针对失败的行再次运行它 DECLARE @SP VARCHAR(50) DECLARE @ROWID INT DECLARE @MAXROW INT DECLARE @HEADOFFICECL
DECLARE @SP VARCHAR(50)
DECLARE @ROWID INT
DECLARE @MAXROW INT
DECLARE @HEADOFFICECLIENTINVOICEID VARCHAR(50)
DECLARE @OUTLETID VARCHAR(50)
DECLARE @COMPANYINFOID VARCHAR(50)
DECLARE @YEARID VARCHAR(50)
DECLARE @AREAID VARCHAR(50)
DECLARE @REPORTSTYLE VARCHAR(50)
DECLARE @STARTDATE VARCHAR(50)
DECLARE @ENDDATE VARCHAR(50)
DECLARE @SQL VARCHAR(1000)
SET @SP = 'FINANCE_BUDGETING_AGAINST_ACTUAL_REPORT'
SET @ROWID = 1
SELECT @MAXROW = MAX(ROWID)
FROM #AKTEMP
WHILE @ROWID <= @MAXROW
BEGIN
SELECT @HEADOFFICECLIENTINVOICEID = HEADOFFICECLIENTINVOICESID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @OUTLETID = OUTLETID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @COMPANYINFOID = COMPANYINFOID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @YEARID = YEARID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @AREAID = AREAID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @REPORTSTYLE = REPORTSTYLE
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @STARTDATE = CONVERT(VARCHAR(11), REPORTDATEFROM, 106)
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @ENDDATE = CONVERT(VARCHAR(11), REPORTDATETO, 106)
FROM #AKTEMP
WHERE ROWID = @ROWID
SET @SQL = @SP + ' @HEADOFFICECLIENTINVOICEID = ' + @HEADOFFICECLIENTINVOICEID +
', @OUTLETID = ' + @OUTLETID +
', @COMPANYINFOID = ' + @COMPANYINFOID +
', @YEARID = ' + @YEARID +
', @AREAID = ' + @AREAID +
', @REPORTSTYLE = ' + @REPORTSTYLE +
', @STARTDATE = ''' + @STARTDATE + '''' +
', @ENDDATE = ''' + @ENDDATE + ''''
PRINT @SQL
PRINT @ROWID
EXEC (@SQL)
SET @ROWID = @ROWID + 1
END
我使用Try-Catch错误处理进行处理。若出现错误,它将捕获表变量@TAB中的rowid 注意:我没有检查它,因为您的案例没有可用的模式
DECLARE @SP VARCHAR(50)
DECLARE @ROWID INT
DECLARE @MAXROW INT
DECLARE @HEADOFFICECLIENTINVOICEID VARCHAR(50)
DECLARE @OUTLETID VARCHAR(50)
DECLARE @COMPANYINFOID VARCHAR(50)
DECLARE @YEARID VARCHAR(50)
DECLARE @AREAID VARCHAR(50)
DECLARE @REPORTSTYLE VARCHAR(50)
DECLARE @STARTDATE VARCHAR(50)
DECLARE @ENDDATE VARCHAR(50)
DECLARE @SQL VARCHAR(1000)
SET @SP = 'FINANCE_BUDGETING_AGAINST_ACTUAL_REPORT'
SET @ROWID = 1
SELECT @MAXROW = MAX(ROWID)
FROM #AKTEMP
DECLARE @TAB TABLE (
SNO INT IDENTITY
,ROWID INT
)
WHILE @ROWID <= @MAXROW
BEGIN
BEGIN TRY
SELECT @HEADOFFICECLIENTINVOICEID = HEADOFFICECLIENTINVOICESID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @OUTLETID = OUTLETID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @COMPANYINFOID = COMPANYINFOID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @YEARID = YEARID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @AREAID = AREAID
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @REPORTSTYLE = REPORTSTYLE
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @STARTDATE = CONVERT(VARCHAR(11), REPORTDATEFROM, 106)
FROM #AKTEMP
WHERE ROWID = @ROWID
SELECT @ENDDATE = CONVERT(VARCHAR(11), REPORTDATETO, 106)
FROM #AKTEMP
WHERE ROWID = @ROWID
SET @SQL = @SP + ' @HEADOFFICECLIENTINVOICEID = ' + @HEADOFFICECLIENTINVOICEID + ', @OUTLETID = ' + @OUTLETID + ', @COMPANYINFOID = ' + @COMPANYINFOID + ', @YEARID = ' + @YEARID + ', @AREAID = ' + @AREAID + ', @REPORTSTYLE = ' + @REPORTSTYLE + ', @STARTDATE = ''' + @STARTDATE + '''' + ', @ENDDATE = ''' + @ENDDATE + ''''
PRINT @SQL
PRINT @ROWID
EXEC (@SQL) END
SET @ROWID = @ROWID + 1
END TRY
BEGIN CATCH
INSERT INTO @TAB
SELECT @ROWID
SET @ROWID = @ROWID + 1
END CATCH
END
SELECT * FROM @TAB
为了在不影响整个过程的情况下处理SQL错误,可以在SQL Server上使用classic及其语法 下面是我如何修改您的SQL代码的
Declare @SP varchar(50)
Declare @RowID int
Declare @MaxRow int
Declare @HeadofficeclientinvoiceID varchar(50)
Declare @Outletid varchar(50)
Declare @CompanyInfoID varchar(50)
Declare @YearID varchar(50)
Declare @AreaID varchar(50)
Declare @ReportStyle varchar(50)
Declare @Startdate varchar(50)
Declare @Enddate varchar(50)
Declare @sql varchar(1000)
Set @SP = 'Finance_Budgeting_Against_Actual_Report'
Set @RowID = 1
Select @MaxRow = MAX(rowid) from #AKTemp
While @RowID <= @MaxRow
Begin
Select
@HeadofficeclientinvoiceID = HeadOfficeClientInvoicesID,
@Outletid = Outletid,
@CompanyInfoID = CompanyInfoID,
@YearID = YearID,
@AreaID = AreaID,
@ReportStyle = ReportStyle,
@Startdate = CONVERT(VARCHAR(11),ReportDateFrom, 106),
@Enddate = CONVERT(VARCHAR(11),ReportDateTo, 106)
from #AKTemp where RowID = @RowID
Set @sql = @SP
+' @HeadofficeclientinvoiceID = '+ @HeadofficeclientinvoiceID
+ ', @Outletid = ' + @Outletid
+ ', @CompanyInfoID = ' + @CompanyInfoID
+ ', @YearID = ' + @YearID
+ ', @AreaID = ' + @AreaID
+ ', @ReportStyle = ' + @ReportStyle
+ ', @Startdate = ''' + @Startdate + ''''
+ ', @Enddate = ''' + @Enddate + ''''
Set @sql = @SP
BEGIN TRY
Exec(@sql)
END TRY
BEGIN CATCH
print 'Error:'
Print @Sql
Print @RowID
END CATCH;
Set @RowID = @RowID + 1
End
请注意,我使用一条SQL select语句从临时表行中选择参数。您可以修改代码以获得更好的性能
第二,请注意SQL Try…Catch块。
您可以根据需要修改CATCH块,以报告发生错误的行,而不是使用WHILE命令,另一个选项是使用SQL游标,它将迭代游标的所有行。有关基本信息,请参阅给定参考资料 请检查为您的案例实现的以下SQL游标代码。您将看到它与您的WHILE循环非常相似
Declare @SP varchar(50)
Declare @RowID int
Declare @MaxRow int
Declare @HeadofficeclientinvoiceID varchar(50)
Declare @Outletid varchar(50)
Declare @CompanyInfoID varchar(50)
Declare @YearID varchar(50)
Declare @AreaID varchar(50)
Declare @ReportStyle varchar(50)
Declare @Startdate varchar(50)
Declare @Enddate varchar(50)
Declare @sql varchar(1000)
Set @SP = 'Finance_Budgeting_Against_Actual_Report'
DECLARE mycursor CURSOR FAST_FORWARD FOR SELECT RowID from #AKTemp
OPEN mycursor
FETCH NEXT FROM mycursor INTO @RowID
WHILE @@FETCH_STATUS = 0
BEGIN
-------------------------------------------
Select
@HeadofficeclientinvoiceID = HeadOfficeClientInvoicesID,
@Outletid = Outletid
@CompanyInfoID = CompanyInfoID,
@YearID = YearID,
@AreaID = AreaID,
@ReportStyle = ReportStyle,
@Startdate = CONVERT(VARCHAR(11),ReportDateFrom, 106),
@Enddate = CONVERT(VARCHAR(11),ReportDateTo, 106)
from #AKTemp
where RowID = @RowID
Set @sql = @SP
+' @HeadofficeclientinvoiceID = '+ @HeadofficeclientinvoiceID
+ ', @Outletid = ' + @Outletid
+ ', @CompanyInfoID = ' + @CompanyInfoID
+ ', @YearID = ' + @YearID
+ ', @AreaID = ' + @AreaID
+ ', @ReportStyle = ' + @ReportStyle
+ ', @Startdate = ''' + @Startdate + ''''
+ ', @Enddate = ''' + @Enddate + ''''
BEGIN TRY
Exec(@sql)
END TRY
BEGIN CATCH
print 'Error:'
Print @Sql
Print @RowID
END CATCH;
-------------------------------------------
FETCH NEXT FROM mycursor INTO @RowID
END
CLOSE mycursor
DEALLOCATE mycursor
看起来不需要动态部件:
SET NOCOUNT ON
DECLARE
@ROWID INT,
@MAXROW INT,
@HEADOFFICECLIENTINVOICEID VARCHAR(50),
@OUTLETID VARCHAR(50),
@COMPANYINFOID VARCHAR(50),
@YEARID VARCHAR(50),
@AREAID VARCHAR(50),
@REPORTSTYLE VARCHAR(50),
@STARTDATE VARCHAR(50),
@ENDDATE VARCHAR(50),
@SQL VARCHAR(1000),
@crRows cursor
SET @crRows = CURSOR FAST_FORWARD
SELECT t.HeadofficeclientinvoiceID, t.Outletid, t.CompanyInfoID,
t.YearID, t.AreaID, t.ReportStyle, t.Startdate, t.Enddate
FROM #AKTEMP t
ORDER BY t.ROWID
OPEN @crRows
FETCH NEXT FROM @crRows
INTO @HeadofficeclientinvoiceID, @Outletid, @CompanyInfoID,
@YearID, @AreaID, @ReportStyle, @Startdate, @Enddate
WHILE @@FETCH_STATUS = 0
BEGIN TRY
EXEC dbo.FINANCE_BUDGETING_AGAINST_ACTUAL_REPORT
@HeadofficeclientinvoiceID = @HeadofficeclientinvoiceID,
@Outletid = @Outletid,
@CompanyInfoID = @CompanyInfoID,
@YearID = @YearID,
@AreaID = @AreaID,
@ReportStyle = @ReportStyle,
@Startdate = @Startdate
@Enddate = @Enddate
FETCH NEXT FROM @crRows
INTO @HeadofficeclientinvoiceID, @Outletid, @CompanyInfoID,
@YearID, @AreaID, @ReportStyle, @Startdate, @Enddate
END TRY
BEGIN CATCH
/* CATCH PART FROM @Shakeer's answer */
END
CLOSE @crRows
DEALLOCATE crRows
也许您需要将@RowID附加到游标获取部分,然后选择为什么不将失败行的ID放在一个表中呢?您好,是的,这样可以。但是我不知道我会键入什么代码来识别失败的ID和成功的ID。您可以使用一个select语句设置所有值,例如:select@OutletID=OuletID、@AreaID=AreaID、@。。。在AKTemp中,rowid=@rowidyou甚至可以用一个select来构建整个脚本:select@sql+='@OutletID='+castOutletID as varchar10+',“+…谢谢,这让查询变得更好