2

我在处理多个文档时遇到了挑战,特别是处理数据库中的重复文件名。我正在尝试创建一个管理员可以在其中添加 HTML 文档的系统。他将输入两个字段:文档名称及其源代码。

添加文档时,名称(例如“A Page”)和文件名(基于名称,例如“a_page.html”)将插入数据库,并在服务器上创建包含源代码的文件。

现在的问题是如果我尝试添加另一个具有相同名称的文档(例如“A Page”)会发生什么。我希望文件名是“a_page_2.html”,以免覆盖现有文件。如果另一个同名,“a_page_3.html”等等。

有没有简单的SQL语句来实现?

4

2 回答 2

1

不,没有简单的说法。可能已经有 a_page_2.html 了。

因此,只需让您的文档名称已经是唯一的:

  • 在数据库中插入新记录
  • 获取唯一标识
  • 通过将给定的名称和 id 放在一起,使用此 id 创建文件

选择文档名称时,您可以这样做

SELECT concat(name,'_',id) as name ...

它类似于 Stackoverflow 创建问题 url 的方式:

/questions/14919687/on-insert-how-can-i-change-the-duplicate-name-to-something-else-in-the-database/
            ^ id    ^ conventional name that can have 1000s duplicates

您也可以完全摆脱传统名称,只留下 id:
http://stackoverflow.com/questions/14919687/仍然有效

于 2013-02-17T09:38:39.813 回答
-1
  • 制作文件名列UNIQUE
  • 尝试插入,如果出现重复键错误,请重复添加数字直到成功

使用 PDO,它可能看起来像这样:

class QueryException extends RuntimeException { }
class DuplicateKeyException extends QueryException { }

function executeInsert(PDOStatement $stmt) {
    try {
        $stmt->execute();
    } catch (PDOException $e) {
        switch ($e->errorInfo[1]) {
            case 1062:
                throw new DuplicateKeyException($e->getMessage(), null, $e);
            default:
                throw new QueryException($e->getMessage(), null, $e);
        }
    }
}

$filename = 'a_page';
$contents = '<title>test</title>';

$stmt = $pdo->prepare('INSERT INTO documents (filename,contents) VALUES (:filename,:contents)');
$repeat = true; $counter = 0;
while ($repeat)
    try {
        $stmt->bindValue(
            ':filename',
            $filename . ($counter > 0 ? ("-$counter" : '') . '.html'
        );
        $stmt->bindValue(':contents', $contents);
        executeInsert($stmt);
        $repeat = false;
    } catch (DuplicateKeyException $e) {
        $repeat = true;
        $counter++;
    } catch (QueryException $e) {
        $repeat = false;
        // error handling here
    }
}
于 2013-02-17T10:40:30.297 回答