我看到Java处理RAISERROR
引发的SQL Server错误的方式有所不同,具体取决于实际错误是什么,
- 违反唯一约束:SQL异常由Java Catch块捕获和处理
- 除以零:未捕获SQL异常
演示:
1。存储过程:uspTestRE
ALTER PROCEDURE demo.uspTestRE (
@inKey VARCHAR(5),--Primary Key value in TestRE table
@inDBZ VARCHAR(1) --Y/N flag to trigger Divide By Zero error
)
AS
BEGIN
SET xact_ABORT,NOCOUNT ON;
BEGIN TRY
BEGIN TRANSactION
--Insert record into TestRE table
INSERT INTO TestRE (tREKey) VALUES (@inKey);
--Trigger DBZ error
IF @inDBZ = 'Y'
BEGIN
SELECT 1/0;
END;
--Transaction is in a state to be committed
IF (xact_STATE())=1
BEGIN
COMMIT TRANSactION;
END;
END TRY
BEGIN CATCH
DeclARE
@errorMessage NVARCHAR(MAX) = ERROR_MESSAGE(),@errorState INT = ERROR_STATE(),@errorSeverity INT = ERROR_SEVERITY();
--Transaction is uncommitable so rollback
IF (xact_STATE()) = -1
BEGIN
ROLLBACK TRANSactION;
END;
RAISERROR(@errorMessage,@errorSeverity,@errorState);
RETURN 23;
END CATCH
END;
从SQLCMD执行SP时,它会生成以下错误消息:
测试1:违反密钥
Msg 50000,Level 14,State 1,Server WW-HV5FQV2,Procedure demo.uspTestRE,Line 44
Violation of PRIMARY KEY constraint 'PK__TestRE__0FEE01A3EEF4E2AE'. Cannot insert duplicate key in object 'dbo.TestRE'. The duplicate key value is (UKV).
测试2:被零除
Msg 50000,Level 16,Line 42
Divide by zero error encountered.
即两者的预期行为。
但是,我的Java程序却没有相同的行为。
2。 Java程序:uspTestRE.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.CallableStatement;
public class uspTestRE {
// Connect to DEMO_INST database as svcDemoInst Login
public static void main(String[] args) {
String connectionUrl =
"jdbc:sqlserver://localhost:1433;"
+ "database=DEMO;"
+ "user=svcDemoLogin;"
+ "password=Demo;"
+ "trustServerCertificate=true;"
+ "loginTimeout=30;";
ResultSet resultSet = null;
CallableStatement cstmt = null;
try {cstmt = DriverManager.getconnection(connectionUrl).prepareCall("{? = call demo.uspTestRE(?,?)}");
int i = 0;
cstmt.registerOutParameter(++i,java.sql.Types.INTEGER);
cstmt.setString(++i,args[0]);
cstmt.setString(++i,args[1]);
cstmt.execute();
int returnCode = cstmt.getInt(1);
System.out.println("Success: Stored Procedure Return Status: " + returnCode);
}
catch (SQLException e) {
System.out.println("Error Code: " + e.getErrorCode() +",Error Message: "+e.getMessage());
// e.printStackTrace();
}
}
}
当我在此处运行相同的测试用例时,得到以下信息:
测试1:违反关键(行为符合预期)
C:\>java uspTestRE UKV N
Error Code: 50000,Error Message: Violation of PRIMARY KEY constraint 'PK__TestRE__0FEE01A3EEF4E2AE'. Cannot insert duplicate key in object 'dbo.TestRE'. The duplicate key value is (UKV).
测试2:被零除(不会被困)
C:\>java uspTestRE DBV Y
Success: Stored Procedure Return Status: 23
有人可以向我解释为什么除以零的错误-被SQL Server捕获并在SP Catch块中处理-未被Java代码捕获的原因吗?
我能看到的两个错误之间唯一的区别是被零除错误是严重性16。