この表に数値を挿入するときに、先頭のゼロをどのように保存しますか?[閉まっている]


10

テーブルに2つのレコードを挿入しました。

create table num(id int)
insert into num values(0023)
insert into num values(23)
select * from num

クエリすると、すべてと表示され23ます。つまり、SQL Serverは先頭の0を無視します。その背後にあるメカニズムは何ですか?SQL Serverで、挿入時に値を返すにはどうすればよいですか(つまり0023、および23)?


2
なぜ先行ゼロを気にするのですか?それらがシステムにとって意味がある場合はid、タイプVARCHARまたは類似のものでなければなりません。
Nick Chammas

0023 0023が23または023または0000000023とは異なるものとしてデータベースにエンコードされることをどのように期待しますか?それらはすべて同じNUMBERを表します。また、intはNUMBERデータ型です。サーバーがこの「10進数のゼロの先行数」の値を格納する場所はありません。
ErikE

これは貧弱な質問であり、プログラミングクラスの紹介で取り上げられているでしょう。intの性質上、intは先行ゼロを格納できません。これは、任意の数のWebリソースを調べることで解決できます。これには、データベース管理者の入力は必要ありません。
jcolebrand

1
先行ゼロは暗示されます。代わりに文字列を使用する以外に、特定の数の先行ゼロが必要な場合、それはint列に格納されているものを超える追加情報です。1つのオプションは文字列列を使用することですが、別のオプションは、先行ゼロの数を別の列またはUIに格納することです。たとえば、UIが常に先頭にゼロを埋め込んで4桁にフォーマットする場合、この情報はUIに保存されています。ゼロの数を変化させてレコードごとに保持する必要がある場合は、代わりにその情報を別のフィールドに格納できます。
Dave Cousineau

回答:


27

0023は数値ではありません。文字列です。23数です。SQL Serverは、これらのゼロを追加する必要がないことを認識できるため、それらを無視します。アプリケーションに0023として値を表示する場合は、アプリケーション側でフォーマットを行うことをお勧めします。このようにして、SQL Serverに格納されている数値は、加算、集計、またはその他の計算を行う場合でも数値のままです。本当に「0023」として保存する必要がある場合は、文字フィールドに変換する必要があります。char、varchar、nvarchar、nchar。


0023が文字列の場合、idをint形式として定義したテーブルに値を挿入するにはどうすればよいですか?
user8365 2012年

@ user8365 -定義のどちらかidVARCHARかだけではなく、0023の23を挿入
Lamak

5
@ user8365-SQL Server にそのフィールドのドメインの整合性を侵害させることができるかどうか尋ねています。できません。0023文字列の場合、文字列として保存します。そうでない場合は、INTとして保存し、先行ゼロを忘れます。
Nick Chammas

まさに@NickChammasが言ったこと。ここでは選択肢はありません。23は数値、0023は文字列です。数値が必要な場合は、数値として扱います。私の答えが言うように、数値のように並べ替え、加算、減算、乗算、除算などが必要な場合、それは数値である必要があります。選択肢はありません。引数はありません。先行ゼロはフォーマットです。アプリのコードなどでそれを行ってください。
Grant Fritchey、2012年

@グラント先行ゼロが単なるフォーマットであることには同意できません。彼らはどんな数字体系でも合法です。ただし、0023b10 = 23b10; そのため、どのストレージシステムでも、先頭のゼロをすべてエンコードしないことにより、ある程度の圧縮が行われます。基本的に、質問者は間違った質問をしています。0023が整数ではないのはなぜですか?整数です!それを表すために、無限の先行数値をエンコードする必要はありません。
ooutwire 2012年

5

他の回答で00023はすでに数で述べられています。計算列を使用して、カスタム形式を使用してその数値を表示できることを追加したいと思います。例えば、

create table num_table(id int not null primary key identity(1,1),
num int, leading_zeros smallint,
constraint chk_leading_zero_nonnegative check (leading_zero>=0),
num_formatted as replicate('0',coalesce(leading_zeros,0)) +cast(num as varchar(10)));
insert into num_table(num,leading_zeros) values(23,2) ;
select num_formatted from num_table; -- output '0023'

良い点、注目に値する。
Grant Fritchey、2012年

0

0023は数値ですが、数学的な理由がないため、intおよび他の数値データ型は先行ゼロを格納しません。

先行ゼロを格納する必要がある場合は、char、varcharなどの文字列データ型を使用します


1
INTが固定長(32ビットのような)であり、それらを格納するためにバイナリ表記が使用されていると仮定すると、実際に先行ゼロが格納されます。ただし、出力には表示されません。
ypercubeᵀᴹ

@ypercube-そうですが、先行ゼロの数は、32ビットを埋めるために必要なものです(ユーザー定義可能ではありません)。
Nick Chammas

@ニック:ええ、そこに議論はありません。ポイントは、先行ゼロが格納されているかどうかではないと思います。同じ数値の2つのバージョンをデータ型に格納できるかどうかです。1つは先行ゼロあり、もう1つはゼロなしです。
ypercubeᵀᴹ

しかし、これは意味がありません。2つの10進数の先行ゼロは、32ビット整数の先行ゼロの数とはまったく関係がありません。10進数を考えてみます。これ15は、16進数で1桁のみFです。彼らはすでに異なる数の「先行ゼロ」を持っています。2147483647は10桁ですが、16進数では7FFFFFFFまたは8桁です。
ErikE 2012年

基本的に、私たちが使用している数学的数値システムを考慮しなければなりません...この場合は10進数(基数10)です。23は10進数です。0x1000 + 0x100 + 2x10 + 3 = 23です。8進数の場合、2X8 + 3となります。したがって、ストレージエンジンに言うと、「2つの先行ゼロを持つストア23」は、同じ最終結果、つまり23をエンコードするだけなので、役に立ちません。SQLServerはゼロを無視せず、10進数値を返すだけです。あなたが挿入された数、つまり、0023または23に等しい
ooutwire
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.