在数据库中将扩展前的文件名增加1

时间:2014-03-21 10:57:57

标签: mysql sql mysqli

我有一个上传文件的脚本,并将文件名的详细信息存储在数据库中。当文档上传时,如果DOCUMENT_ID已经存在,我希望能够更新数据库中文件的名称,以增加数字,例如_1,_2,_3(在文件扩展名之前)。表结构如下所示:

ID   |  DOCUMENT_ID  |  NAME            |  MODIFIED     |   USER_ID
33   |  81           |  document.docx   |  2014-03-21   |   1
34   |  82           |  doc.docx        |  2014-03-21   |   1
35   |  82           |  doc.docx        |  2014-03-21   |   1
36   |  82           |  doc.docx        |  2014-03-21   |   1

所以在上面的例子中,我希望ID 35 NAME为doc_1.docx,ID 36 NAME为doc_2.docx。

这是我到目前为止所处的地方。我检索了上传的最后一个文件详细信息:

$result1 = mysqli_query($con,"SELECT ID, DOCUMENT_ID, NAME, MODIFIED 
FROM b_bp_history ORDER BY ID DESC LIMIT 1");

while($row = mysqli_fetch_array($result1))
{
$ID = $row['ID'];
$documentID = $row['DOCUMENT_ID'];
$documentName = $row['NAME'];
$documentModified = $row['MODIFIED'];
}

因此,这将为我提供查看DOCUMENT_ID是否已存在所需的详细信息。现在我认为最好通过执行以下操作来确定它是否存在:

$sql = "SELECT ID, DOCUMENT_ID 
FROM b_bp_history WHERE DOCUMENT_ID = $documentID";
$result2 = mysqli_query($sql);

if(mysqli_num_rows($result2) >0){

/* This is where I need my update */

} else {

/* I don't need an update in here as it will automatically add to the database 
table with no number after it.  Not sure if I should always add the first one 
with a _1 after it so the increment is easy? */

}

从上面我可以看到,我需要在那里进行更新,基本上会检查名称后面是否存在数字,如果确实存在,则将其递增1。在else语句中,即如果DOCUMENT_ID不存在,我可以添加带有_1.docx的第一个,这样增量会更容易吗?

如果DOCUMENT_ID已经存在,则前半部分的更新需要检查扩展前的最后一个数字并增加+1,所以如果它是_1然后接下来将是_2。不知道如何做到这一点。我想要的最终结果是:

ID   |  DOCUMENT_ID  |  NAME              |  MODIFIED     |   USER_ID
33   |  81           |  document.docx     |  2014-03-21   |   1
34   |  82           |  doc.docx          |  2014-03-21   |   1
35   |  82           |  doc_1.docx        |  2014-03-21   |   1
36   |  82           |  doc_2.docx        |  2014-03-21   |   1

我希望能解释一下,谢谢你的帮助。

干杯, 安迪

2 个答案:

答案 0 :(得分:1)

我最近遇到了类似的问题,但我使用的是MSSQL而且我没有MySQL语法,所以这里有一个T-SQL代码。希望,它会对你有帮助!

declare 
    @id int,
    @document_id int,
    @document_name varchar(255),
    @append_name int,
    @name varchar(255),
    @extension varchar(10)

set @append_name = 1

select top 1
    @id = ID,
    @document_id = DOCUMENT_ID,
    @document_name = NAME
from
    b_bp_history

while exists (
    select *
    from b_bp_history
    where 
        NAME = @document_name and
        DOCUMENT_ID = @document_id and
        ID <> @id)
begin
    set @name = ''
    set @extension = ''

    declare @dot_index int -- index of dot-symbol in document name
    set @dot_index = charindex('.', reverse(@document_name))

    if (@dot_index > 0)
    begin       
        set @name = substring(@document_name, 0, len(@document_name) - @dot_index + 1)
        set @extension = substring(@document_name, len(@document_name) - @dot_index + 2, len(@document_name) - len(@name))
    end
    else
        set @name = @document_name

    if (@append_name > 1) -- if not first try to rename file
    begin
        if (right(@name, len(cast(@append_name - 1 as varchar)) + 1)) = '_' + cast(@append_name - 1 as varchar)
        begin
            set @name = substring(@name, 0, len(@name) - (len(cast(@append_name - 1 as varchar))))
        end
    end

    set @name = @name + '_' + cast(@append_name as varchar)

    if (len(@extension) > 0)
        set @document_name = @name + '.' + @extension
    else
        set @document_name = @name


    set @append_name = @append_name + 1
end

update b_bp_history
set NAME = @document_name
where ID = @id

答案 1 :(得分:1)

以下是工作更新查询

UPDATE document_history
INNER JOIN (SELECT dh.id, IF(rev.revision_id = 0, dh.name,REPLACE(dh.name, '.', CONCAT('_', rev.revision_id, '.'))) AS new_name, 
rev.document_id, rev.modified
FROM (
SELECT t0.document_id, t0.modified, count(*) - 1 AS revision_id
FROM document_history as t0
JOIN document_history as t1
ON t0.document_id = t1.document_id
AND t0.modified >= t1.modified
GROUP BY t0.document_id, t0.modified
ORDER BY t0.document_id ASC, t0.modified ASC) AS rev
JOIN document_history dh
ON dh.document_id = rev.document_id
AND dh.modified = rev.modified) update_record
ON document_history.id = update_record.id
SET document_history.name = update_record.new_name;

您可以在http://www.sqlfiddle.com/#!2/9b3cda/1

看到SQL小提琴

我使用UPDATE上此页面上提供的信息来汇总我的查询:

MySQL - UPDATE query based on SELECT Query

使用下面的页面生成Revision ID

ROW_NUMBER() in MySQL

还使用了Richard Pascual在他精心回答的答案中提供的架构。

希望此查询可以帮助您根据需要为文档命名。