1. 程式人生 > >Oracle中varchar2型別欄位長度限制使用問題

Oracle中varchar2型別欄位長度限制使用問題

為紀念中華人民共和國建軍90週年,特此一篇,以此紀念,我軍威武!!!


一、問題背景

專案中商品釋出,卻沒有儲存成功。

二、問題定位

初步判斷向資料庫中儲存時出現了錯誤,檢視日誌檔案,由於日誌檔案過大就採用grep進行搜尋(再一次說明grep 的強大)
其中 “ReserveProductService.update” 是要搜尋的關鍵字,catalina.out是日誌檔案, -n 顯示搜尋內容所在行數, -B 2 是顯示搜尋內容的前兩行(還有-C 前後幾行,-A 後幾行)將2換成更大值顯示內容如下
問題原因就出來了,由於插入內容長度超過了欄位長度限制注:為了方便分析錯誤日誌,將日誌內容修改如下,修改後會列印到對應的日誌檔案中,而不是全部輸入到tomcat控制檯中修改前
public static void dbLogError(StringBuffer errorMessage, Exception ex) {
		if (dbLog != null) {
			dbLog.error(errorMessage);
		}

		if (isPrintStackTrace && ex != null) {
			ex.printStackTrace();
		}
	}

修改後
public static void dbLogError(StringBuffer errorMessage, Exception ex) {
		if (dbLog != null) {
			dbLog.error(errorMessage);
		}

		if (isPrintStackTrace && ex != null) {
			dbLog.error(ex.getMessage(), ex);       //將錯誤棧列印到日誌檔案中
			ex.printStackTrace();
		}
	}


三、問題分析

檢視該欄位在資料庫中的設定
qualitystan              VARCHAR2(254) default '',
其就是254而前臺限制的是200字
if(trim(document.getElementsByName('bean.qualityStan')[0].value).length > 200){
        		alert("您輸入的質量標準超過了200字,請重新輸入!");
          		document.getElementsByName('bean.qualityStan')[0].focus();
          		return;
        	}

為什麼錯誤棧中卻提示的是實際值是314。看下Oracle中varchar2長度的說明oracle 中的dataType可參考http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements001.htm#SQLRF30020

檢視專案中用的編碼格式
SELECT parameter, VALUE FROM nls_database_parameters WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

NLS_NCHAR_CHARACTERSETAL16UTF16
NLS_CHARACTERSETZHS16GBK
說明:NLS_CHARACTERSET是資料庫字符集,NLS_NCHAR_CHARACTERSET是國家字符集(Oracle中字符集的介紹可參考http://www.cnblogs.com/KissKnife/archive/2011/11/11/2245410.html)
Oracle中有兩大類字元型資料,VARCHAR2是按照資料庫字符集來儲存資料。而NVARCHAR2是按照國家字符集儲存資料的。同樣,CHAR和NCHAR也一樣,一是資料庫字元符,一是國家字符集。

NVARCHAR2(N),其中的N是指字元數,不是位元組數。不過其最大長度是以位元組為單位,即4000位元組。

VARCHAR2(N),其中的N可能是指字元數,也可能是指位元組數。你可以顯式地在宣告的時候指定,比如VARCHAR2(10 BYTE)或者VARCHAR2(10 CHAR),未顯式指明時,則由引數NLS_LENGTH_SEMANTICS決定。


SQL> SELECT parameter, VALUE FROM nls_database_parameters;
PARAMETER                      VALUE
------------------------------ --------------------------------------------------------------------------------
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               ZHS16GBK
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY              $
NLS_COMP                       BINARY
NLS_LENGTH_SEMANTICS           BYTE
NLS_NCHAR_CONV_EXCP            FALSE
NLS_RDBMS_VERSION              11.2.0.4.0


那麼欄位QUALITYSTAN(varchar2(254))的編碼格式是ZHS16GBK,長度限制的是254個位元組。漢字的話會佔用2個位元組,因此如果是200個漢字的話,其實是400個位元組,而欄位長度確實254個位元組。因此這個時候還是超出了。

四、問題解決

1)可以修改資料庫欄位長度,或者型別(用varchar2(254char)或者nvarchar2(254))2)修改前端限制,這個比較方便簡單
if(trim(document.getElementsByName('bean.qualityStan')[0].value).length > 120){
        		alert("您輸入的質量標準超過了120字,請重新輸入!");
          		document.getElementsByName('bean.qualityStan')[0].focus();
          		return;
        	}


總結:看似簡單的問題,其實更需要紮實的基礎。

相關推薦

Oraclevarchar2型別長度限制使用問題

為紀念中華人民共和國建軍90週年,特此一篇,以此紀念,我軍威武!!!一、問題背景專案中商品釋出,卻沒有儲存成功。二、問題定位初步判斷向資料庫中儲存時出現了錯誤,檢視日誌檔案,由於日誌檔案過大就採用grep進行搜尋(再一次說明grep 的強大)其中 “ReserveProductService.update”

Oraclevarchar2型別長度是按照byte來定義的

很多新手在建資料庫或新增表、欄位時,會這樣忽略一個問題:ORACLE中VARCHAR2型別的欄位長度是按照byte來定義的。如果資料庫使用的字符集是GBK,GB2312或者其他定長字符集的話,這個問題似乎可以被忽略,因為只要把資料庫的欄位長度/2就可以得到你要限制插入該欄位

