Условное ОБНОВЛЕНИЕ T-SQL (v2)

Используйте строку числового формата "R" :

double d = 0.00034101243963859839;
string s = d.ToString("R");
//...
double d2 = double.Parse(s);
if(d == d2)
{
  //-- Success
}

Эти R обозначает "распространение в прямом и обратном направлениях". Из связанного документа:

Этот формат поддерживается только для Единственных и Двойных типов. Спецификатор туда и обратно гарантирует, что числовое значение, преобразованное в строку, будет проанализировано назад в то же числовое значение.

Как в стороне, я подозреваю, что нет никакого способа сохранить те последние две цифры. Существует только такая доступная точность, и я сомневаюсь, что они когда-либо превращают ее в d во-первых. Но можно удостовериться, что строка, по крайней мере, читает назад, что Вы действительно имеете правильно.

при реальной необходимости в дополнительной точности Вы могли бы попытаться использовать decimal вместо этого.

15
задан Andrey 20 October 2017 в 02:45
поделиться

8 ответов

Синтаксис, необходимый для создания вашего оператора:

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.

27
ответ дан 1 December 2019 в 00:54
поделиться

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.

7
ответ дан 1 December 2019 в 00:54
поделиться
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
ответ дан 1 December 2019 в 00:54
поделиться

Мне кажется, что вы напрасно тратите силы. Если вы извлекаете шесть значений, отобразите их пользователю (в некотором пользовательском интерфейсе), и они могут изменить некоторое их количество переменных. и нажмите кнопку «Сохранить» - затем просто обновляйте все 6 полей каждый раз, получая новые значения из полей ввода пользователя.

Некоторые, возможно, не изменились, но что с того. Так код будет намного проще.

1
ответ дан 1 December 2019 в 00:54
поделиться

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
0
ответ дан 1 December 2019 в 00:54
поделиться
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
0
ответ дан 1 December 2019 в 00:54
поделиться

Я не уверен, что это лучший способ сделать это, но, возможно, вы можете попробовать

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
0
ответ дан 1 December 2019 в 00:54
поделиться

Я настоятельно рекомендую использовать метод Адама Робинсона, если вам требуется, чтобы это было в одной хранимой процедуре.

Еще лучше было бы просто использовать отдельные хранимые процедуры для каждого из этих обновлений.

0
ответ дан 1 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: