繁体   English   中英

Java JDBC - PreparedStatement executeUpdate() 总是返回 1

[英]Java JDBC - PreparedStatement executeUpdate() always returns 1

目前,我正在编写 Java 代码,该代码从位于各种文件夹中的XML文件中检索data ,然后将文件本身和检索到的数据上传到SQL-server Database 我不想将任何重复的 XML 文件上传到数据库,但由于文件可以有随机名称,我正在使用我即将上传的每个文件中的Hash检查,我将文件上传到下表:

XML文件

CREATE TABLE [dbo].[XMLFiles](
    [PathID] [int] NOT NULL,
    [FileID] [int] IDENTITY(1,1) NOT NULL,
    [XMLFileName] [nvarchar](100) NULL,
    [FileSize] [int] NULL,
    [FileData] [varbinary](max) NULL,
    [ModDate] [datetime2](7) NULL,
    [FileHash] [nvarchar](100) NULL,
 CONSTRAINT [PK_XMLFiles] PRIMARY KEY CLUSTERED 
(
    [FileID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

我用来上传文件的代码如下:

公共 int 上传文件

public int UploadFile(String Path,int pathID) throws SQLException, SAXException, IOException {
        
                 int ID=-1;
                 String hash;
                 int len,rowCount=0;
                 String query;
                 PreparedStatement pstmt;
                    try {
                    File file = new File(Path);
                    hash=XMLRead.getFileChecksum(file);

                    FileInputStream fis = new FileInputStream(file);
                    len = (int) file.length();
                    query = (" IF NOT EXISTS "
                            + " (SELECT 1"
                            + " FROM XMLFiles"
                            + " WHERE FileSize="+len+" AND FileHash='"+hash+"')"
                            + " BEGIN"
                            + " INSERT INTO XMLFiles (PathID,XMLFileName,FileSize,FileData,ModDate,FileHash) "
                            + " VALUES(?,?,?,?,GETDATE(),?)"
                            + " END;");
                    pstmt = Con.prepareStatement(query);
                    pstmt.setInt(1, pathID);
                    pstmt.setString(2, file.getName());
                    pstmt.setInt(3, len);
                    pstmt.setBinaryStream(4, fis, len);
                    pstmt.setString(5, hash);
                    rowCount=pstmt.executeUpdate();
                    System.out.println("ROWS AFFECTED:-"+rowCount);

                    if (rowCount==0){
                            System.out.println("THE FILE: "+file.getName()+"ALREADY EXISTS IN THE SERVER WITH THE NAME: ");
                            System.out.println(GetFilename(hash));
                    }

                   } catch (Exception e) {
                   e.printStackTrace();
                    }
                    
                    
                        
                return rowCount;                              
            }

我正在使用 28 个文件执行程序,其中 4 个是重复文件但名称不同,我知道代码工作正常,因为在每次执行结束时只上传 24 个唯一文件,问题是我m 使用rowCount检查文件是否已上传,如果文件未上传,因为它是重复文件我也不会将该filedata上传到数据库,就像这样(以下代码是一个片段来说明我正在做的comprobation):

int rowCount=UploadFile(Path,pathID);                    
  if (rowCount==1){
       //UPLOAD DATA
  }

问题是方法UploadFile中的executeUpdate()总是返回1即使database中没有受影响的行,我在这里遗漏了什么吗?,我找不到我的代码有什么问题,是IF NOT EXISTS存在我正在做的返回1 comprobation?

可能是当您在 IF 块中的 SELECT 找到现有行时,它会被计数并返回。

如果没有抛出异常,您可以在没有 IF NOT EXISTS 检查的情况下尝试 INSERT,看看是否是这种情况。 如果您没有阻止插入的某种键,则最终可能会出现重复项,或者如果您有阻止插入的键,则可能会收到异常。 值得测试看看你得到了什么。

如果是 SELECT 返回 1,则可能需要将它们拆分为两个语句,如果第一个语句找到一行,则只需跳过第二个语句的执行。 您可以将它们保留在同一个事务中,基本上您的数据库正在执行当前编写的两个语句。 这是更多的代码,但如果你在同一个事务中做,它对你的数据库的影响是一样的。

SQL 语句返回的更新计数仅针对普通 DML 语句( INSERTUPDATEDELETE )定义良好。

它不是为 SQL 脚本定义的。

该值是服务器选择为脚本返回的任何值。 对于 MS SQL Server,它可能是语句/脚本末尾的@@ROWCOUNT值:

@@ROWCOUNT设置为受影响或读取的行数。

由于您正在执行SELECT语句,因此它设置了@@ROWCOUNT值。 如果为零,则执行INSERT语句,该语句将覆盖@@ROWCOUNT值。

假设该大小/散列永远不会超过一行,您将始终得到 1 的计数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM