質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Q&A

1回答

835閲覧

SQL Server/CURSOR処理:FETCHしないパラメータについて

theoryxyz

総合スコア11

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

0グッド

1クリップ

投稿2018/02/19 04:52

編集2018/02/21 06:00

CURSORを利用したデータ更新において、
前行のデータを保持しておく目的で、FETCHしないパラメータもFETCHするパラメータの後に宣言して使用しています。
そのデータ型はMONEYとDECIMAL(6,3)です。

さて、FETCHしないパラメータもデータを保持できるのですが、小数点以下を含む値を代入すると少数点以下第一位で四捨五入されて整数に丸められてしまいます。

基本的な質問にて恐縮ですが、本現象は仕様になりますでしょうか?

アドバイスなどいただけますと幸いです。
何卒よろしくお願いいたします。

どうにも先が見えない状況にてソースを掲載させていただきます。
問題点は@current_value_with_point_before_roundの小数点第一位が四捨五入されてしまうことでしたが、ISNULL(@current_point, 0)の@current_pointにNULLでない数値が代入された次の行からは、小数点以下が切り上げられず(0にならず)入力されることが分かりました。
説明不足かもしれませんが取り急ぎ。何卒よろしくお願いいたします。

CREATE TABLE [dbo].[t_history]
([code] CHAR(6) NOT NULL
,[date] DATETIME NOT NULL
,[value] MONEY
,[compared_previous_day_yen] MONEY DEFAULT NULL
,[compared_previous_day_percent] DECIMAL(5,2) DEFAULT NULL
,[compared_previous_day_percent_before_round] DECIMAL(6,3) DEFAULT NULL
,[value_with_point] MONEY DEFAULT NULL
,[value_with_point_before_round] DECIMAL(19,9) DEFAULT NULL
,[initial_date] INT
,[point] MONEY
CONSTRAINT [pk_t_history] PRIMARY KEY([code], [date]))

DECLARE current_day CURSOR
FOR SELECT [date]
,[value]
,[initial_date]
,[point]
FROM [dbo].[t_history]
ORDER BY [code]
,[date]

DECLARE @current_date DATETIME
,@current_value MONEY
,@previous_value MONEY
,@current_initial_date INT
,@current_point MONEY
,@previous_point MONEY
,@current_value_with_point MONEY
,@current_value_with_point_before_round DECIMAL(19,9)
,@previous_value_with_point MONEY
,@previous_value_with_point_before_round DECIMAL(19,9)

OPEN current_day

FETCH NEXT FROM current_day
INTO @current_date
,@current_value
,@current_initial_date
,@current_point

WHILE @@FETCH_STATUS = 0
BEGIN
IF @current_initial_date = YEAR(@current_date) * 10000 + MONTH(@current_date) * 100 + DAY(@current_date)
BEGIN
SET @current_value_with_point_before_round = @current_value
SET @current_value_with_point = @current_value
UPDATE [dbo].[t_history]
SET [compared_previous_day_yen] = NULL
,[compared_previous_day_percent] = NULL
,[value_with_point] = @current_value_with_point
,[value_with_point_before_round] = @current_value_with_point_before_round
WHERE CURRENT OF current_day
END
ELSE
BEGIN
SET @current_value_with_point_before_round = @previous_value_with_point_before_round * ((1.000000000 * (@current_value + ISNULL(@current_point, 0))) / @previous_value)
SET @current_value_with_point = ROUND(@current_value_with_point_before_round, 0)
UPDATE [dbo].[t_history]
SET [compared_previous_day_yen] = @current_value - @previous_value
,[compared_previous_day_percent] = ROUND((1.000000000 * @current_value / @previous_value - 1) * 100, 2)
,[compared_previous_day_percent_before_round] = (1.000000000 * @current_value / @previous_value - 1) * 100
,[value_with_point] = @current_value_with_point
,[value_with_point_before_round] = @current_value_with_point_before_round
WHERE CURRENT OF current_day
END

SET @previous_value = @current_value SET @previous_point = @current_point SET @previous_value_with_point = @current_value_with_point SET @previous_value_with_point_before_round = @current_value_with_point_before_round FETCH NEXT FROM current_day INTO @current_date ,@current_value ,@current_initial_date ,@current_point

END

CLOSE current_day
DEALLOCATE current_day

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sousuke

2018/02/19 06:50

SQLServerのバージョンはいくつでしょうか?またソースも可能な限り提示されたほうがよろしいかと。テーブル定義とdeclare cursor部がないとなんとも言えないと思います。
theoryxyz

2018/02/19 21:48

バージョンは2012です。ソースはうろ覚え、モバイルで記入し始めましたが断念しました。。ダイレクト投稿できると良いのですがすみません。
sousuke

2018/02/21 08:55

コードはコードブロックで囲ったほうがいいですよ。
sousuke

2018/02/21 09:06

あと状況を再現できるテストデータのinsert文がある方が親切です。
theoryxyz

2018/02/21 11:35

すみません。変数名など変更して一般化しています。データまでは厳しいです。ソースはテーブル定義とカーソル処理部分です。ぱっと見、データ依存までは推し量れないとしても、コーディング上ではお気づきになる点は無いという認識でよろしいでしょうか?
guest

回答1

0

前行のデータを保持したい理由はなんですか?
前行のデータ「だけ」でいいのであればLAG関数や逆のLEAD関数でアクセスできます。
LAG関数-Microsoftサイト

どういうコードなのか想像できないので別アプローチになって申し訳ありません。

投稿2018/02/20 00:11

編集2018/02/20 00:12
sousuke

総合スコア3828

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

theoryxyz

2018/02/20 01:25

ご回答ありがとうございます。 こちらこコード無しの相談にて恐縮です。 本件、SQL Serverの処理特性に依存しているようにも思われますので、 LAGによる書き直しも検討してみます。 どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問