ความแตกต่างระหว่าง varchar และ varchar2 ใน Oracle คืออะไร?


คำตอบ:


336

สำหรับตอนนี้พวกเขามีความหมายเหมือนกัน

VARCHARถูกสงวนไว้โดยOracleเพื่อสนับสนุนความแตกต่างระหว่างNULLและสตริงว่างในอนาคตตามที่ANSIกำหนดมาตรฐาน

VARCHAR2ไม่แยกความแตกต่างระหว่างNULLสตริงและว่างและจะไม่

หากคุณอาศัยสตริงที่ว่างเปล่าและเป็นสิ่งเดียวที่คุณควรใช้NULLVARCHAR2


40
ไม่เคยได้ยินเหตุผลนั้นมาก่อนมีประโยชน์ ขอบคุณ สำหรับเร็กคอร์ดมันยังคงไร้สาระอย่างสิ้นเชิงว่าประเภทตัวละครหลักใน Oracle คือ "varchar2" นั่นไม่ได้ทำให้คนอื่นเป็นกระบองที่น่ากลัวใช่ไหม ดูเหมือนว่าฉันจะแก้ไขปัญหาบางอย่างในสัปดาห์แรกของการเรียนรู้การเขียนโปรแกรม
Ian Varley

7
@Ian: ประเภทหลักเป็นVARCHAR2เพราะในปัจจุบันไม่มีประเภทที่VARCHARควรปฏิบัติ ที่จริงแล้วคุณไม่ควรใช้VARCHARเลยจนกว่าจะมีการใช้งานอย่างถูกต้อง
Quassnoi

11
ขอบคุณ @Quassnoi ดังนั้นฉันเดาว่าส่วนที่โง่คือ Oracle ไม่มี VARCHAR ที่เหมาะสมเหมือนกับฐานข้อมูลอื่น ๆ ใช่ไหม มีบางสิ่งที่โง่เกิดขึ้นที่นี่ฉันแน่ใจว่ามัน ... :)
Ian Varley

11
@Ian: เมื่อ Oracle ได้รับการพัฒนาไม่มีมาตรฐาน เมื่อถึงเวลามาตรฐานก็มีภาระของแอพรุ่นเก่าอยู่แล้ว เราทุกคนรู้ว่ามันเกิดขึ้นได้อย่างไร
Quassnoi

5
ขออภัยมันเป็นจริง @UnKnown ที่เขียนแสดงความคิดเห็นที่ไม่ถูกต้องผมก็ตอบสนองต่อ ความจริงที่ว่าwhere x is NULLผลตอบแทนที่แตกต่างจากการwhere x = ''ไม่ได้หมายความว่าNULLและ''มีความแตกต่างกันในทางใดทางหนึ่ง พฤติกรรมที่แตกต่างกันเกิดจากตัว=ดำเนินการ
Dan Lenski

38

ปัจจุบัน VARCHAR ทำงานเหมือนกับ VARCHAR2 อย่างไรก็ตามประเภทVARCHARนี้ไม่ควรใช้เนื่องจากถูกสงวนไว้สำหรับการใช้งานในอนาคต

นำมาจาก: ความแตกต่างระหว่าง CHAR, VARCHAR, VARCHAR2


@PhilipRego VARCHARไม่ควรใช้ ฉันแก้ไขมัน
bugybunny

29

นำมาจาก Oracle เวอร์ชันล่าสุดที่เสถียร 12.2: ประเภทข้อมูล

ความแตกต่างที่สำคัญคือVARCHAR2เป็นชนิดข้อมูลภายในและVARCHARเป็นชนิดข้อมูลภายนอก ดังนั้นเราต้องเข้าใจความแตกต่างระหว่างชนิดข้อมูลภายในและภายนอก ...

ภายในฐานข้อมูลค่าจะถูกเก็บไว้ในคอลัมน์ในตาราง ภายใน, Oracle หมายถึงข้อมูลในรูปแบบเฉพาะที่รู้จักกันเป็นชนิดข้อมูลภายใน

