プロが教えるわが家の防犯対策術!

SQLServer2005でfloat型の項目に-3.34 を手入力(クエリアナライザでinsert文で入力した時も同様)して、コマンドプロンプトから以下のselect文を実行した所、-3.3399999999999999 で表示されました。
sqlcmd -U ユーザ名 -P パスワード -d データベース名
1> select * from テーブル名

クエリアナライザで同様に select * from テーブル名
した場合は、-3.34 のまま正しく表示されます。
-12.34、-22.34などの数値ではこの事象は発生せず、何か条件があるようです。お分かりになる方がいらっしゃいましたら、ご教示いただけないでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (2件)

実機確認してみましたが、表示結果の違いは、クライアントソフト(コマンドプロンプトやアナライザ)の仕様差ですね。


数値表現の限界に関しては、#1さんの回答の通りで、浮動小数点では小数以下何桁まで精度を維持して欲しい場合には使用すべきではなく、decimal型などを使用すべきです。
今回の表示結果の差は、クライアントソフト自身あるいは、その開発言語の仕様差で、丸め等が行われた結果です。
decimal型などを使用し、小数点以下の精度も保証する定義(ただし、トータル桁数が15桁などの制限あり)にすれば、今回のような問題は発生しません。
    • good
    • 0
この回答へのお礼

お礼が遅くなり大変申し訳ございません。
OacleでもSQLServerでも実際にデータベースに持っている数値とSPL*PLUSやsqlcmdで画面表示(ファイル出力)される値は必ずしも一致しない事が分かりました。
貴重なご回答を賜り誠にありがとうございました。

お礼日時:2007/02/06 19:32

float型は「浮動小数点数型」と呼ばれる型で、小数を表現する場合に使用されるのですが


コンピューターの性質上、すべての小数を正確に表現できるわけではありません。

詳しく検証はしていませんが、おそらく今回の「-3.34」が浮動小数点型として格納された際に誤差が発生した物と思われます。

参考URLはC言語の解説ですが「浮動小数点数型」とはどういう物かを説明しているので
何かの参考になるかもしれません。

この誤差を解決するには、
 1. 文字列として格納しておき、演算時に数値に変換する
 2. 小数点以下の桁数を決め、例えば2桁ならば100倍して格納しておく
 3. 小数を正確に格納できるデータ型を選択する
といった選択肢が考えられますが、3.のデータ型についてはSQLServerを使用した経験がないため、存在するかどうかもわかりません。
# MySQLならばDECIMAL型というのがあるのですが。

以上、参考になれば幸いです。

参考URL:http://www.kyoto-su.ac.jp/~yamada/programming/fl …
    • good
    • 0
この回答へのお礼

お礼の回答が遅くなり、大変申し訳ございません。
SQLServerではデータ型でDECIMAL型を使用する事で、整数部、小数部の桁数を固定できるようです。(例 DECIMAL(m,n))
貴重なご回答を賜り誠にありがとうございました。

お礼日時:2007/02/06 19:26

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QFloat型の時の計算結果がおかしい

ユーザー側で、Microsoft SQL Server2000を使用しています。
計算結果がおかしいので、仕事場で、SQL2008環境で互換モードでも、以下の現象が出てこまって
おります。テストで、確認しました。

23.0 - 22.1
の計算結果を0.9と出したいのですが、
 0.899999999999999
と結果が返ってきます。
どこが間違っているのでしょうか?

SELECT
[Field01] AS 'Field01'
,[Field02] AS 'Field02'
,[Field01]-[Field02] AS 'Field01-02'
,(CAST(23 AS FLOAT) - cast(22.1 AS FLOAT) ) AS 'test1'
,(CAST(23 AS REAL ) - cast(22.1 AS REAL ) ) AS 'test2'
FROM
[dbo].[Table01]

Aベストアンサー

間違ってはいません。

しかし浮動小数点データは概数であるため、データ型の範囲に含まれるすべての値を正確に表せるわけではありません。

SQLServer 2008 などの概数型は IEEE754 仕様に従っています。

