当前位置: 首页 > 知识库问答 >
问题:

RAISERROR-Java客户机中SQLException行为的差异

郎长卿
2023-03-14
    null

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).
Msg 50000, Level 16, State 1, Server WW-HV5FQV2, Procedure demo.uspTestRE, Line 42
Divide by zero error encountered.

然而,我的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代码捕获?

共有1个答案

屠德宇
2023-03-14

谢谢你https://stackoverflow.com/users/7297700/David-Browne-Microsoft

我开始发布Github问题,他们请求的输出之一是JDBC跟踪。

当我这样做并比较2个跟踪输出时:

    null
    null

在另一篇文章中读到当SP返回resultset时RAISERROR的行为不同(在我的例子中是无意的),我更改了uspTestRE存储过程中的以下代码:

IF @inDBZ = 'Y'
  BEGIN
    SELECT 1/0;
  END;

IF @inDBZ = 'Y'
  BEGIN
    SET @dbz = 1/0;
  END;

这解决了我的问题。

 类似资料:
  • 我在做一个客户端/服务器应用程序。目前它的功能很好,但我需要添加一个“选项”。 server类如下所示: 因此许多客户端都能够连接到服务器。我的观点是:我希望一个连接的客户机(比如说,Client1)能够向他选择的另一个连接的客户机(Client2)发送一些东西。 我的问题是:Client1如何找到/拥有/检索Client2的套接字,因为所有的Client1都通过这个clientSocket在不同

  • connection方法似乎工作得很好,但当它执行调用“ExecuteQuery(sql)”方法的方法时,它会抛出SQLException。 我想我把jdbc驱动程序、ojdbc库和数据库配置得很好,但是我找不到为什么方法没有完成它的工作。有线索吗? 堆栈跟踪:

  • 问题内容: 我正在PostgreSQL 9.1中使用数据库,该数据库中的条目连续来自另一个程序。我正在6秒后从Ajax发送请求以获取最新条目.tomcat输出窗口显示异常— 之后程序也可以正常工作。当我通过查询检查我的postgres时- 它表明连接不断增加,但是在每个请求之后我都关闭了连接。我正在使用netbeans和struts 1.3。 //连接bean中的关闭方法是 每次在控制台“ con

  • 问题内容: 这里的正确语法是什么? 我试过了: 问题答案: 您可以在中将其用作字符串替换参数:

  • 在尝试设置一个简单的AndroidDriver时,我得到了一个。 所需的代码如下- Appium Java客户机版本是6.1.0。 我得到的异常如下所示- 在io.appium.java_client.android.androiddriver.getcapabilities(androiddriver.java:209)在org.openqa.selenium.remote.remoteWebd