Stored Procedure で動的に Query を生成・実行したいトキは多々ある。
ので、よく使うシステム Stored Procedure がある。
それが『 sp_executesql 』。
ところが。
これの細かい仕様を理解せずに今まで使用しておりました。
Stored を組み始めて・・・早数ヶ月。お恥ずかしい。
[ sp_executesql ] のパラメーターは大雑把に ( 詳細はBOL参照 )
@stmt ( SQL ステートメント: 必須 )
,@params ( @stmt で使用するパラメーター変数定義(型 , IN / OUT ) : 既定値 NULL )
,@param1 ( @params の値設定 : 既定値 NULL )
で、第一引数の「@stmt」に注意があったんですよ。
今日、BOL をきちんと読んだら書いてあった。
--*--*--*--*--*
~。+ 演算子で 2 つの文字列を連結するなどの複雑な Unicode 式は使用できません。
--*--*--*--*--*
あたしはコレを知らず。
「@stmt」の型は 『NVARCHAR(MAX)』だけど、「+ 演算子で 2 つの文字列を連結する」と、どうもストレージを最大に使えないんだかなんだか、文字列が切り詰められちゃう。
( N''プレフィックスをつけると 4000 文字位。つけないと 8000文字位 )
で、Query が不完全になってエラーを発すると。。。
そんなワケで、『NVARCHAR(MAX)』って『NVARCHAR(4000)』と変わらない??
と勘違いしていました。
無知っておそろしい。つくづく。
ちなみに、『NVARCHAR(MAX)』のサイズ説明は BOL には下記のようにあります。(抜粋)
--*--*--*--*--*
max はストレージの最大サイズが 2^31-1 バイトであることを示しています。
ストレージのサイズは、入力文字数の 2 倍のバイト数に 2 バイトを足した数です。
--*--*--*--*--*
単純に計算して・・・536870911 文字??
( 計算苦手なんで違うかも )
今更だけど、知ってよかった。で、メモ。
2009年3月18日水曜日
2009年2月20日金曜日
[SQL_Server] Query で割算の見落とし。
【目的】Queryで割算して、小数点第一位までパーセンテージを求める。
ええ、常識かもしれないんですけどね、MEMO。
割算には [ / ](スラッシュ) を用いるワケですが、
「整数 ÷ 整数」して、戻り値には小数点付の精度を求める場合、ちょっと一手間必要。
というのも、「整数(A) ÷ 整数(B)」の戻り値は『整数』だそうで。
だから、[ 整数A ] か [ 整数B ] (若しくは両方)を、演算前に
小数持ちタイプのデータ型に型変換してあげる必要があると。
** 例 **
SELECT ( 20 / 57 ) * 100 AS Straight
,( CAST( 20 AS FLOAT ) / 57 ) * 100 AS castFLOAT_Single
,( CAST( 20 AS FLOAT ) / CAST( 57 AS FLOAT ) ) * 100 AS castFLOAT
,( CAST( 20 AS DECIMAL ) / 57 ) * 100 AS castDecimal_Single
,( CAST( 20 AS DECIMAL ) / CAST( 57 AS DECIMAL ) ) * 100 AS castDecimal;
[Result]
Straight : 0
castFLOAT_Single : 35.0877192982456
castFLOAT : 35.0877192982456
castDecimal_Single: 35.087700
castDecimal : 35.0877192982456140
** ** **
というコトで、ジブンは片側だけ [ FLOAT ] にキャストしてあげる方法をとった。
** 解決 **
SELECT CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,1 ) AS DECIMAL(4 ,1) ) AS N'切捨て'
,CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,0 ) AS DECIMAL(4 ,1) ) AS N'四捨五入';
** **** **
何故に更に [ DECIMAL(4 ,1) ] にキャストしているかは、実行してみればわかる。
ええ、常識かもしれないんですけどね、MEMO。
割算には [ / ](スラッシュ) を用いるワケですが、
「整数 ÷ 整数」して、戻り値には小数点付の精度を求める場合、ちょっと一手間必要。
というのも、「整数(A) ÷ 整数(B)」の戻り値は『整数』だそうで。
だから、[ 整数A ] か [ 整数B ] (若しくは両方)を、演算前に
小数持ちタイプのデータ型に型変換してあげる必要があると。
** 例 **
SELECT ( 20 / 57 ) * 100 AS Straight
,( CAST( 20 AS FLOAT ) / 57 ) * 100 AS castFLOAT_Single
,( CAST( 20 AS FLOAT ) / CAST( 57 AS FLOAT ) ) * 100 AS castFLOAT
,( CAST( 20 AS DECIMAL ) / 57 ) * 100 AS castDecimal_Single
,( CAST( 20 AS DECIMAL ) / CAST( 57 AS DECIMAL ) ) * 100 AS castDecimal;
[Result]
Straight : 0
castFLOAT_Single : 35.0877192982456
castFLOAT : 35.0877192982456
castDecimal_Single: 35.087700
castDecimal : 35.0877192982456140
** ** **
というコトで、ジブンは片側だけ [ FLOAT ] にキャストしてあげる方法をとった。
** 解決 **
SELECT CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,1 ) AS DECIMAL(4 ,1) ) AS N'切捨て'
,CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,0 ) AS DECIMAL(4 ,1) ) AS N'四捨五入';
** **** **
何故に更に [ DECIMAL(4 ,1) ] にキャストしているかは、実行してみればわかる。
登録:
投稿 (Atom)