概数型では、多くの場合、指定されたとおり正確な値が格納されません。正確な値にきわめて近い概数が格納されます。多くのアプリケーションでは指定した値と格納される概数のわずかな差は問題にはなりません。ただし、その差が問題になる場合もあります。float 型と real 型にはこのような概数の性質があるので、財務アプリケーション、丸めが行われる演算、等価性のチェックなど、正確な数値動作が必要な場合には、これらのデータ型を使用しないでください。

代わりに、int 型、decimal 型、money 型、smallmoney 型を使用することをお勧めします。


実際にはどういうことなのか、多少極端ですが、例を上げてみましょう。

いま、ここで新しいCPUを構想していて、4ビットで 0.00~4.00 までの実数を表現するものを考えているとします。

この例題で、4 ビットのうちの上位2ビットを 1の位、下位2ビットを小数点以下の位にすると仮定した場合、小数点以下は2ビットしかありませんから、2進数の 00 を 0.00、2進数の 01 を 0.025、2進数の 10 を 0.05、2進数の 11 を 0.075 と表現する合計4つのみとなります。そして、1の位は 0、1、2、3 です。
この範囲で表現できる数値では正確な4は表現できませんが、概数として表せば、3.75 が一番4に近い数値となるわけです。

実際にはもう少しビット数が多いわけですが、おおむねこのような仕組みで実数が表現されています。

間違ってはいません。

しかし浮動小数点データは概数であるため、データ型の範囲に含まれるすべての値を正確に表せるわけではありません。

SQLServer 2008 などの概数型は IEEE754 仕様に従っています。

概数型では、多くの場合、指定されたとおり正確な値が格納されません。正確な値にきわめて近い概数が格納されます。多くのアプリケーションでは指定した値と格納される概数のわずかな差は問題にはなりません。ただし、その差が問題になる場合もあります。float 型と real 型にはこのような概数の性質がある...続きを読む

Qデータ型でFloatとreal の計算の違い?

教えてください。

ストアドでfloor(数量(reat) × 単価(money))=金額という計算をさせています。
そこで、200(コ)×9.4(円)=1879円と出るのです。floorで切り捨てても、1880円のはずです。flootなしでやっても、1879,9998と出ます。
何度入力しなおしても同じです。
Floatだと、1880となります。
他の計算はちゃんとできているようです(ざっと見た限りで100%確かめた訳ではありません)

理由がわからないのですが、教えてください。

Aベストアンサー

floatもrealもいわゆる概数といわれるデータ型で、小数の保持には必ず誤差が生じます。

一方、SQL Serverにはデータ型の優先順位というものがあります。
http://msdn.microsoft.com/ja-jp/library/ms190309.aspx

floatもrealもmoneyより上です。
したがって、float * money, real * moneyの演算を行うと、moneyはそれぞれfloat, realに変換されてから演算に使われます。
moneyで9.4と持っていたものがreal型に変換されると、結局9,4にはなりません。
おそらく9.399999389...あたりになってしまいます。realの有効桁数は7桁しかありませんから、小数点以下7桁目以降はアテにならない数字になります。
これに200を掛けても1879.999877..などとなるため、floorを掛けても1879になってしまいます。

floatも基本は同じですが、有効桁数が15桁あります。
moneyの9.4はおそらく9.40000000000004くらいの精度で変換されます。したがってfloorを掛けても1880と出ます。

しかし、誤差が上に出るか、下に出るかは扱う数字により保証の限りではありません。
したがって、real型やfloat型を金額計算に用いるべきではありません。
numeric(decimal)で計算すべきでしょう。

#質問者さんは結果をmoney型で受け取ろうとされているようです。

floatもrealもいわゆる概数といわれるデータ型で、小数の保持には必ず誤差が生じます。

一方、SQL Serverにはデータ型の優先順位というものがあります。
http://msdn.microsoft.com/ja-jp/library/ms190309.aspx

floatもrealもmoneyより上です。
したがって、float * money, real * moneyの演算を行うと、moneyはそれぞれfloat, realに変換されてから演算に使われます。
moneyで9.4と持っていたものがreal型に変換されると、結局9,4にはなりません。
おそらく9.399999389...あたりになってしまいます。r...続きを読む

