Используйте строку числового формата "R" :
double d = 0.00034101243963859839;
string s = d.ToString("R");
//...
double d2 = double.Parse(s);
if(d == d2)
{
//-- Success
}
Эти R
обозначает "распространение в прямом и обратном направлениях". Из связанного документа:
Этот формат поддерживается только для Единственных и Двойных типов. Спецификатор туда и обратно гарантирует, что числовое значение, преобразованное в строку, будет проанализировано назад в то же числовое значение.
Как в стороне, я подозреваю, что нет никакого способа сохранить те последние две цифры. Существует только такая доступная точность, и я сомневаюсь, что они когда-либо превращают ее в d
во-первых. Но можно удостовериться, что строка, по крайней мере, читает назад, что Вы действительно имеете правильно.
при реальной необходимости в дополнительной точности Вы могли бы попытаться использовать decimal
вместо этого.
Синтаксис, необходимый для создания вашего оператора:
Update [Message]
SET [Subject] = CASE WHEN @SubjectChanged = 1 THEN @Subject ELSE [Subject] END,
Body = CASE WHEN @BodyChanged = 1 THEN @Body ELSE Body END
WHERE MessageID = @MessageID
, если вы все еще хотите придерживаться его после всех предложений.
Nb, если вы опускаете часть ELSE [Тема] в операторы CASE вместо игнорирования UPDATE устанавливают для поля значение NULL.
Your best bet, by far, is to use explicit IF statements:
IF @subjectHasChanged = 1 and @bodyHasChanged = 1
UPDATE Messages SET Subject = @subject, Body = @body
WHERE MessageId = @MessageId
ELSE IF @subjectHasChanged = 1
UPDATE Messages SET Subject = @subject WHERE MessageId = @MessageId
ELSE IF @bodyHasChanged
UPDATE Messages SET Body = @body WHERE MessageId = @MessageId
From a performance point of view, nothing beats this. Because SQL can see during query compilation that you only update Body, or Subject, or both, it can generate the appropriate plan, for instance not even bothering to open (for update) the non-clustered index you have on Subject (if you have one, of course) when you only update Body.
From a code code quality point of view, this is disaster, a nightmare to maintain. But acknowledging the problem is 80% solving the problem :) . You can use code generation techniques for instance to maintain such problem procedures.
Another viable approach is actually to use dynamic SQL, construct the UPDATE in the procedure and use sp_executesql. It has its own set of problems, as all dynamic SQL has. There are resources about dynamic SQL problems, and there are workarounds and solutions, see The Curse and Blessings of Dynamic SQL.
update Message set
Subject = (case when @SubjectChanged = 1 then @Subject else Subject end),
Body = (case when @BodyChanged = 1 then @Body else Body end)
where MessageID = @MessageID
Это действительно должно быть все, что вам нужно. Однако, если вы действительно не можете обновить поле, если оно не изменилось , вам придется сделать это в отдельных инструкциях.
if @SubjectChanged = 1
update Message set Subject = @Subject where MessageID = @MessageID
if @BodyChanged = 1
update Message set Body = @Body where MessageID = @MessageID
Мне кажется, что вы напрасно тратите силы. Если вы извлекаете шесть значений, отобразите их пользователю (в некотором пользовательском интерфейсе), и они могут изменить некоторое их количество переменных. и нажмите кнопку «Сохранить» - затем просто обновляйте все 6 полей каждый раз, получая новые значения из полей ввода пользователя.
Некоторые, возможно, не изменились, но что с того. Так код будет намного проще.
Use DEFAULT values for the stored procedure parameters.
create proc UpdateMessage(
@MessageID int, -- mandatory
@Subject nvarchar(100) = NULL,
@Body nvarchar(max) = NULL)
Then, you can structure your update in this way:
Update [Message]
SET
[Subject] = ISNULL(@Subject, [Subject]),
Body = ISNULL(@Body, Body)
WHERE MessageID = @MessageID
CREATE PROCEDURE UpdateMessage
@MessageID int,
@Subject nvarchar(100),
@Body nvarchar(max),
AS
BEGIN
if(@Subject is null or @Subject='')
SELECT @Subject=Subject FROM Message WHERE MessageID=@MessageID
if(@Body is null or @Body='')
SELECT @Body=Body FROM Message WHERE MessageID=@MessageID
UPDATE Message SET Subject=@Subject, Body=@Body WHERE MessageID=@MessageID
END
GO
Я не уверен, что это лучший способ сделать это, но, возможно, вы можете попробовать
IF @SubjectChanged = 1 THEN
BEGIN
UPDATE [Message]
SET [Subject] = @Subject
WHERE MessageID = @MessageID
END
END
IF @BodyChanged = 1 THEN
BEGIN
UPDATE [Message]
SET Body = @Body
WHERE MessageID = @MessageID
END
END
Я настоятельно рекомендую использовать метод Адама Робинсона, если вам требуется, чтобы это было в одной хранимой процедуре.
Еще лучше было бы просто использовать отдельные хранимые процедуры для каждого из этих обновлений.