SQL Server w logistyce

Przejęcie kolumn standardowych w dostosowaniu systemu i jego koszt

Dane klienta leżą w osobnej tabeli rozszerzenia, ale część jego pojęć trafiła do istniejących kolumn standardowych. Poniżej opisujemy mechanizm i skutek dla każdego, kto czyta te kolumny po nazwach.

sql.server.net.pl/sql-server/
Programista przy dwóch monitorach z kodem w ciemnym biurze
Programista przy dwóch monitorach z kodem w ciemnym biurze
W skrócie
  • Tabela rozszerzenia: dane klienta leżą w osobnej tabeli w osobnym schemacie, powiązanej z awizacją numerem referencyjnym.
  • Przejęte kolumny: część pojęć klienta nie dostała własnej kolumny i weszła do istniejących kolumn standardowych.
  • Skutek: zapytanie czytające te kolumny po nazwach daje nieprawdę, także gdy stoi za raportem albo eksportem.
  • Zasada: opis pola musi mówić o jego funkcji, a nie o nazwie kolumny.

Opisujemy dostosowanie systemu awizacji Studio VSS.net do potrzeb jednego klienta. To przypadek jednego wdrożenia, a nie opis standardu produktu. Artykuł pokazuje koszt pewnego wyboru, a nie wzorzec do powtórzenia. Kod napisaliśmy od nowa na podstawie opisu schematu, z nazwami przykładowymi, takimi jak rozszerzenie.tabela_rozszerzenia i widok_awizacji.

Nazwy kolumn standardowych pojawiają się tu wyłącznie jako opis funkcji pola. W przykładowym kodzie kolumny mają uproszczone nazwy, więc kod służy do pokazania mechanizmu, a nie do skopiowania.

Tabela rozszerzenia w osobnym schemacie

Dane specyficzne dla klienta leżą w osobnej tabeli rozszerzenia, w osobnym schemacie bazy. Tabela zbiera cztery grupy pól.

  • Ilości: kartony i sztuki.
  • Towar: kategorie produktów i sposób pakowania.
  • Dokumenty: dokumenty eksportowe i miejsce uznane.
  • Dostawa: rodzaj dostawy i wymiary palety.

Powiązanie z awizacją idzie przez numer referencyjny, czyli wartość wydawaną jako unikalna w skali całej bazy, którą opisuje strona o tabeli _refno. Relacja jeden do jednego wynika ze sposobu zapisu, a nie z ograniczenia bazy, więc sama baza nie wymusza jednego wiersza na numer.

CREATE SCHEMA rozszerzenie;
GO

CREATE TABLE rozszerzenie.tabela_rozszerzenia (
    numer_ref       bigint       NOT NULL,
    kartony         int          NULL,
    sztuki          int          NULL,
    pakowanie       nvarchar(30) NULL,
    rodzaj_dostawy  nvarchar(30) NULL,
    miejsce_uznane  bit          NULL
);

Przykład ilustracyjny, skrócony do kilku pól. Nie ma tu klucza obcego ani ograniczenia unikalności, bo powiązanie pilnuje sposób zapisu.

W jednej ze standardowych tabel poszerzono kolumnę tekstową. Kolumna z numerami zamówień urosła ze 100 do 1000 znaków, żeby mieścić listę kilku numerów rozdzielonych średnikiem. Zmianę typu kolumny opisuje dokumentacja ALTER TABLE.

Widoki jako warstwa opisów

Obok tabeli rozszerzenia klient ma kilkanaście widoków, które zamieniają kody na opisy ze słowników. Widoki korzystają z sześciu słowników: rodzaj awizacji, typ transportu, rodzaj kontenera, magazyn, oddział i rampa. Odbiorca zapytania widzi dzięki nim opis zamiast kodu, a treść słownika zmienia się w jednym miejscu.

Widoki rozróżniają też dostawy i wysyłki. Awizacje mają pole kierunku: dostawy mają kierunek IN, a wysyłki kierunek OUT, i widoki filtrują po tym polu. Widoki dostaw przyjmują dodatkowo puste pole kierunku. Zwroty oznacza rodzaj awizacji oraz cecha dokumentu, z jedną wartością dla zwrotu towarowego i drugą dla paletowego.

Zestawienia platformy czytają dane z takich widoków, a ich definicje opisuje strona o tabeli x_zestawienia. Treść zapytań ekranów platforma przechowuje w repozytorium zapytań. Przykład widoku zasilającego odpowiedzi API pokazujemy w artykule o API awizacji na procedurach SQL i JSON. Składnię widoku opisuje dokumentacja CREATE VIEW.

Kolumny, które przejęły nowe pojęcia

