目前正在研究java中的代码,该代码从位于各种文件夹中的data
文件中检索XML
,然后将文件本身和检索到的数据上传到SQL-server Database
。我不希望将任何重复的XML文件上传到数据库,但由于文件可以使用随机名称即时检查使用每个文件即将上传的Hash
,我将文件上传到下表:
XMLFILES
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
我用来上传文件的代码如下:
public int UploadFile
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个唯一文件,问题是即时通讯使用rowCount
检查文件是否已上传,以及文件是否因为重复文件而未上传,我也没有将data
的{{1}}上传到数据库中,像这样(下面的代码是一个片段来说明我正在做的事情):
file
问题是方法int rowCount=UploadFile(Path,pathID);
if (rowCount==1){
//UPLOAD DATA
}
中的executeUpdate()
总是返回UploadFile
,即使1
中没有受影响的行,这里是否有遗漏?我无法找到我的代码有什么问题,是database
我正在做一个返回IF NOT EXISTS
的问题吗?
答案 0 :(得分:0)
可能是当IF块中的SELECT找到现有行时,它会被计算并返回。
如果没有抛出异常,你可以在没有IF NOT EXISTS检查的情况下尝试INSERT,看看是否是这种情况。如果您没有某种类型的密钥阻止它们被插入,您可能会得到重复项,或者如果您有一个阻止插入的密钥,您可能会收到异常。值得测试看看你得到了什么。
如果SELECT返回1,则可能需要将它们拆分为两个语句,如果第一个找到一行,则只需跳过第二个语句的执行。您可以将它们保存在同一个事务中,基本上您的数据库正在执行当前编写的两个语句。这是更多的代码,但是如果你在同一个事务中执行,它对数据库的影响也是一样的。
答案 1 :(得分:0)
SQL语句返回的更新计数仅针对普通DML语句(INSERT
,UPDATE
或DELETE
)进行了明确定义。
没有为SQL脚本定义。
该值是服务器为脚本选择返回的值。对于MS SQL Server,它可能是语句/脚本末尾的@@ROWCOUNT
值:
将
@@ROWCOUNT
设置为受影响或读取的行数。
由于您正在执行SELECT
语句,因此它会设置@@ROWCOUNT
值。如果为零,则执行INSERT
语句,该语句将覆盖@@ROWCOUNT
值。
假设永远不会有多个具有该大小/哈希的行,您将始终获得1的计数。