Страница 1 из 2

Человеческий язык SQL ошибок.

Добавлено: 16 Ноябрь 2015, 20:47
kreator
Всегда отбивались, но сейчас вал претензий:
1.jpg
Собственно, пример не столь важен. Как отойти от форейн-ключей, праймери, референс и т.д. (непоняток для обычных юзеров)? Есть какие-нибудь идеи, решения? Самому отрабатывать, скажем, в форме - не вариант, утомишься. В FileManager'е что-нибудь прописать? Как народ решает?

Человеческий язык SQL ошибок.

Добавлено: 16 Ноябрь 2015, 21:48
RaFaeL
У нас процедура Eraser в которую передается имя таблицы и номер записи, дальше там внутри много кода на указателях

Человеческий язык SQL ошибок.

Добавлено: 16 Ноябрь 2015, 22:47
Yufil
Добрый день!
Может быть, пригодится...

Описывается процедура FileThrow

FileThrow FUNCTION(*FIleManager Fm,<String FIleName>),Long !Вывод сообщений об ошибке

Код: Выделить всё

FileThrow            PROCEDURE  (*FIleManager Fm,<String FileName>) ! Declare Procedure
! Before Embed Point: %DataSection) DESC(Data Section) ARG()
Loc:FileName         Cstring(100)
Loc:FileError        Cstring(500)
Loc:Info             Cstring(100)

A                    Any
Loc:Pos              Long
TextGroup            Group
                      String('unique key|Нарушена уникальность записи')
                      String('table reference|Запись используется в другой таблице БД')
                     End
Loc:Msg              Cstring(100)
! After Embed Point: %DataSection) DESC(Data Section) ARG()
  CODE