QSQL Serverにおける小数部の0表記について

お世話になっております

FLOAT型の数値を補正する為に、小数部10桁のdecimal型に変換すると
例えば 3.14 ならば 3.1400000000 と表示されてしまいます
RTRIMで0を消そうと思ったのですが、SQL Serverでは0のRTRIMは対応していないようです

FLOATやREAL型を使わずに、SQL Serverで小数部の0を消すには、どうしたら良いでしょうか?
ご教授頂ければ幸いです

Aベストアンサー

0をスペースに変更しRTRIMした後でスペースを0に戻すとか?
REPLACE(RTRIM(REPLACE(表示値,'0',' ')),' ','0')

QSQL Server のキャラクターセット(内部文字コード)は何処で定義するのでしょうか?

SQL Server超初心者です。(Oracleについては約1年ちょっとの経験はあります)どうぞよろしくお願いします。
今回SQL Server2005 を使って簡単なシステムを構築する事になりました。
SQL Serverが扱う文字コートについて教えてください。
Oracleを使っていた時の経験としてDB内部のキャラクターセットと
クライアントで使う文字セット(NLS_LANG)を意識しておかないと、いろんな「文字化け」問題に遭遇した時に対応できませんでした。
きっとSQL Serverにおいても同じような事ではないかと思いここに質問させていただきます。
以下2点についてどなたかコメント願います。
1.(Oracleでいうキャラクターセット)はどこで定義するのでしょうか?
2.OracleでいうNLS_LANGに相当するものはあるのでしょうか?
 (ひょっとしたらマイクロソフト製品なのでサーバもクライアントもCP932固定なのでしょうか?)

根本的にはシステム構築する上で『極力文字化けに遭遇したくない』思い出このような質問をさせていただきました。
『文字化け』について注意点などありましたら合わせてコメントいただければ助かります。
以上よろしくお願いします。

SQL Server超初心者です。(Oracleについては約1年ちょっとの経験はあります)どうぞよろしくお願いします。
今回SQL Server2005 を使って簡単なシステムを構築する事になりました。
SQL Serverが扱う文字コートについて教えてください。
Oracleを使っていた時の経験としてDB内部のキャラクターセットと
クライアントで使う文字セット(NLS_LANG)を意識しておかないと、いろんな「文字化け」問題に遭遇した時に対応できませんでした。
きっとSQL Serverにおいても同じような事ではないかと思いここに質問...続きを読む

Aベストアンサー

Windowsのロケールの設定を日本語にした状態でSQLServerをインストールした場合、cp932がデフォルトの照合順序になります。照合順序については参考URLをご覧下さい。

SQLServerではわかりませんが、PostgresではJDBCドライバ部分で変換していたように記憶しています。ODBCドライバではAutoTranslateという機能があります。

このため、ODBC接続で何も考えずにvarcharを使用するとcp932になります。

参考URL:http://www.microsoft.com/japan/msdn/sqlserver/sql2005/bb330962.aspx

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q処理件数を非表示にしたい

ManagementStudioでストアドプロシージャの開発をしています

開発中、デバッグのためにプロシージャをコールすると、SQLの発行の度に
「何件処理されました。」
「何件処理されました。」
「何件処理されました。」
「何件処理されました。」
「何件処理されました。」
・・・

と処理件数が表示され、確認の際に邪魔で困っています。
処理件数を非表示にするにはどうすれば良いでしょうか?

また同様に、SELECT文の発行ごとにSELECT結果がグリッドに表示されるのを非表示にできないでしょうか?

Aベストアンサー

処理件数を非表示にする方法

⇒SELECT文の前に「set nocount on」を記載すると件数は表示されません。

SELECT文の発行ごとにSELECT結果がグリッドに表示されるのを非表示にする方法

⇒デバッグのためには表示された方が良いと思いますが、
 とりあえず…SELECT文の前に「SET NOEXEC ON」を記載するとデバッグだけ実施され、
 グリッドは表示されません。