Część pojęć klienta nie dostała własnej kolumny. Weszła do kolumny standardowej, która w tej samej tabeli ma nadal swoją pierwotną funkcję. Tabela zestawia sześć takich przypadków.

Kolumny standardowe i ich znaczenie u klienta
Kolumna standardowaZnaczenie w standardzieZnaczenie u klienta
Kolumna dokumentu tożsamości kierowcyDokument tożsamości kierowcyNumer kontenera. W zwrotach kolumna zachowuje znaczenie standardowe.
Kolumna zdjęcia tablicy rejestracyjnejOdnośnik do zdjęcia tablicy rejestracyjnej, a nie numer tablicyNumer dokumentu odprawy.
DDPAwizacja bezpośrednio od dostawcy z pominięciem działu transportuW dostawach importowych dane do uzupełnienia. W wysyłkach CMR zatwierdzony przez rolę Eksport.
PiętrowaniePiętrowanie paletZnacznik korekty danych kierowcy, a od statusu 4 znacznik kontenera oclonego w całości.
Waga wyjazdowaWaga przy wyjeździeOdprawa zakończona.
Waga wjazdowa (wysyłki)Waga przy wjeździeDokumenty EUR1 lub CO dołączone.

Sześć kolumn standardowych z nowym znaczeniem w opisywanym wdrożeniu.

Tabela rozszerzenia i kolumny z nowym znaczeniem Schemat: tabela rozszerzenia w osobnym schemacie w relacji 1:1 z awizacją, widoki opisów oraz sześć kolumn standardowych, które u klienta mają inne znaczenie. Tabela rozszerzenia i kolumny z nowym znaczeniemDane klienta mają osobną tabelę, a część pojęć wchodzi do istniejących kolumnAwizacja (tabele standardowe)Kalendarz i dane awizacji.Tabela rozszerzeniaOsobny schemat. Powiązanie po numerzereferencyjnym (1:1 z zapisu).Kartony i sztuki, kategorie i pakowanie,dokumenty eksportowe i miejsceuznane oraz wymiary palety.1:1WidokiZamieniają kody na opisy ze słowników: rodzajawizacji, transport, magazyn, rampa.Kolumna standardowaW standardzieU klientaDokument tożsamościkierowcyDane kierowcyNumer konteneraTablica rejestracyjnaZdjęcie tablicyNumer dokumentu odprawyDDPDostawa bezpośredniaDostawy: do uzupełnienia. Wysyłki: CMRzatwierdzonyPiętrowaniePiętrowanie paletKorekta danych kierowcy, od odprawykontener oclonyWaga wyjazdowaWaga przy wyjeździeOdprawa zakończonaWaga wjazdowa (wysyłki)Waga przy wjeździeDokumenty EUR1 lub CO dołączoneSkutek odczytu po nazwie kolumnyZapytanie czytające te kolumny po nazwach daje nieprawdę, także w raporcie. Opis pola musimówić o jego funkcji.Rozszerzone poleKolumna numerów zamówień urosła ze 100 do 1000 znaków, bo mieści listę numerów po średniku.
Schemat: tabela rozszerzenia powiązana z awizacją po numerze referencyjnym oraz kolumny standardowe z nowym znaczeniem u klienta.

Numer kontenera leży w kolumnie dokumentu tożsamości kierowcy. W zwrotach ta kolumna zachowuje znaczenie standardowe, więc o jej treści decyduje rodzaj awizacji. Numer dokumentu odprawy leży w kolumnie, która w standardzie przechowuje odnośnik do zdjęcia tablicy rejestracyjnej. Procesy, w których te numery występują, opisują artykuły o agencji celnej w statusie magazynowym kontenera oraz o danych kierowcy uzupełnianych przez tego, kto je zna.

Flaga DDP znaczy w standardzie awizację przyjmowaną bezpośrednio od dostawcy z pominięciem działu transportu. W dostawach importowych oznacza u klienta dane do uzupełnienia. Ustawia się ją przy założeniu awizacji importowej, a zdejmuje po uzupełnieniu danych transportu i kierowcy. W zestawieniach nosi podpis Wymagana korekta. W wysyłkach ta sama kolumna znaczy, że CMR zatwierdziła rola Eksport, o czym piszemy w artykule o wysyłce eksportowej i bramkach między rolami.

Kolumny wag przejęto na flagi. Waga wyjazdowa znaczy odprawa zakończona. W wysyłkach waga wjazdowa znaczy dokumenty EUR1 lub CO dołączone, a flagę wagi wjazdowej kasuje krok końca odprawy.

Jedna kolumna, trzy znaczenia