โดยทั่วไปแอปพลิเคชัน OCI (Oracle Call Interface) จะไม่ทำงานกับการแสดงประเภทข้อมูลภายในของข้อมูล แต่ด้วยประเภทข้อมูลภาษาโฮสต์ที่กำหนดไว้ล่วงหน้าโดยภาษาที่พวกเขาเขียน เมื่อข้อมูลถูกถ่ายโอนระหว่างแอปพลิเคชันไคลเอนต์ OCI และตารางฐานข้อมูลไลบรารี OCI จะแปลงข้อมูลระหว่างชนิดข้อมูลภายในและชนิดข้อมูลภายนอก

ประเภทภายนอกให้ความสะดวกสำหรับโปรแกรมเมอร์โดยทำให้สามารถทำงานกับชนิดภาษาโฮสต์แทนรูปแบบข้อมูลที่เป็นกรรมสิทธิ์ OCI สามารถทำการแปลงชนิดข้อมูลได้หลากหลายเมื่อถ่ายโอนข้อมูลระหว่างฐานข้อมูล Oracle และแอปพลิเคชัน OCI มีชนิดข้อมูลภายนอก OCI มากกว่าชนิดข้อมูลภายในของ Oracle

VARCHAR2ชนิดข้อมูลเป็นตัวแปรสตริงที่มีความยาวของตัวอักษรที่มีความยาวสูงสุด 4000 ไบต์ หากพารามิเตอร์ init.ora max_string_size เป็นค่าเริ่มต้นความยาวสูงสุดของVARCHAR2สามารถเป็น 4000 ไบต์ หากพารามิเตอร์ init.ora max_string_size = ถูกขยายความยาวสูงสุดของ a VARCHAR2สามารถเป็น 32767 ไบต์

VARCHARสตริงร้านค้าประเภทข้อมูลตัวอักษรของความยาวที่แตกต่างกัน 2 ไบต์แรกประกอบด้วยความยาวของสตริงอักขระและไบต์ที่เหลือประกอบด้วยสตริง ความยาวที่ระบุของสตริงในการโยงหรือการเรียกกำหนดต้องมีความยาวสองไบต์ดังนั้นVARCHARสตริงที่ใหญ่ที่สุดที่สามารถรับหรือส่งได้มีความยาว 65533 ไบต์ไม่ใช่ 65535

การทดสอบอย่างรวดเร็วในฐานข้อมูลที่ 12.2 แสดงให้เห็นว่าเป็นชนิดข้อมูลภายในออราเคิลยังคงถือว่าVARCHARเป็นpseudotypeVARCHAR2สำหรับ ไม่ใช่SYNONYMชนิดวัตถุจริงใน Oracle

SQL> select substr(banner,1,80) from v$version where rownum=1;
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production    

SQL> create table test (my_char varchar(20));
Table created.

SQL> desc test
Name                 Null?    Type
MY_CHAR                       VARCHAR2(20)

นอกจากนี้ยังมีความหมายของVARCHARตัวเลือก Precompiler ของProC / C ++ สำหรับโปรแกรมเมอร์ที่มีความสนใจลิงค์คือ: คู่มือโปรแกรมเมอร์ Pro * C / C ++


1
ดังนั้นนี่หมายความว่าVARCHARยังถือว่า'' == null?

2
ใช่. การอภิปรายประเภท VS ภายในภายนอกข้างต้นมาจากการอ้างอิง OCI การอ้างอิงภาษา SQL 12.2ยังคงมีคำสั่ง 'ไม่ใช้' ที่เหมือนกันซึ่งมีสำหรับ VARCHAR เสมอ
William Robertson

นี่คือเหตุผลที่ฉันพูดถึงความแตกต่างของ OCI มิฉะนั้นมันค่อนข้างสงวนไว้สำหรับการใช้งานในอนาคตหรือตามที่พวกเขาพูดว่า 'ความยาวผันแปร' ซึ่งอาจบอกใบ้ถึงชุดอักขระเช่นมัลติไบต์ UTF8 ...
sandman

1
คุณแสดงให้เห็นว่าค่าที่ประกาศเป็น VARCHAR จะถูกเก็บไว้ในฐานข้อมูลเป็น VARCHAR2 อย่างไรก็ตามความยาวสูงสุดของ VARCHAR (65533 ไบต์) มากกว่าความยาวสูงสุดของ VARCHAR2 (32767 ไบต์) ฐานข้อมูลจัดการกับสิ่งนี้อย่างไร
Piotr Dobrogost