例であげると以下のとおりです。
SET NOCOUNT ON
SET NOEXEC NO
SELECT *
FROM DB.dbo.TableName
go

QBCPユーティリティの使用法_ヘッダー情報の取得_

どなたかご存知の方教えてください。
bcp ユーティリティから、SQLサーバーのテーブルのファイルエクスポート(.txt)は出力できたのですが、データ列名が取得できていませんでした。
列名を取得することは可能なのでしょうか?
可能な場合、.fmt のファイルで設定するのでしょうか?
よろしくお願いします。

Aベストアンサー

キーワード「bcp 列名」でGoogle検索すると4番目に次のページがヒットしました,ご参考まで。
http://d.hatena.ne.jp/w650/20080215/p2

Q型 varchar から型 numeric への変換エラー。

SQLクエリアナライザを使って、あるデータベースからLEFT JOINなどを駆使し、条件にそってデータを抽出しようと必死でやっております。
今まではうまく取得できていたのに、”型 varchar から型 numeric への変換エラー。”というエラーがでるようになりました。
前回とテーブルのデータを比較してみると、IsNULL(chrShokuhinCD,'') as chrShokuhinCDで引っ掛かっているようです。
この項目には空白(スペース)が入ったデータが最近存在しているのが原因だと思うのですが。。。
空白だったとき、IsNULL(chrShokuhinCD,'') as chrShokuhinCDはどのように修正すればよいでしょうか?教えてください。

Aベストアンサー

>空白だったとき、IsNULL(chrShokuhinCD,'') as chrShokuhinCDはどのように修正すればよいでしょうか?

では質問です。
空白だったとき、どんな数値として扱えばいいでしょうか?

これで何を入れればいいかわかると思いますが。

QSQLサーバから、項目の属性(型)を取得したいのですが・・・

SQLサーバからテーブルの項目名、属性(型)を取得するには、どのように
クエリを組めば良いのでしょうか?

Aベストアンサー

2つ前の質問に書いたのと一緒ですが。。
基本的にsys.objects, sys.columnsというシステムビューを使います。

select object_name(object_id),name,type_name(user_type_id) from sys.columns c
where object_id=object_id('テーブル名')

QSQLserver算術オーバーフローエラーについて

使用環境は DB SQL Server2008 Express
使用ツールは Microsoft SQL Server Management Studio です

SQLserver2000からSQLserver2008DBへ移行しようとしているのですが
ストアドプロシージャのところでうまくいきません

具体的には、処理を走らせると下記メッセージが出てきます

floatをデータ型numericに変換中に、算術オーバーフローエラーが発生しました
プロシージャ"○○"は、許可されていないステータスNULLを返そうとしました。
代わりにステータス0を返します

調べると 
小数点以下があるフィールド同士を掛けて、その結果の小数点以下をROUNDで切り
捨てた値を小数点のないフィールドに追加しようとするとエラーになる 
とありました。

下記 2行あたりが怪しいと思うのですが対処方法がわかりません。
ご教授願えないでしょうか?

SET @GetRand = CAST(RAND()*10 AS numeric(1,0))

SET @GetRand = CAST(RIGHT(CONVERT(varchar,CAST(RAND()*100 AS
numeric(2,0))+100),2) As numeric(2,0))

またストアドプロシージャは、VBのようにデバッグで1行単位で処理を確認してい
くことはできないのでしょうか?

使用環境は DB SQL Server2008 Express
使用ツールは Microsoft SQL Server Management Studio です

SQLserver2000からSQLserver2008DBへ移行しようとしているのですが
ストアドプロシージャのところでうまくいきません

具体的には、処理を走らせると下記メッセージが出てきます

floatをデータ型numericに変換中に、算術オーバーフローエラーが発生しました
プロシージャ"○○"は、許可されていないステータスNULLを返そうとしました。
代わりにステータス0を返します

調べると 
小数点以下があるフィールド...続きを読む

Aベストアンサー

>SET @GetRand = CAST(RAND()*10 AS numeric(1,0))

RAND()*10の値が9.5以上だと破たんする(=丸められて10になる。)ので、floorするとか。


人気Q&Aランキング