Najwięcej znaczeń niesie kolumna piętrowania. W standardzie oznacza piętrowanie palet. U klienta ma jeszcze dwa znaczenia zależne od statusu: znacznik korekty danych kierowcy w statusach 1 i 2 oraz, od statusu 4, znacznik kontenera oclonego w całości. Korekta danych kierowcy po kontroli bramy korzysta więc z innej kolumny niż flaga DDP.

Wartość tej kolumny ustawiają i zerują różne zdarzenia. Zestawiamy je w tabeli.

Zdarzenia, które ustawiają i zerują kolumnę piętrowania
ZdarzenieSkutek dla kolumny
Zaznaczenie korekty przy potwierdzeniu przybyciaUstawia znacznik korekty danych kierowcy
Korekta danych kierowcyZeruje znacznik
Dostawy: przejście z weryfikacji do rampyZeruje znacznik
Dostawy: wyjazdZeruje znacznik
Wysyłki: zgoda na odprawęZeruje znacznik
Wysyłki: koniec odprawyZeruje znacznik
Wysyłki: wyjazdZeruje znacznik
Od statusu 4: krok agencji celnej z wynikiem kontener oclony w całościUstawia znacznik kontenera oclonego

Zdarzenia według opisu wdrożenia. Wartość niezerowa blokuje ekran zmiany statusu do czasu korekty.

Blokada dotyczy w dostawach statusów 1 i 2. Dopóki dane kierowcy nie zostaną skorygowane, ekran zmiany statusu nie przepuści awizacji dalej. Ta sama kolumna ma więc inne znaczenie w statusie 2 i po odprawie, a zerują ją także zwykłe przejścia statusów, oprócz samej korekty danych.

Dlaczego odczyt po nazwie kolumny daje fałsz

Zapytanie, które czyta te kolumny po nazwach, daje nieprawdę, także gdy stoi za raportem albo eksportem. Pierwsze z poniższych zapytań wygląda jak lista awizacji przyjmowanych bezpośrednio od dostawcy.

SELECT a.numer_awizacji, a.kierunek
FROM dbo.awizacje AS a
WHERE a.ddp = 1;

SELECT SUM(a.waga_wjazdowa) AS laczna_waga
FROM dbo.awizacje AS a
WHERE a.kierunek = 'OUT';

Przykład ilustracyjny. Zakładamy, że flaga to wartość 1.

Pierwsze zapytanie zwróci między innymi dostawy importowe, które czekają na uzupełnienie danych, oraz wysyłki z CMR zatwierdzonym przez rolę Eksport. Awizacje z tych dwóch grup nie są przyjmowane bezpośrednio od dostawcy w znaczeniu standardu. Drugie zapytanie zwróci liczbę, która wygląda jak łączna waga, a w wysyłkach liczy flagi dokumentów EUR1 lub CO. Żadne z nich nie zgłosi błędu, bo składniowo oba są poprawne.

Opis pola musi mówić o jego funkcji, a nie o nazwie kolumny.

Widok nazywa kolumnę według funkcji i zależnie od rodzaju oraz statusu awizacji. W przykładzie przyjmujemy reguły wymyślone, które pokazują wzorzec, a nie odtwarzają wdrożenia.

CREATE VIEW dbo.widok_awizacji
AS
SELECT a.numer_awizacji,
       a.kierunek,
       CASE WHEN a.rodzaj <> 'ZWR' THEN a.dok_tozsamosci END AS numer_kontenera,
       CASE WHEN a.rodzaj = 'ZWR' THEN a.dok_tozsamosci END AS dokument_kierowcy,
       CASE WHEN a.kierunek = 'IN' THEN a.ddp END AS dane_do_uzupelnienia,
       CASE WHEN a.kierunek = 'OUT' THEN a.ddp END AS cmr_zatwierdzony,
       CASE WHEN a.kierunek = 'OUT' THEN a.waga_wjazdowa END AS dokumenty_eur1_co,
       CASE WHEN a.status IN (1, 2) THEN a.pietrowanie END AS korekta_danych_kierowcy,
       CASE WHEN a.status >= 4 THEN a.pietrowanie END AS kontener_oclony_w_calosci
FROM dbo.awizacje AS a;

Przykład ilustracyjny. Nazwy kolumn i reguły CASE są wymyślone, a widok ma inne kolumny niż w artykule o API.

Odczyt przez taki widok nie pomyli już funkcji pól. Koszt widać jednak od drugiej strony: każdy, kto czyta tabelę bezpośrednio, a nie przez widok, musi znać te reguły z dokumentacji, bo sama baza ich nie zdradza.

Podobny problem dotyczy podpisów. Zestawienia platformy zamieniają nazwy kolumn na podpisy, a w opisywanym wdrożeniu przemianowano podpisy na pojęcia klienta: numer kontenera, numer dokumentu odprawy, wymagana korekta i oclony cały kontener.

