Forum Użytkownikow Subiekt GT

InsERT GT => Dodatki - zestawienia - sfera => Wątek zaczęty przez: tomaszf w Marzec 07, 2017, 08:57:42

Tytuł: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 08:57:42
Witam.

Potrzebuje napisać trigger "pilnujący" czy faktura wystawiana jest we właściwy sposób.
Naklepałem coś takiego:

BEGIN
  BEGIN TRY
    DECLARE @PoleWlasne VARCHAR(MAX)
    DECLARE @ZadanySposob int
    DECLARE @WybranySposob int
    DECLARE @KHID int
    DECLARE @blad int
    DECLARE @typDok int
    SET @blad = 0

    SET @typDok = (SELECT ISNULL(dok_typ, 0) FROM inserted)

    IF (@typDok = 2 OR  @typDok = 11 OR @typDok = 16)
    BEGIN   
      SET @KHID = (SELECT ISNULL(dok_OdbiorcaId, 0) FROM inserted)
      SET @PoleWlasne = (SELECT isnull(LOWER(kh_Pole8), '') FROM kh__kontrahent WHERE kh_Id = @khid)   
   
      IF (@PoleWlasne = 'netto')   
        BEGIN     
          SET @ZadanySposob = 1   
        END
      ELSE
        BEGIN
          IF (@PoleWlasne = 'brutto')
            SET @ZadanySposob = 0         
          ELSE
            SET @ZadanySposob = -1       
        END   

      SET @WybranySposob = ( SELECT TOP 1 dok_CenyTyp FROM inserted )   

      IF (@ZadanySposob >= 0)
        BEGIN 
          IF (@ZadanySposob <> @WybranySposob)
            SET @blad = 1
          ELSE
            SET @blad = 0
         END
             
      IF ( @blad > 0 ) 
        RAISERROR('<msg>Wybierz poprawny sposób przeliczania dokumentu!</msg>', 16, 1)
    END
  END TRY

  BEGIN CATCH
  END CATCH;
END

Jednak zamiast oczekiwanego komunikatu pojawia się dymek z treścią "Błąd składniowy w poleceniu" (bez linka do właściwej treści).
Co zrobiłem źle?

Ps. Wiem że cały kod można uprościć, ale został maksymalnie rozbity na potrzeby analizy błędu.

Pozdrawiam i dziękuję.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: dkozlowski w Marzec 07, 2017, 14:48:51
Zobacz jaki jest rzeczywisty komunikat błędu i powinno trochę się rozjaśnić. Ogólnie blokady nie należą do łatwych rozwiązań, trzeba bardzo dobrze poznać działanie programu.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 15:30:59
Do CATCH procedura nie wchodzi, co masz na myśli pisząc o rzeczywistym komunikacie?
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: candy w Marzec 07, 2017, 15:50:37
Wciśnij F1 i poszukaj "Przechwytywanie w aplikacji błędów SQL Servera"
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 15:58:50
Candy pisząc to co pokazałem posiłkowałem się właśnie tym tematem z pliku pomocy.
Nie widzę tu nic co mogło by pomóc przy rozwiązaniu problemu.

Ps. jeśli miałeś na myśli dodanie klucza w rejestrze to nie zmienia od treści błędu w dymku.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: candy w Marzec 07, 2017, 16:02:05
Ps. jeśli miałeś na myśli dodanie klucza w rejestrze to nie zmienia od treści błędu w dymku.
Mam pewne podejrzenia że nie przeczytałeś ostatniego zdania ze wskazanego przeze mnie opisu:
"Funkcjonalność przechwytywania w aplikacji błędów SQL Servera jest aktywna tylko dla posiadaczy abonamentu na ulepszenia."
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: dkozlowski w Marzec 07, 2017, 16:02:20
co masz na myśli pisząc o rzeczywistym komunikacie?

No pisałem o wyjątku generowanym przez serwer SQL.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 17:17:28
Candy  doczytałem ;).
Przykład z pomocy działa poprawnie.

Daniel niestety wyjątkiem nie rzuca.
Jeśli zmienię RAISERROR  na jakiś insert do loga to zapisuje się poprawnie.
Tytuł: Trigger SQL - RAISERROR
Wiadomość wysłana przez: candy w Marzec 07, 2017, 17:22:05
To może jeszcze świadczyć o tym że trigger powoduje inny błąd niż ten który przewidziałeś.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 17:24:36
Candy tak jak napisałem wcześniej jak zmienię RAISERROR na coś innego (np INSERT do tabeli z logami) to działa poprawnie.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: dkozlowski w Marzec 07, 2017, 18:12:11
Daniel niestety wyjątkiem nie rzuca.
Jeśli zmienię RAISERROR  na jakiś insert do loga to zapisuje się poprawnie.

No jak nie rzuca błędem skoro masz komunikat:

Jednak zamiast oczekiwanego komunikatu pojawia się dymek z treścią "Błąd składniowy w poleceniu" (bez linka do właściwej treści).

Oczywiście cały czas piszę o błędzie generowanym przez serwer SQL, ale przez Ciebie.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 07, 2017, 22:33:57
Szczerze mówiąc nie rozumiem.

Zamieniając linijkę
IF ( @blad > 0 ) 
        RAISERROR('<msg>Wybierz poprawny sposób przeliczania dokumentu!</msg>', 16, 1)

na np

IF ( @blad > 0 ) 
        INSERT INTO trig_log (txt) VALUES ('TU POWINIEN BYĆ DYMEK')   

Przy spełnionym warunku (wyborze sposobu przeliczania inny niż w PW) w tabelce trig_log pojawia się rekord TU POWINIEN BYĆ DYMEK, więc wydaje mi się, że sam trigger działa poprawnie a błąd powoduje RAISERROR....
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: dkozlowski w Marzec 07, 2017, 23:00:56
Szczerze mówiąc nie rozumiem.

Najprościej jest skorzystać z Profilera.

Przy spełnionym warunku (wyborze sposobu przeliczania inny niż w PW) w tabelce trig_log pojawia się rekord TU POWINIEN BYĆ DYMEK, więc wydaje mi się, że sam trigger działa poprawnie a błąd powoduje RAISERROR....

Wydaje się być oczywistym, że jeśli trigger działaby poprawnie to zobaczyłbyś dymek z treścią błędu w programie, a skoro tak się nie dzieje to trigger jednak nie działa poprawnie.

ps.
Pozostaje wszystko aktualne co napisałem w pierwszej odpowiedzi.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 08, 2017, 11:33:57
Sprawdzając błędy profilerem  dostałem coś takiego:
User Error Message  -  <msg>Wybierz poprawny sposób przeliczania dokumentu!</msg>
Exception  -  The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
User Error Message  -  The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
User Error Message  -  The statement has been terminated.

Wychodzi na to, że trigger poprawnie przekazuje zamierzony komunikat, ale "przy okazji" generuje inny błąd...
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: candy w Marzec 08, 2017, 11:48:10
Wychodzi na to, że trigger poprawnie przekazuje zamierzony komunikat, ale "przy okazji" generuje inny błąd...

Czyli tradycyjnie:
- Panie doktorze, wszyscy mnie ingorują
- Następny, proszę!

To może jeszcze świadczyć o tym że trigger powoduje inny błąd niż ten który przewidziałeś.
Tytuł: Odp: Trigger SQL - RAISERROR
Wiadomość wysłana przez: tomaszf w Marzec 08, 2017, 13:07:46
To może inaczej:

czy po treści błędów które podałem w poprzednim poście, ktoś jest w stanie podpowiedzieć czemu tak się dzieje i co zmienić w tym triggerze, aby nie "gryzł się" z programem?