! Before Embed Point: %ProcessedCode) DESC(Processed Code) ARG()
    Loc:FileError=Lower(FileError())
    Loop Row# =1 to 1000
      A &= What(TextGroup,Row#)
      If A &= Null
        Loc:Pos = 0
        Break
      End
      Loc:Msg = A
      Loc:Pos = Instring('|',Loc:Msg,1,1)
      If Loc:Pos>0
        If Instring(Loc:Msg[1 : Loc:Pos-1], Loc:FileError,1,1)
          Break
        End
      End
    End
    If Omitted(2)
      GlobalErrors.SetFile(Fm.GetName())
      Loc:FileName = Fm.GetName()
    Else
      GlobalErrors.SetFile(FileName)
      Loc:FileName = FileName
    End
    Case FM.GetError()
    Of Msg:DeleteFailed
      Case FileErrorCode()
      Of 23000
        Message('Ошибка при удалении строки ' |
         & 'из справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         ,'Ошибка удаления записи',Icon:Exclamation)
        Return Level:Notify
      End
    Of Msg:AddFailed Orof Msg:PutFailed
      Case FileErrorCode()
      Of 23000
        Message('Введено дублирующее или недопустимое значение ' |
         & 'для справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         ,'Ошибка создания записи',Icon:Exclamation)
        Return Level:Notify
      Else
        Message('Введено дублирующее или недопустимое значение ' |
         & 'для справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         ,'Ошибка сохранения записи',Icon:Exclamation)
        Return Level:Notify
      End
    End
    !Stop('FileError=' & FileError() & ' FileErrorCode=' & FileErrorCode())
    RETURN GlobalErrors.ThrowMessage(Fm.GetError(),FileName)
А внутри процедур FileManager прописываем свою обработку ошибки, например, для таблицы Order пишем

Код: Выделить всё

Hide:Access:Order.Throw PROCEDURE

ReturnValue          BYTE,AUTO

  CODE
   !------------------- Здесь наша вставка в метод Throw 
      Return Self.FileThrow('Заказ')
  !------------------------------------------------        
  ReturnValue = PARENT.Throw()
  RETURN ReturnValue
Делал руками, но можно, наверное, и шаблоном сгенерить или класс унаследовать.
Мне показалось руками проще...

В результате имеем свою обработку ошибок и содержательные сообщения
Ну и ещё простенькая процедура - просто возвращает текст сообщения об ошибке - мож пригодится

Код: Выделить всё

GetErrorText         PROCEDURE  (*FileManager FM)          ! Declare Procedure
  CODE
! Before Embed Point: %ProcessedCode) DESC(Processed Code) ARG()
  IF FM.GetError() 
     Return( Fm.ThrowMessage(Fm.GetError(),Fm.GetName()))
  END
  Return('')

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 16:09
Shur
Мне кажется, что это борьба со следствием. Если в словаре данных правильно прописать relations, правильно указать реакцию на каскадные операции, то sql-ошибка не возникнет, а будут появляться вполне себе адекватные (локализованные, надеюсь) сообщения Клариона.

Если удаление все же необходимо, то можно написать кларионовский триггер на данную таблицу, где сделать соответствующие проверки.

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 16:43
kreator
Юрий, спасибо, хоть есть направление куда смотреть.
Shur писал(а):Мне кажется, что это борьба со следствием. Если в словаре данных правильно прописать relations, правильно указать реакцию на каскадные операции, то sql-ошибка не возникнет, а будут появляться вполне себе адекватные (локализованные, надеюсь) сообщения Клариона.
Дело в том, что всё прописано на сервере. А в словаре только указание, что всё прописано на сервере :mrgreen: . Поэтому Кларион тупо воспроизводит сообщения сервера. Как это по-научному - FrontEnd и BackEnd?

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 17:08
Shur
Дело в том, что всё прописано на сервере. А в словаре только указание, что всё прописано на сервере :mrgreen: . Поэтому Кларион тупо воспроизводит сообщения сервера.
Скорее всего в словаре для этой таблицы указано, что обработка каскадов будет производиться на сервере (поэтому Кларион "тупо" отдает управление на сервер, а потом так же "тупо" воспроизводит сообщения), а вам надо указать, что обработку каскадов надо делать в Кларе.

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 17:18
Yufil
Это вполне рабочая процедура, для MS SQL Server можно пользовать, только зайти в глобальные embed'ы и в метод Throw для всех таблиц MS SQL понатыкать обработчики.

Есть ещё обработчик разрыва связи с БД, чтобы программа тихо завершалась в таких случаях (все равно ничего не придумаешь), а не терзала оператора сообщениями.

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 20:40
kreator
Shur писал(а):а вам надо указать, что обработку каскадов надо делать в Кларе.
Спасибо не надо, пусть сервак работает. Это его прямая обязанность.

Человеческий язык SQL ошибок.

Добавлено: 17 Ноябрь 2015, 22:02
Shur
kreator писал(а):...пусть сервак работает. Это его прямая обязанность.
OK. Раз каскадность на уровне сиквела, пусть на уровне сиквела.
Тогда не совсем понятно, отчего вообще взялось такое сообщение. Значит в базе есть форейн кей, но отсутствует триггер на удаление, обеспечивающий каскадную обработку (или целостность для данного случая).
В MS SQL можно в таком триггере можно элементарно взвести raiserror c русскоязычным сообщением. В Firebird должно существовать что-то аналогичное

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 12:18
kreator
Shur писал(а):Тогда не совсем понятно, отчего вообще взялось такое сообщение. Значит в базе есть форейн кей, но отсутствует триггер на удаление, обеспечивающий каскадную обработку (или целостность для данного случая).
В MS SQL можно в таком триггере можно элементарно взвести raiserror c русскоязычным сообщением. В Firebird должно существовать что-то аналогичное
В базе есть форейн ключ, допустим, с запретом удаления (каскадное удаление пройдет без сообщений, думаю, поэтому случай неинтересный). Было бы хорошо получить русскоязычное сообщение от сервера. Особенно, если это делается элементарно. Как?

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 12:45
Yufil
Ну, приведённый метод выведет сообщение типа 'Ошибка удаления строки из справочника "Единицы", поскольку на него ссылаются другие таблицы'. Можно докрутить разбор сообщения дальше, если есть желание.

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 12:51
kreator
Yufil писал(а): Ну, приведённый метод выведет сообщение типа 'Ошибка удаления строки из справочника "Единицы", поскольку на него ссылаются другие таблицы'. Можно докрутить разбор сообщения дальше, если есть желание.
Ну а как это? Что-то дополнительно на серваке нужно делать. MS SQL не пользую пока. Есть, например, Firebird. Вроде как в отработку форейн-ключа не влезешь (???).

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 13:08
Shur
kreator писал(а):В базе есть форейн ключ, допустим, с запретом удаления (каскадное удаление пройдет без сообщений, думаю, поэтому случай неинтересный). Было бы хорошо получить русскоязычное сообщение от сервера. Особенно, если это делается элементарно. Как?
Вот я и говорю про триггер на удаление для данной таблицы, в котором делается проверка на целостность, в случае нарушения должна взводиться пользовательская ошибка и делаться откат транзакции.

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 14:39
Shur
Кстати, без написания триггера, может быть есть возможность русификации Firebird? Сообщение, правда, будет на полуптичьем языке, но всё ж.
Нашел ссылку http://www.sql.ru/forum/101615/lokaliza ... b-oshibkah. Но так и не понял, было ли найдено приемлемое решение. Да и времени с тех пор утекло.
Kreator, в эту сторону не смотрели?

Человеческий язык SQL ошибок.

Добавлено: 18 Ноябрь 2015, 15:25
kreator
Хорошая ссылка, спасибо. Но что-то ж... чувствую - не надо туда лезть. На стороне клиента кажется удобней и универсальней. Опять же тема может действительно развиться до сообщений бизнес-логики, а не просто "есть ссылка на это поле".