Должен ли я добавить If Exists в мою хранимую процедуру SQL?

#sql #sql-server-2005 #sql-function

#sql #sql-server-2005 #sql-функция

Вопрос:

Добрый день всем,

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

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

Я предполагаю, что из того, что я прочитал в Интернете, я должен использовать функцию ‘IF EXISTS’ в моей хранимой процедуре. Я не уверен на 100%, как это будет работать с текущим кодом, который у меня есть в моей хранимой процедуре? Я только хочу проверить, доступны ли эти записи, и если нет, то добавить их или, если они уже существуют, не добавлять их.

Я просто думаю, что я немного запутался с количеством статей и т. Д., Которые я прочитал в Интернете.

Вот моя текущая хранимая процедура:

 ALTER PROCEDURE [dbo].[GasNominationsRawData_Insert]

AS SET NOCOUNT ON;  

INSERT INTO dbo.GasRawData (timestamp,TagName,Value) 

    SELECT timestamp AS Interval, Left(Right(TagName,Len(TagName)-5),Len(TagName)-10) As TagName,
    CONVERT(decimal(10, 2), ROUND(value, 2)) As Value
    FROM 
       OPENQUERY(IHISTORIAN,'
        SET starttime =''yesterday  4h'', endtime =''today  6h'' 
        SELECT timestamp, tagname, value
        FROM ihRawData
        WHERE tagname = "UMIS.99FC9051.F_CV"
           OR tagname = "UMIS.99F851C.F_CV"
           OR tagname = "UMIS.35GTGAS.F_CV"
           OR tagname = "UMIS.99XXG546.F_CV"
        AND timestamp BETWEEN ''timestamp'' and ''timestamp'' 
        AND SamplingMode =Calculated
        AND CalculationMode =Average
        AND IntervalMilliseconds =1h
        ORDER BY tagname, timestamp
        ')
  

Любая помощь или предложения будут высоко оценены.

С уважением, Бетти.

Ответ №1:

Один из очень простых способов предотвращения дублирования — добавить a UNIQUE INDEX в поля, которые вы хотите сохранить отличительными.

CREATE UNIQUE INDEX ix_MyIndexName ON Table(Field1, Field2, Field3)

При попытке вставить повторяющееся значение для перечисленных полей будет выдана ошибка.

Кроме того, вы можете добавить опцию IGNORE_DUP_KEY = ON к приведенному выше, чтобы продолжить, если будет предпринята попытка вставить повторяющееся значение. Будет сгенерировано предупреждение, но это не приведет к сбою запроса.

Это имеет минимальные накладные расходы и не потребует от вас выполнения каких-либо работ по обслуживанию.

Комментарии:

1. Добрый день, JNK, создание УНИКАЛЬНОГО ИНДЕКСА, я думаю, звучит неплохо. Однако я просто хотел бы проверить, будет ли он работать с некоторыми примерами записей. Моими столбцами таблицы в БД являются ‘timestamp’, ‘tagname’ и ’Value’. Примеры записей (только для двух тегов) в БД будут выглядеть следующим образом: (Временная метка, имя тега, значение) 27/10/2011 05:00 99F851C 0.03, 27/10/2011 06:00 99F851C 0.03, 27/10/2011 05:00 99FC9051 14.62, 27/10/2011 06:00 99FC9051 13.66. Пожалуйста, смотрите следующую часть комментариев…

2. По сути, будет дублироваться «временная метка», поскольку мой запрос возвращает часовой интервал для каждого тега со вчерашнего дня 05:00 утра до текущей даты 06:00 утра. Поэтому мне нужно убедиться, что дубликаты не являются дубликатами отдельных ‘timestamp’ ’tagname’. Будет ли работать СОЗДАНИЕ УНИКАЛЬНЫХ ИНДЕКСНЫХ дубликатов записей В GasRawData (временная метка, имя тега)?

3. Привет, JNK, да, создание индекса действительно работало как таковое. Однако теперь у меня есть исключение, которое мне нужно разрешить, и я не уверен, как это сделать. «Не удается вставить дублирующуюся строку ключа в объект ‘dbo.GasRawData’ с уникальным индексом ‘DupRecords’. Оператор был завершен «. Это относится к dbcommand . Строка ExecutedNonQuery() на странице vb? Я попытаюсь опубликовать код для кнопки, в которой он используется, если вы сможете помочь?

4. Вам нужно использовать IGNORE_DUP_KEY = ON то, что я упомянул, или обрабатывать ошибки.

5. Защищенный подраздел btnAddRawData_Click(обычно отправитель как объект, иногда как система. EventArgs) обрабатывает btnAddRawData.Щелкните с помощью dbconnection в качестве нового SqlConnection(ConfigurationManager. AppSettings(«dbconnection»)) dbconnection. Откройте(), используя dbcommand как SqlCommand = dbconnection . createCommand с помощью dbcommand . CommandType = CommandType . StoredProcedure . CommandText = «GasNominationsRawData_Insert» dbcommand . ExecuteNonQuery() завершается с помощью End с использованием End с использованием End Sub End Class

Ответ №2:

Когда вы говорите «дубликат», вы имеете в виду дубликат TagName ? Если да, то самым простым решением было бы использовать уникальное ограничение для этого поля в таблице. Или вы также можете использовать AFTER INSERT триггер, чтобы проверить, существует ли он TagName уже (возможно, с помощью комбинации VALUE ?), И если да, то ROLLBACK транзакция.

Комментарии:

1. «Повторяющиеся» записи, о которых идет речь, являются записями для ‘timestamp’ и ‘tagname’. Каждое из указанных выше «имен тегов» содержит данные для часовых интервалов. Приведенный выше запрос возвращает 26 часовых интервалов для каждого тега, которые начинаются с 05:00 утра предыдущего дня до 06:00 утра текущей даты?

Ответ №3:

Я бы сделал If EXISTS

В основном просто сделайте

 IF EXISTS( select * from wherever where something = something )
BEGIN
-- Return an error here
Return 0
END
ELSE
BEGIN
 -- Insert Code Goes Here
Return 1
END
  

Затем, когда вы выполняете свой SP, если он возвращает 0, вы знаете, что произошла ошибка, и вы можете отобразить сообщение своему пользователю о вставке дублирующихся данных. Этот подход будет означать, что вы можете обнаружить результат запроса, и если он не был вставлен из-за дубликатов, вы можете отобразить соответствующее сообщение, оно также даст вам подтверждение того, что запись вставлена.