簡體   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