Mybatis框架--Ibatis框架踩坑01 -- JavaBigInteger型別問題!

       在Mybatis框架、 Ibatis框架中, 不支援Java中的 java.math.BigInteger 型別欄位, 支援 java.math.BigDecimal 型別欄位。若Java實體類中,使用 java.math.BigInteger 型別欄位,在

查詢Oracle帶有Clob的表的大小

在oracle裡面,由於lob欄位有獨立的lob segment來儲存,所以查詢需要DBA_SEGMENTS S, DBA_INDEXES  2張表結合才可查出結果。 以下是實驗SQL說明: 表名:GJ_NORM_POOL 表歸屬使用者名稱:ORACLE

Mybatis處理DB2Blob型別的一種方法

簡單來說,就是把Blob欄位對應的屬性的型別設定為byte[],然後在對映xml中存的時候在該欄位出指定為Blob型別就可以了。 例子 EB_COMM_NEWS表中,CONTENT為BLOB型別 在實體類EbCommNews中,對應的屬性為private byte[] CON

oracle為shape新增索引

表名為oscline,shape欄位的格式為sdo_geometry INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  VALUES ('OSCLINE', 'shape', &nb

Sql Server資料庫Identity型別的使用

大家在建立資料庫的時候肯定是經常使用Identity標識欄位型別的。下面就介紹兩個使用這種型別欄位的小技巧。 1.讓標識欄位從指定的數字開始計數: DBCC checkident (TableName,reseed,計數值-1) 如:讓customers表重新從1開始計數 d

記錄問題:mysqldatetime型別在後臺讀取與前端展示

1.資料庫欄位型別為datetime,model裡:@Column(name = "createtime", length = 20) private Date createTime;2.兩種將資料傳到前端的方法方法一:List<Map<String, Objec

解決在資料庫timestamp型別輸出在頁面上多餘的“.0”

在資料庫中createtime為timestamp型別,資料中的建立時間是沒有後綴'.0',傳到網頁上就出現'.0',在後臺程式碼中更改時間格式。程式碼實現:                  for (ExamRecords examRecords : examRecord

Oracle怎麼檢查 是否包含 ' 單引號

1、用chr函式,找到單引號的assciiSQL> select * from test1 where description like '%'||chr(39)||'%';         ID DESCRIPTION----------- ------------

OracleNUMBER型別不指定長度和小數點精度與指定的區別!

在Oracle中Number型別可以用來儲存0,正負定點或者浮點數,可表示的資料範圍在  1.0 * 10(-130) —— 9.9...9 * 10(125) {38個9後邊帶88個0}的數字,當Oracle中的數學表示式的值>=1.0*10(126)時,Oracle

mysql 長度限制

分析MySQL資料型別的長度       MySQL有幾種資料型別可以限制類型的"長度",有CHAR(Length)、VARCHAR(Length)、TINYINT(Length)、SMALLINT(Length)、MEDIUMINT(Length)、INT(Length

oracle字元型按數字排序

今天在轉換資料時,遇到了一個主鍵排序的問題。字元型的主鍵,儲存的都是數字,資料導過來以後發現數據排序都是亂的,就想著按數字規則排序。 但發現to_number總是報錯,就想著裡面應該是有字元存在。後來使用了正則關係式,問題解決。 以下是正則關係式的兩種用法,記錄下來。 se

oracle按指定排序刪除重複記錄

       今天看了一下專案上的DBA針對某一模組中的業務寫的儲存過程,裡面資料清洗的過程中時常會進行排重操作,自己總結了一下oracle中排重的思路1,使用rowid來作為限制條件排重rowid與rownum的區別兩者都是偽列,rowid是物理結構上的,而rownum是邏

Oracle查詢某不為空或者為空的SQL語句怎麼寫

比如 insert into table a (a1,b1)values("a1",''); 對於這種情況,因為表裡存的是”,其實是沒有內容的,要查詢這個欄位,不能直接使用 select * from a where b1=''; sql中判斷非

MySQL資料庫tinyint型別讀取資料為true和false

vertx jdbc 取myaql資料也存在這樣的問題,按照如下在進行sql語句編寫時候加上*1就i可以了 今天遇到這麼一個問題,公司最近在做一個活動,然後資料庫需要建表,其中有個欄位是關於獎勵發放的狀態的欄位,結果讀取出來的值為true 一、解決讀取資料為true/

Incorrect datetime value: '' for column Mysql5.6 datetime 型別的插入問題

在5.0.45-community-nt-log中能正常執行的SQL,在5.6.21中不正常。 1. 1檢視資料庫版本 mysql> select database(), version(); +------------+-----------------------

MySQLfloat型別的顯示問題

由於受到版本和平臺的限制,同樣的SQL在不同的平臺上執行的結果可能會不一致。 影響:1. mysql在升級或遷移時可能會導致float型別的資料發生變化。 2. mysqldump建立的備份在slave上進行恢復,可能會遇到float型別的資料在master和slave上

設定oracle的blob,將xml檔案寫入到資料庫

http://hi.baidu.com/net1979/blog/item/1829e14ee7d26c0db2de0569.html可以將二進位制大物件 (BLOB) 作為二進位制或字元資料寫入資料庫,具體視資料來源的

ruby布林型別的非空校驗

無法用validate_presence_of來對boolean型別欄位進行非空校驗 migration程式碼 class CreateCorporateFinancials < ActiveRecord::Migration def self