2009-06-19 19 views
1

我有一個在MySQL中有各種VARCHAR字段的表。我想通過PHP插入一些表單中的用戶數據。很明顯,如果我知道PHP中的字段長度,我可以用substr()來限制那裏的數據長度。但是這種做法違反了DRY(字段長度存儲在MySQL中,並且在我的PHP腳本中是一個常量)。有沒有辦法讓我配置一個INSERT,這樣它會自動切斷過長的字符串,而不是失敗?在插入時自動將字符串剪輯到合適的長度

編輯:當我的字符串過長時,它在PHP/PDO中失敗(或至少導致一個異常)。不知道我必須在PHP/PDO中做什麼,所以它是正確的。

編輯2:呃。這是錯誤的方法;即使我能在INSERT上正常工作,如果我想檢查重複的字符串,它也不會正確匹配。

+1

不該你知道你的字段的長度你插入之前......在你知道你打算將哪些字段成? – 2009-06-19 16:57:16

+1

要保持DRY,您可以讀取數據庫字段的長度,並在PHP中使用它來剪切輸入字符串。但我認爲你的應用程序(PHP代碼)必須知道你想保存的數據類型。這意味着你應該在PHP中配置它。 – powtac 2009-06-19 16:57:17

回答

8

實際上,默認情況下,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文件中設置SQL模式,使用mysqld的--sql-mode選項或使用SET語句。

有關SQL模式的完整文檔,請參閱http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html

0

您可以查詢information_schema以獲取列的長度並在插入之前使用該數據截斷,但這比開銷更多。只需爲此語句關閉嚴格的SQL模式:

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

您可以使用列元數據來檢查字符串長度。 (PHP Manual on PDOStatement->getColumnMeta

獲取元數據的整個表這樣

$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; 
}