Podpis Wymagana korekta jest przypisany do kolumny DDP w zestawieniach dostaw. Podpis oclony cały kontener istnieje w definicjach zestawień, ale kolumna jest w nich ukryta. W zestawieniach zwrotów kolumna dokumentu tożsamości kierowcy zachowuje swój podpis. Definicje podpisów opisuje strona o tabeli x_zestawienia_kolumny.

Pytania przed przejęciem kolumny

Artykuł opisuje koszt tej decyzji w jednym wdrożeniu i nie traktujemy go jako wzorca. Przed podobnym wyborem w innym systemie odpowiedz na cztery pytania.

  • Odczyt po nazwie: kto czyta kolumnę po nazwie: raport, eksport, integracja albo ekran standardowy.
  • Zależność od statusu: czy znaczenie zmienia się wraz ze statusem lub rodzajem awizacji i gdzie to zapisano.
  • Podpisy: czy podpis kolumny w zestawieniach mówi o funkcji pola, czy o jego pierwotnej nazwie.
  • Własna kolumna: co zmieniłoby się w odczytach, gdyby pojęcie dostało własną kolumnę w tabeli rozszerzenia.
FAQ

Najczęstsze pytania o kolumny standardowe z nowym znaczeniem

01

Gdzie klient trzyma dane spoza standardowych tabel awizacji?

Dane klienta leżą w osobnej tabeli rozszerzenia w osobnym schemacie bazy. Powiązanie z awizacją idzie przez numer referencyjny, a relacja jeden do jednego wynika ze sposobu zapisu, nie z ograniczenia bazy.

02

Które kolumny standardowe przejęto na własne pojęcia?

Numer kontenera leży w kolumnie dokumentu tożsamości kierowcy, a numer dokumentu odprawy w kolumnie z odnośnikiem do zdjęcia tablicy rejestracyjnej. Przejęto też kolumnę DDP i kolumnę piętrowania, a kolumny wag służą jako flagi.

03

Dlaczego jedna kolumna ma kilka znaczeń zależnych od statusu?

Część pojęć klienta nie dostała własnej kolumny, więc weszła do istniejącej. Kolumna piętrowania oznacza w standardzie piętrowanie palet, a u klienta niesie też znacznik korekty danych kierowcy w statusach 1 i 2 oraz, od statusu 4, znacznik kontenera oclonego w całości.

04

Jak zabezpieczyć raporty przed błędnym odczytem takich kolumn?

Opis pola musi mówić o jego funkcji, a nie o nazwie kolumny. Widok, który nazywa kolumnę według funkcji i uwzględnia rodzaj oraz status awizacji, nie myli znaczeń, a odczyt tabeli po nazwach kolumn daje nieprawdę.

05

Po co widoki zamieniają kody na opisy?

Widoki zamieniają kody na opisy z sześciu słowników: rodzaj awizacji, typ transportu, rodzaj kontenera, magazyn, oddział i rampa. Odbiorca zapytania widzi opis zamiast kodu, a widoki filtrują też po kierunku IN lub OUT.

Słownik pojęć

Słownik pojęć

Pojęcia z kodu i wdrożenia opisanych w artykule.

TTabela rozszerzenia
Osobna tabela na dane specyficzne dla klienta, powiązana z tabelą standardową kluczem. W opisywanym wdrożeniu kluczem jest numer referencyjny awizacji.
SSchemat bazy
Przestrzeń nazw w bazie, która grupuje obiekty takie jak tabele i widoki. Tabela rozszerzenia leży w opisywanym wdrożeniu w osobnym schemacie.
WWidok SQL
Zapisane zapytanie SELECT, do którego odwołujemy się jak do tabeli. Widoki z opisu zamieniają kody na opisy ze słowników.
PPrzejęcie kolumny
Nadanie istniejącej kolumnie standardowej nowego znaczenia zamiast dopisania własnej kolumny. Odczyt po nazwie kolumny daje wtedy nieprawdę.
SSłownik kodów
Tabela, która wiąże kod z opisem, na przykład rodzaj awizacji albo rampę. Widoki łączą się z nią, żeby pokazać opis zamiast kodu.
NNumer referencyjny
Unikalny w skali bazy numer, który wiąże rekord z jego danymi pomocniczymi. Łączy awizację z jej wierszem w tabeli rozszerzenia.
KKierunek awizacji
Pole, które odróżnia dostawy od wysyłek: dostawy mają wartość IN, wysyłki OUT. Widoki filtrują po tym polu.

Zobacz to w praktyce

Sprawdź, jak systemy SoftwareStudio oparte na MS SQL Server wspierają ten obszar Twojej firmy.