IIRC นานมาแล้ว (อาจจะเป็น Oracle 6 หรือไม่) มีประเภท VARCHAR ที่ติดตั้งช่องว่างภายในผิดปกติหรือมีการตัดช่องว่างหรือไม่ AAR, VARCHAR2 คือคำตอบ Oracle บอกว่าพวกเขาจะนำ VARCHAR กลับมา แต่ฉันแน่ใจว่าจะมีการขบเขี้ยวเคี้ยวฟันเมื่อสตริงว่างไม่ว่าง
JMD

2

หลังจากการทดลองบางอย่าง (ดูด้านล่าง) ฉันสามารถยืนยันได้ว่า ณ เดือนกันยายน 2560 ไม่มีอะไรเปลี่ยนแปลงเกี่ยวกับการทำงานที่อธิบายไว้ในคำตอบที่ยอมรับ : -

  1. สาธิต Rextester สำหรับ Oracle 11g: สตริงที่ว่างเปล่าจะถูกแทรกเป็นNULLสำหรับทั้งสองและVARCHAR VARCHAR2
  2. การสาธิต LiveSQL สำหรับ Oracle 12c:ผลลัพธ์เดียวกัน

เหตุผลที่ผ่านมาสำหรับคำหลักสองคำนี้อธิบายได้ดีในคำตอบของคำถามอื่น


0
  1. VARCHAR สามารถเก็บอักขระได้สูงสุด 2000 ไบต์ในขณะที่ VARCHAR2 สามารถเก็บอักขระได้มากถึง 4000 ไบต์

  2. ถ้าเราประกาศประเภทข้อมูลเป็น VARCHAR มันจะใช้พื้นที่สำหรับค่า NULL ในกรณีของประเภทข้อมูล VARCHAR2 มันจะไม่ครอบครองพื้นที่ใด ๆ สำหรับค่า NULL เช่น,

    name varchar(10)

จะสำรองหน่วยความจำ 6 ไบต์แม้ว่าชื่อจะเป็น 'Ravi__' ก็ตาม

name varchar2(10) 

จะสำรองพื้นที่ตามความยาวของสายป้อน เช่นหน่วยความจำ 4 ไบต์สำหรับ 'Ravi__'

ที่นี่ _ แทน NULL

หมายเหตุ: varchar จะสำรองพื้นที่สำหรับค่า Null และ varchar2 จะไม่สำรองพื้นที่สำหรับค่า Null


2
ผมคิดว่าคำตอบนี้จะทำให้เกิดความสับสนกับVARCHAR CHAR
Jon Heller

0

ปัจจุบันพวกเขาเหมือนกัน แต่ก่อนหน้านี้

  1. ที่ไหนสักแห่งในเน็ตฉันอ่าน

VARCHAROracle สงวนไว้เพื่อรองรับความแตกต่างระหว่างNULLและสตริงว่างในอนาคตตามมาตรฐาน ANSI ที่กำหนดไว้

VARCHAR2ไม่แยกความแตกต่างระหว่างNULLสตริงและว่างและจะไม่

  1. นอกจากนี้

Emp_name varchar(10)- หากคุณป้อนค่าน้อยกว่า 10 หลักพื้นที่ที่เหลือจะไม่สามารถลบได้ ใช้ทั้งหมด 10 ช่องว่าง

Emp_name varchar2(10) - หากคุณป้อนค่าน้อยกว่า 10 หลักพื้นที่ที่เหลือจะถูกลบโดยอัตโนมัติ


ฉันสะดุดกับโพสต์นี้เมื่อเร็ว ๆ นี้โปรดทราบว่ามันไม่ถูกต้อง ดำเนินการฟิลด์ต่อไปนี้และทั้งสองจะเป็น 3 ตัวอักษร:create table deleteme_table(v varchar(10), v2 varchar2(10)); insert into deleteme_table (v, v2) values ('abc','abc'); select v, length(v), v2, length(v2) from deleteme_table;
Brian Leach

-1

VARCHAR เป็นคำพ้องความหมายของ VARCHAR2 อย่างไรก็ตามคุณไม่ควรใช้ VARCHAR เพราะ Oracle อาจเปลี่ยนซีแมนติกส์ในอนาคต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.