Mam bardzo długo działającą procedurę przechowywaną w SQL Server 2005, którą próbuję debugować i używam do tego polecenia „print”. Problem polega na tym, że odbieram wiadomości z SQL Server tylko na samym końcu mojego sproc - chciałbym móc opróżnić bufor komunikatów i zobaczyć te komunikaty natychmiast podczas uruchamiania sproca, a nie na samym początku koniec.
sql-server
tsql
printing
Erik Forbes
źródło
źródło
Odpowiedzi:
Użyj
RAISERROR
funkcji:Nie powinieneś całkowicie zamieniać wszystkich swoich wydruków na horror. Jeśli masz gdzieś pętlę lub duży kursor, po prostu zrób to raz lub dwa razy na iterację, a nawet co kilka iteracji.
Ponadto: po raz pierwszy dowiedziałem się o RAISERROR pod tym linkiem, który teraz uważam za ostateczne źródło obsługi błędów SQL Server i zdecydowanie warto przeczytać:
http://www.sommarskog.se/error-handling-I.html
źródło
Opierając się na odpowiedzi @JoelCoehoorn, moim podejściem jest pozostawienie wszystkich moich instrukcji PRINT na miejscu i po prostu stosowanie się do nich za pomocą instrukcji RAISERROR, aby spowodować kolor.
Na przykład:
Zaletą tego podejścia jest to, że instrukcje PRINT mogą łączyć łańcuchy, podczas gdy RAISERROR nie. (Tak czy inaczej, masz taką samą liczbę wierszy kodu, jak będziesz musiał zadeklarować i ustawić zmienną do użycia w RAISERROR).
Jeśli, podobnie jak ja, używasz AutoHotKey lub SSMSBoost lub równoważnego narzędzia, możesz łatwo skonfigurować skrót, taki jak „] flush”, aby wprowadzić dla siebie linię RAISERROR. Oszczędza to czas, jeśli jest to ten sam wiersz kodu za każdym razem, tzn. Nie trzeba go dostosowywać, aby przechowywał określony tekst lub zmienną.
źródło
RAISERROR()
obsługujeprintf()
interpolację ciągów w stylu. Na przykład, jeśli@MyVariableName
jest typem stringish (npVARCHAR(MAX)
,NVARCHAR(MAX)
etc.), można skorzystaćRAISERROR()
z jednej linii:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Tak ... Pierwszy parametr funkcji RAISERROR wymaga zmiennej NVARCHAR. Więc spróbuj następujących;
LUB
źródło
Inną lepszą opcją jest nie poleganie na DRUKOWANIU lub RAISERROR, a jedynie załadowanie instrukcji „print” do tabeli ## Temp w TempDB lub stałej tabeli w bazie danych, która zapewni natychmiastową widoczność danych za pośrednictwem instrukcji SELECT z innego okna . To działa najlepiej dla mnie. Użycie stałego stołu służy również jako dziennik wydarzeń z przeszłości. Instrukcje drukowania są przydatne w przypadku błędów, ale za pomocą tabeli dziennika można również określić dokładny punkt awarii na podstawie ostatniej zarejestrowanej wartości dla tego konkretnego wykonania (zakładając, że śledzisz ogólny czas rozpoczęcia wykonywania w tabeli dziennika).
źródło
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
sesji monitorowaniaREAD UNCOMMITTED
transakcji do innej tabeli, ale prawdopodobnie przegapisz chwilę wcześniejROLLBACK
. Prawdopodobnie rozwiązuje to pytanie „jak daleko?” nie „dlaczego wycofać?”Tylko dla odniesienia, jeśli pracujesz w skryptach (przetwarzanie wsadowe), a nie w procedurze przechowywanej , dane wyjściowe opróżniania są wyzwalane przez komendę GO, np.
Ogólnie rzecz biorąc, mój wniosek jest następujący: dane wyjściowe wykonania skryptu mssql, uruchamiane w graficznym interfejsie SMS lub za pomocą sqlcmd.exe, są opróżniane do pliku, stdoutput, okno GUI na pierwszej instrukcji GO lub do końca skryptu.
Płukanie wewnątrz procedury przechowywanej działa inaczej, ponieważ nie można umieścić GO w środku.
Odniesienie: instrukcja tsql Go
źródło
go
nie tylko opróżnia wyjście, ale kończy partię zgodnie z podanym linkiem. Cokolwiekdeclare
d zostanie odrzucone, więc nie jest bardzo przydatne do debugowania.declare @test int print "I want to read this!" go set @test=5
będzie zgłaszać błąd, twierdząc, że błąd@test
jest niezdefiniowany, ponieważ jest w nowej partii.