在插入时自动将字符串修剪到适当的长度

发布于 2024-07-25 04:52:36 字数 361 浏览 6 评论 0原文

我在 MySQL 中有一个包含各种 VARCHAR 字段的表。 我想通过 PHP 从表单插入一些用户数据。 显然,如果我知道 PHP 中的字段长度,我可以使用 substr() 限制数据长度。 但这违反了 DRY(字段长度存储在 MySQL 中并作为我的 PHP 脚本中的常量)。 有没有办法让我配置 INSERT,以便它自动截断过长的字符串,而不是失败?

编辑:当我的字符串过长时,它在 PHP/PDO 中失败(或至少导致异常)。 不确定我必须在 PHP/PDO 中做什么,所以它做正确的事情。

编辑2:呃。 这是错误的做法; 即使我让它在 INSERT 上正常工作,如果我想检查重复的字符串,它也不会正确匹配。

I have a table with various VARCHAR fields in MySQL. I would like to insert some user data from a form via PHP. Obviously if I know the field lengths in PHP, I can limit the data length there with substr(). But that sort of violates DRY (field length stored in MySQL and as a constant in my PHP script). Is there a way for me to configure an INSERT so it automatically chops off excessively-long strings, rather than fails?

edit: it's failing (or at least causing an exception) in PHP/PDO, when I have excessively long strings. Not sure what I have to do in PHP/PDO so it Does The Right Thing.

edit 2: Ugh. This is the wrong approach; even if I get it to work ok on INSERT, if I want to check for a duplicate string, it won't match properly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谎言月老 2024-08-01 04:52:36

实际上,MySQL 默认情况下会将字符串截断为列宽。 它会生成警告,但允许插入。

mysql> create table foo (str varchar(10));
mysql> insert into foo values ('abcdefghijklmnopqrstuvwxyz');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'str' at row 1 | 
+---------+------+------------------------------------------+
mysql> select * from foo;
+------------+
| str        |
+------------+
| abcdefghij | 
+------------+

如果设置严格的 SQL 模式,它将把警告变成错误并拒绝插入。


回复您的评论:SQL 模式是 MySQL 服务器配置。 可能不是 PDO 造成的,但另一方面这是可能的,因为任何客户端都可以为其会话设置 SQL 模式。

您可以使用以下语句检索当前全局或会话 sql_mode 值:

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

默认值应为空字符串(未设置模式)。 您可以在 my.cnf 文件中使用 mysqld 的 --sql-mode 选项或使用 SET 语句设置 SQL 模式。

更新:MySQL 5.7及更高版本默认设置严格模式。 请参阅 https://dev.mysql.com/doc/refman /5.7/en/sql-mode.html

Actually, MySQL truncates strings to the column width by default. It generates a warning, but allows the insert.

mysql> create table foo (str varchar(10));
mysql> insert into foo values ('abcdefghijklmnopqrstuvwxyz');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'str' at row 1 | 
+---------+------+------------------------------------------+
mysql> select * from foo;
+------------+
| str        |
+------------+
| abcdefghij | 
+------------+

If you set the strict SQL mode, it turns the warning into an error and rejects the insert.


Re your comment: SQL mode is a MySQL Server configuration. It probably isn't PDO that's causing it, but on the other hand it's possible, because any client can set SQL mode for its session.

You can retrieve the current global or session sql_mode value with the following statements:

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

The default should be an empty string (no modes set). You can set SQL mode in your my.cnf file, with the --sql-mode option for mysqld, or using a SET statement.

Update: MySQL 5.7 and later sets strict mode by default. See https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

沙沙粒小 2024-08-01 04:52:36

您可以使用列元数据来检查字符串长度。 (PDOStatement->getColumnMetaPHP 手册)

获取整个表的元数据方式

$query = $conn->query("SELECT * FROM places");
$numcols = $query->columnCount();

$tablemeta = array();
for ($i = 0; $i < $numcols; $i++) {
    $colmeta = $query->getColumnMeta($i);
    $tablemeta[$colmeta['name']] = $colmeta;
}

You can use column metadata to check string length. (PHP Manual on PDOStatement->getColumnMeta)

Get metadata for whole table this way

$query = $conn->query("SELECT * FROM places");
$numcols = $query->columnCount();

$tablemeta = array();
for ($i = 0; $i < $numcols; $i++) {
    $colmeta = $query->getColumnMeta($i);
    $tablemeta[$colmeta['name']] = $colmeta;
}
悲凉≈ 2024-08-01 04:52:36

您可以查询 information_schema 来获取列的长度,并使用该数据在插入之前进行截断,但这会带来不必要的开销。 只需关闭此语句的严格 SQL 模式即可:

SET @prev_mode = @@sql_mode;
SET sql_mode = '';
INSERT blah....;
SET sql_mode = @prev_mode;

you could query information_schema to get the lenght of the column and use that data to truncate before insert, but that's more overhead than necessary. just turn off strict SQL mode for this statement:

SET @prev_mode = @@sql_mode;
SET sql_mode = '';
INSERT blah....;
SET sql_mode = @prev_mode;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文