2016-10-01 43 views
4

在遷移到新服務器後,執行SELECT查詢後,如果請求的列值爲NULL,Perl的DBI::fetchrow_array()返回看起來像是空字符串:defined()返回1和length()返回0Perl DBI :: fetchrow_array()給NULL賦值爲空而不是undef

一切我讀告訴我,我應該從NULL得到民主基金,實際上這是它的工作原理我的舊服務器上的方式。新服務器有一個MySQL數據庫的副本,我使用導出SQL導入SQL的功能Sequel Pro,我在我的Mac上運行的MySQL gui。對於這兩個數據庫,在Sequel Pro中明確指示的值都是灰色的NULL,如果我以交互方式運行mysql,則爲NULL。例如,看到name在這份成績單:

mysql> SELECT * from trials WHERE id = 26069 ; 
+-------+----------+-----------+---------+--------+ ... 
| id | language | numTrials | name | status | ... 
+-------+----------+-----------+---------+--------+ ... 
| 26069 | en  |   3 | NULL | Done | ... 
+-------+----------+-----------+---------+--------+ ... 
1 row in set (0.00 sec) 

我的舊服務器運行的是較舊的套裝:

  • 的Perl 5.10.1與5.22.1
  • DBI 1.634 1.636對比
  • DBD :: mysql 4.022 vs. 4.033

這是我的代碼,大約在fetchrow_array

@result = $statementHandle->fetchrow_array ; 

for my $value (@result) { 
    if (! utf8::is_utf8($value)) { 
     utf8::decode($value) ; 

     # Log values for debugging the NULL/undef issue: 
     my $aValue = $value ; 
     my $len = length($aValue) ; 
     if (!defined($value)) { 
      $aValue = "<unnndefined>" ; 
     } 
     print {*::STDLOG} info => "daValue l=$len : $daValue\n" ; 
    } 
} 

非常感謝任何人誰可以建議可能發生在這裏!

回答

4

您的代碼將已產生告警

Use of uninitialized value in subroutine entry 

您的來電utf8::decode($value)嘗試$value轉換爲字符串。如果你通過它undef那麼該值將被視爲空字符串(附帶警告)並解碼並存儲爲

將所有代碼放在條件語句中似乎很奇怪。當然,你只是想

utf8::decode($value) if $value and not utf8::is_utf8($value); 

然後其餘的代碼應該是獨立的字段的編碼狀態?

更好的是,您應該確保DBI通過將{mysql_enable_utf8mb4 => 1}選項添加到數據庫connect調用中,以自動編碼和解碼數據庫中的字符串。您還需要將CHARACTER SET utf8mb4添加到CREATE TABLECREATE DATABASE語句中。 (不要使用CHARACTER SET utf8;這是真正的UTF-8的子集,每個字符限制爲三個字節。)當然,如果需要,可以在初始創建之後使用ALTER TABLE

+0

賓果。正如你所建議的那樣,簡單地刪除那個utf8 :: decode($ value),我現在可以像預期的那樣得到undef。 –

+0

我沒有看,因爲我的舊服務器具有完全相同的代碼,並正常工作。正如你所建議的那樣,可能在數據庫配置方面有些不同之處,並且我需要根據你的解釋深入研究。多年來一直在我的待辦事項清單中列舉出一些在這個系統中很明顯的UTF8惡意軟件。它對於非ASCII字符運行良好,但有證據表明多個編程錯誤彼此取消:(( –

+1

原來,涉及'utf8 :: decode()'的舊代碼是一個草率的解決方法,這個數據庫有一個混雜的UTF-8數據存儲爲Latin-1,除了完全刪除這些代碼,並且在'connect()'期間啓用'utf8mb4',我需要[轉換混蛋數據](http:// stackoverflow.com/questions/9407834/mysql-convert-latin1-characters-on-a-utf8-table-into-utf8)。 –