{"id":9671,"date":"2024-07-17T12:20:01","date_gmt":"2024-07-17T10:20:01","guid":{"rendered":"https:\/\/pomoc.comarch.pl\/cee\/640\/?post_type=ht_kb&#038;p=9671"},"modified":"2024-07-17T13:24:05","modified_gmt":"2024-07-17T11:24:05","slug":"programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji","status":"publish","type":"ht_kb","link":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/","title":{"rendered":"Programowanie wirtualnych tabel, funkcji i kolumn relacji"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Spis tre\u015bci<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Prze\u0142\u0105cznik Spisu Tre\u015bci\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Wprowadzenie\" >Wprowadzenie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Grupa_docelowa\" >Grupa docelowa<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Programowanie_wirtualnych_tabel_i_funkcji\" >Programowanie wirtualnych tabel i funkcji<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Definiowanie_nazwy_tabeli\" >Definiowanie nazwy tabeli<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Rozwiazywanie_konfliktow_nazw\" >Rozwi\u0105zywanie konflikt\u00f3w nazw<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Definiowanie_kolumn_tabeli\" >Definiowanie kolumn tabeli<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Nazwa_kolumny\" >Nazwa kolumny<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Typ_danych\" >Typ danych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Parametr_wyjsciowy\" >Parametr wyj\u015bciowy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Parametry_wejsciowe\" >Parametry wej\u015bciowe<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Definiowanie_typow_baz_danych\" >Definiowanie typ\u00f3w baz danych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Definiowanie_uprawnien\" >Definiowanie uprawnie\u0144<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Waznosc_instancji_klasy\" >Wa\u017cno\u015b\u0107 instancji klasy<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Inicjalizacja_zmiennych_instancji\" >Inicjalizacja zmiennych instancji<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Obliczanie_wyniku_tabeli\" >Obliczanie wyniku tabeli<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Tabela_wirtualna\" >Tabela wirtualna<\/a><ul class='ez-toc-list-level-6' ><li class='ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Wykonanie_jednorazowe\" >Wykonanie jednorazowe<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Wykonanie_w_blokach\" >Wykonanie w blokach<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-6'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Wykonanie_metody_run\" >Wykonanie metody run()<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Funkcja_wirtualna\" >Funkcja wirtualna<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Okreslanie_kontekstu_runtime\" >Okre\u015blanie kontekstu runtime<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Rejestracja_wirtualnych_tabel_lub_funkcji\" >Rejestracja wirtualnych tabel lub funkcji<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Automatyczna_konwersja_zawartosci_kolumny_typu_danych_Text\" >Automatyczna konwersja zawarto\u015bci kolumny typu danych Text<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Programowanie_wirtualnych_kolumn_relacji\" >Programowanie wirtualnych kolumn relacji<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Nazwa_kolumny-2\" >Nazwa kolumny<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Typ_danych-2\" >Typ danych<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Obliczanie_wartosci_zwracanej\" >Obliczanie warto\u015bci zwracanej<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Okreslanie_kontekstu_runtime-2\" >Okre\u015blanie kontekstu runtime<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Waznosc_instancji_klasy-2\" >Wa\u017cno\u015b\u0107 instancji klasy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/documentation\/programowanie-wirtualnych-tabel-funkcji-i-kolumn-relacji\/#Rejestracja_wirtualnej_kolumny_zaleznosci\" >Rejestracja wirtualnej kolumny zale\u017cno\u015bci<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h3 id=\"wprowadzenie\" ><span class=\"ez-toc-section\" id=\"Wprowadzenie\"><\/span>Wprowadzenie<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div>W artykule przedstawiono programowanie wirtualnych tabel, wirtualnych funkcji i wirtualnych kolumn zale\u017cno\u015bci od potrzeby tworzonego zapyta\u0144 za po\u015brednictwem interfejsu ODBC.<\/div>\n<div><\/div>\n<h3 id=\"grupa-docelowa\" ><span class=\"ez-toc-section\" id=\"Grupa_docelowa\"><\/span>Grupa docelowa<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>Programi\u015bci<\/li>\n<\/ul>\n<h3 id=\"programowanie-wirtualnych-tabel-i-funkcji\" ><span class=\"ez-toc-section\" id=\"Programowanie_wirtualnych_tabel_i_funkcji\"><\/span>Programowanie wirtualnych tabel i funkcji<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Wirtualna tabela lub funkcja jest implementowana przez oddzieln\u0105 klas\u0119. Musi ona wywodzi\u0107 si\u0119 z klasy com.cisag.pgm.base.CisODBCVirtualTable lub com.cisag.pgm.base.CisODBCVirtualFunction, kt\u00f3re zapewniaj\u0105 podstawow\u0105 funkcjonalno\u015b\u0107. Ich metody abstrakcyjne musz\u0105 zosta\u0107 zaimplementowane przez klas\u0119 pochodn\u0105. Poni\u017cej opisano metody, kt\u00f3re nale\u017cy zaimplementowa\u0107.<\/p>\n<h4 id=\"definiowanie-nazwy-tabeli\" ><span class=\"ez-toc-section\" id=\"Definiowanie_nazwy_tabeli\"><\/span>Definiowanie nazwy tabeli<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Nazwa wirtualnej tabeli lub funkcji jest definiowana przez logiczny typ danych. Jego \u015bcie\u017cka i nazwa okre\u015blaj\u0105 nazw\u0119 tabeli. Metoda getTablePath() musi zwraca\u0107 \u015bcie\u017ck\u0119 systemu logicznego typu danych.<\/p>\n<p>Typ danych logicznych jest dowolny i nie jest oceniany. Dla logicznego typu danych nale\u017cy wprowadzi\u0107 opis danych. Etykieta opisu danych jest u\u017cywana jako opis tabel. Nazwa tabeli wirtualnej pochodzi od nazwy logicznego typu danych.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Metoda getTablePath() wirtualnej tabeli app_general_ItemImage jest zaimplementowana w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<p>public String getTablePath() {<\/p>\n<p>return &#8222;com.cisag.app.general:ItemImage.lt&#8221;;<\/p>\n<p>}<\/div><\/section>\n<p>\u015acie\u017cka wirtualnej tabeli jest skracana przez <em>com.cisag.<\/em>, dla system\u00f3w od partnera tylko przez <em>com.<\/em>. Podkre\u015blenie <em>_<\/em> zast\u0119puje separator <em>.<\/em> .<\/p>\n<p>Logiczny typ danych musi by\u0107 wybrany w taki spos\u00f3b, aby wynikowa nazwa tabeli nie by\u0142a u\u017cywana przez obiekt biznesowy, widok lub inn\u0105 wirtualn\u0105 tabel\u0119 lub funkcj\u0119. Dla lepszej identyfikacji zaleca si\u0119 u\u017cycie w nazwie przyrostka <em>VirtualTable<\/em> lub <em>VirtualFunction<\/em>.<\/p>\n<h5 id=\"rozwiazywanie-konfliktow-nazw\" ><span class=\"ez-toc-section\" id=\"Rozwiazywanie_konfliktow_nazw\"><\/span>Rozwi\u0105zywanie konflikt\u00f3w nazw<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Nazwy tabel obiekt\u00f3w biznesowych oraz tabel i funkcji wirtualnych s\u0105 okre\u015blane na podstawie nazwy obiektu biznesowego lub logicznego typu danych. Je\u015bli dla danej nazwy istnieje kilka tabel, zastosowanie ma nast\u0119puj\u0105ce rozwi\u0105zywanie konflikt\u00f3w:<\/p>\n<ul>\n<li>je\u015bli dla danej nazwy istnieje tabela obiektu biznesowego, w\u00f3wczas u\u017cywana jest ta tabela. Inne tabele o tej samej nazwie s\u0105 ignorowane i nie mo\u017cna uzyska\u0107 do nich dost\u0119pu.<\/li>\n<li>je\u015bli dla nazwy istnieje kilka wirtualnych tabel lub funkcji, u\u017cywana jest pierwsza znaleziona tabela wirtualna. Wszystkie inne tabele s\u0105 ignorowane.<\/li>\n<li>je\u015bli dla danej nazwy istnieje kilka funkcji wirtualnych, u\u017cywana jest pierwsza znaleziona funkcja wirtualna.<\/li>\n<\/ul>\n<div>Ponadto w dzienniku komunikat\u00f3w serwera aplikacji zapisywany jest komunikat o b\u0142\u0119dzie.<\/div>\n<div><\/div>\n<h4 id=\"definiowanie-kolumn-tabeli\" ><span class=\"ez-toc-section\" id=\"Definiowanie_kolumn_tabeli\"><\/span>Definiowanie kolumn tabeli<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Kolumny tabeli s\u0105 definiowane w metodzie getAttributes(). Ka\u017cdy element tablicy definiuje kolumn\u0119 tabeli i jej pozycj\u0119 w tabeli. Element jest ci\u0105giem znak\u00f3w o nast\u0119puj\u0105cej strukturze: <em>Nazwa kolumny\/\u015bcie\u017cka LDT\/typ parametru<\/em>.<\/p>\n<h5 id=\"nazwa-kolumny\" ><span class=\"ez-toc-section\" id=\"Nazwa_kolumny\"><\/span>Nazwa kolumny<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Nazwa kolumny definiuje nazw\u0119 kolumny w tabeli. Nazwa musi by\u0107 unikalna w obr\u0119bie tabeli.<\/p>\n<h5 id=\"typ-danych\" ><span class=\"ez-toc-section\" id=\"Typ_danych\"><\/span>Typ danych<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Logiczny typ danych definiuje typ kolumny i etykiet\u0119 kolumny poprzez powi\u0105zany opis danych. Mo\u017cna u\u017cywa\u0107 wszystkich podstawowych typ\u00f3w danych systemu (bez SBLOB), a tak\u017ce z\u0142o\u017conych logicznych typ\u00f3w danych opartych na nast\u0119puj\u0105cych specjalnych cz\u0119\u015bciach lub specjalnych logicznych typach danych:<\/p>\n<ul>\n<li>com.cisag.app.general.obj.DomesticAmount<\/li>\n<li>com.cisag.app.general.obj.Quantity<\/li>\n<li>com.cisag.app.general.obj.ForeignAmount<\/li>\n<li>com.cisag.app.general.obj.Duration<\/li>\n<li>com.cisag.app.general.obj.PointInTime<\/li>\n<li>com.cisag.pgm.datatype.CisAttributeTimeStamp<\/li>\n<li>com.cisag.pgm.datatype.CisAttributeDate<\/li>\n<\/ul>\n<p>Typ parametru okre\u015bla, czy kolumna tabeli mo\u017ce by\u0107 u\u017cywana jako parametr wej\u015bciowy czy wyj\u015bciowy.<\/p>\n<h5 id=\"parametr-wyjsciowy\" ><span class=\"ez-toc-section\" id=\"Parametr_wyjsciowy\"><\/span>Parametr wyj\u015bciowy<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Je\u015bli kolumna jest parametrem wyj\u015bciowym, zwraca obliczon\u0105 warto\u015b\u0107. Sta\u0142a klasy OUTPUT_PARAM powinna by\u0107 okre\u015blona jako typ parametru w definicji kolumny. Je\u015bli nie okre\u015blono typu parametru, kolumna jest zawsze parametrem wyj\u015bciowym.<\/p>\n<h5 id=\"parametry-wejsciowe\" ><span class=\"ez-toc-section\" id=\"Parametry_wejsciowe\"><\/span>Parametry wej\u015bciowe<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Parametr wej\u015bciowy mo\u017ce by\u0107 u\u017cyty do przekazania warto\u015bci do tabeli wirtualnej, kt\u00f3ra jest u\u017cywana do obliczenia zwracanej zawarto\u015bci tabeli. Nazwa kolumny, kt\u00f3ra mo\u017ce by\u0107 u\u017cyta jako parametr wej\u015bciowy, musi zaczyna\u0107 si\u0119 od przedrostka &#8222;in_&#8221; (sta\u0142a klasy INPUT_PARAM_PREFIX). Parametr wej\u015bciowy mo\u017ce by\u0107 oparty wy\u0142\u0105cznie na podstawowych typach danych systemy. Parametr wej\u015bciowy jest zawsze opcjonalny i nie musi mie\u0107 przypisanej warto\u015bci. Po ustawieniu warto\u015bci nie mo\u017cna jej ju\u017c zmieni\u0107, tzn. warto\u015b\u0107 ta jest zwracana jako warto\u015b\u0107 wyj\u015bciowa dla kolumny.<\/p>\n<p>Je\u015bli kolumna ma by\u0107 u\u017cywana tylko jako parametr wej\u015bciowy, jako typ parametru nale\u017cy okre\u015bli\u0107 sta\u0142\u0105 klasy INPUT_PARAM.<\/p>\n<p>Je\u015bli kolumna ma by\u0107 u\u017cywana jako parametr wej\u015bciowy lub wyj\u015bciowy, jako typ parametru nale\u017cy okre\u015bli\u0107 sta\u0142\u0105 klasy INPUT_OUTPUT_PARAM. Je\u015bli kolumnie przypisano warto\u015b\u0107, nie mo\u017cna jej zmieni\u0107. Je\u015bli nie ustawiono \u017cadnej warto\u015bci, do kolumny mo\u017cna przypisa\u0107 obliczon\u0105 warto\u015b\u0107, kt\u00f3ra jest nast\u0119pnie wyprowadzana.<\/p>\n<div>\n<p><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><span style=\"color: initial;\">Zilustrowana metoda getAttributes() wirtualnej tabeli app_general_ItemImage definiuje kolumny in_itemGuid, description, num-ber i content. Kolumna in_itemGuid jest parametrem wej\u015bciowym, pozosta\u0142e kolumny s\u0105 parametrami wyj\u015bciowymi.<\/span><\/p>\n<p>public String[] getAttributes() {<\/p>\n<p>return new String[] {<\/p>\n<p>&#8222;itemGuid\/com.cisag.app.general:OdbcItemGuid.lt\/&#8221;+<\/p>\n<p>INPUT_PARAM,<\/p>\n<p>&#8222;description\/com.cisag.app.general:OdbcItemDescription.lt\/&#8221;+<\/p>\n<p>OUTPUT_PARAM,<\/p>\n<p>&#8222;number\/com.cisag.app.general:OdbcItemNumber.lt\/&#8221;+<\/p>\n<p>OUTPUT_PARAM,<\/p>\n<p>&#8222;content\/com.cisag.app.general:OdbcItemContent.lt\/&#8221;+<\/p>\n<p>OUTPUT_PARAM<\/p>\n<p>};<\/p>\n<p>}<span style=\"color: initial;\"><\/div><\/section><\/span><\/p>\n<div><\/div>\n<\/div>\n<h4 id=\"definiowanie-typow-baz-danych\" ><span class=\"ez-toc-section\" id=\"Definiowanie_typow_baz_danych\"><\/span>Definiowanie typ\u00f3w baz danych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>W przypadku wirtualnej tabeli lub funkcji typy baz danych, w kt\u00f3rych ma by\u0107 dost\u0119pna, musz\u0105 by\u0107 zdefiniowane w podobny spos\u00f3b, jak w przypadku obiektu biznesowego. Do tego celu s\u0142u\u017cy metoda getDatabaseContentTypes(). Zwraca ona tablic\u0119 z obs\u0142ugiwanymi typami baz danych. Mo\u017cna okre\u015bli\u0107 nast\u0119puj\u0105ce typy baz danych:<\/p>\n<ul>\n<li>OLTP<\/li>\n<li>OLAP<\/li>\n<li>repozytorium<\/li>\n<li>konfiguracyjna<\/li>\n<\/ul>\n<p>Odpowiednie sta\u0142e s\u0105 dostarczane przez klas\u0119 com.cisag.pgm.base.<\/p>\n<p>CisODBCExtensionLogic zapewnia odpowiednie sta\u0142e.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Zilustrowana metoda getDatabaseContentTypes () wirtualnej tabeli app_general_ItemImage okre\u015bla, \u017ce tabela jest dost\u0119pna tylko dla baz danych OLTP.<\/p>\n<p>public short[] getDatabaseContentTypes() {<\/p>\n<p>return new short[] {<\/p>\n<p>CisODBCExtensionLogic.DB_CONTENT_TYPE_OLTP<\/p>\n<p>};<\/p>\n<p>}<\/div><\/section>\n<h4 id=\"definiowanie-uprawnien\" ><span class=\"ez-toc-section\" id=\"Definiowanie_uprawnien\"><\/span>Definiowanie uprawnie\u0144<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Aby ograniczy\u0107 dost\u0119p do wirtualnej tabeli lub funkcji, mo\u017cna przypisa\u0107 autoryzacj\u0119. Odbywa si\u0119 to za pomoc\u0105 metody getBaseBusi-nessObjectGuid(), kt\u00f3ra zwraca Class-Guid bazowego obiektu biznesowego. Autoryzacje dla bazowego obiektu biznesowego s\u0105 pobierane z wirtualnej tabeli lub funkcji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Zilustrowana metoda getBaseBusinessObjectGuid() tabeli wirtualnej app_general_ItemImage zwraca Class-Guid obiektu biznesowego com.cisag.app.general.obj.Item. Oznacza to, \u017ce autoryzacje wa\u017cne dla tego obiektu biznesowego w momencie zapytania s\u0105 r\u00f3wnie\u017c stosowane do tabeli wirtualnej.<\/p>\n<p>public byte[] getBaseBusinessObjectGuid() {<\/p>\n<p>return CisObjectUtility.getClassGuid(<\/p>\n<p>com.cisag.app.general.obj.Item.class);<\/p>\n<p>}<\/div><\/section>\n<h4 id=\"waznosc-instancji-klasy\" ><span class=\"ez-toc-section\" id=\"Waznosc_instancji_klasy\"><\/span>Wa\u017cno\u015b\u0107 instancji klasy<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Instancja powi\u0105zanej klasy jest tworzona dla ka\u017cdego zapytania SQL, w kt\u00f3rym u\u017cywana jest wirtualna tabela lub funkcja. Czas \u017cycia instancji jest powi\u0105zany z czasem \u017cycia zapytania SQL. Oznacza to, \u017ce zawarto\u015b\u0107 zmiennych instancji nie jest zachowywana mi\u0119dzy zapytaniami, ale jest dost\u0119pna tylko do momentu pe\u0142nego obliczenia wyniku zapytania dla wirtualnej tabeli lub funkcji.<\/p>\n<h5 id=\"inicjalizacja-zmiennych-instancji\" ><span class=\"ez-toc-section\" id=\"Inicjalizacja_zmiennych_instancji\"><\/span>Inicjalizacja zmiennych instancji<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Wirtualna tabela lub funkcja mo\u017ce posiada\u0107 zmienne instancji. Zmienne instancji nie mog\u0105 by\u0107 jednak inicjowane w konstruktorze klasy. W tym celu nale\u017cy zaimplementowa\u0107 metod\u0119 init(), kt\u00f3ra jest wykonywana przed pierwszym wywo\u0142aniem metody run(). W tej metodzie mo\u017cna zainicjowa\u0107 wszystkie zmienne instancji, poniewa\u017c w tym momencie ustawiana jest odpowiednia sesja i kontekst OLTP.<\/p>\n<h3 id=\"obliczanie-wyniku-tabeli\" ><span class=\"ez-toc-section\" id=\"Obliczanie_wyniku_tabeli\"><\/span>Obliczanie wyniku tabeli<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Zawarto\u015b\u0107 tabeli wirtualnej lub funkcji wirtualnej jest obliczana w czasie wykonywania zapytania ODBC. W tym celu system wywo\u0142uje metod\u0119 run(), w kt\u00f3rej nale\u017cy zapisa\u0107 implementacj\u0119 oblicze\u0144.<\/p>\n<h5 id=\"tabela-wirtualna\" ><span class=\"ez-toc-section\" id=\"Tabela_wirtualna\"><\/span>Tabela wirtualna<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Tabela wirtualna ma typ wykonania, kt\u00f3ry okre\u015bla spos\u00f3b wywo\u0142ywania metody run() przez system. Deweloper musi zdecydowa\u0107 o typie wykonania podczas implementacji tabeli wirtualnej.<\/p>\n<h6 id=\"wykonanie-jednorazowe\" ><span class=\"ez-toc-section\" id=\"Wykonanie_jednorazowe\"><\/span>Wykonanie jednorazowe<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Jest to standardowy typ wykonania. Metoda run() tabeli wirtualnej jest wywo\u0142ywana dok\u0142adnie raz na zapytanie do bazy danych w celu okre\u015blenia zawarto\u015bci tabeli. Wynik jest przechowywany w ca\u0142o\u015bci w pami\u0119ci g\u0142\u00f3wnej, wi\u0119c ten typ wykonania mo\u017ce by\u0107 u\u017cywany tylko wtedy, gdy wynik do obliczenia b\u0119dzie stosunkowo ma\u0142y.<\/p>\n<h6 id=\"wykonanie-w-blokach\" ><span class=\"ez-toc-section\" id=\"Wykonanie_w_blokach\"><\/span>Wykonanie w blokach<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Klasa implementuj\u0105ca musi nadpisa\u0107 metod\u0119 getExecutionType() i zwr\u00f3ci\u0107 sta\u0142\u0105 CisODBCVirtualTable.TYPE_EXECUTION_BLOCK. Metoda run() tabeli wirtualnej mo\u017ce by\u0107 wywo\u0142ywana wielokrotnie dla ka\u017cdego zapytania bazy danych w celu okre\u015blenia zawarto\u015bci tabeli. Ka\u017cde wywo\u0142anie zwraca blok wierszy wynikowych. Ten typ wykonania musi by\u0107 u\u017cywany, je\u015bli wynik do obliczenia mo\u017ce by\u0107 bardzo du\u017cy i dlatego zajmowa\u0142by zbyt du\u017co pami\u0119ci g\u0142\u00f3wnej.<\/p>\n<h6 id=\"wykonanie-metody-run\" ><span class=\"ez-toc-section\" id=\"Wykonanie_metody_run\"><\/span>Wykonanie metody run()<span class=\"ez-toc-section-end\"><\/span><\/h6>\n<p>Po wywo\u0142aniu metody run() tabela wirtualna otrzymuje obiekt CisODBCVir-tualTableResult, kt\u00f3ry zawiera warto\u015bci parametr\u00f3w wej\u015bciowych i wiersze obliczonego wyniku. Mo\u017ce on zawiera\u0107 od 0 do n wierszy wynik\u00f3w i jest przekazywany do obiektu wyniku tabeli wiersz po wierszu.<\/p>\n<p>Nowy obiekt wiersza wyniku klasy CisODBCVirtualTableRow jest tworzony za pomoc\u0105 metody createRow() obiektu wyniku tabeli. Obiekt ten jest kontenerem warto\u015bci kolumn wiersza tabeli. Warto\u015bci okre\u015blone w zapytaniu dla u\u017cytych parametr\u00f3w wej\u015bciowych s\u0105 zawsze ustawiane w tym obiekcie. Metoda set() lub get() odpowiadaj\u0105ca typowi kolumny mo\u017ce by\u0107 u\u017cyta do zapytania lub ustawienia warto\u015bci poprzez okre\u015blenie nazwy kolumny. Warto\u015b\u0107 u\u017cywanego parametru wej\u015bciowego nie mo\u017ce ju\u017c zosta\u0107 zmieniona. Metoda isParameterLocked() obiektu CisODBCVirtu-alTableResult mo\u017ce by\u0107 u\u017cyta do zapytania, czy okre\u015blony parametr wej\u015bciowy jest zablokowany, tj. czy zosta\u0142a mu przypisana warto\u015b\u0107 i czy nie mo\u017cna go zmieni\u0107.<\/p>\n<p>Je\u015bli obiekt wiersza wyniku jest wype\u0142niony, jest on dodawany do wyniku za pomoc\u0105 metody addRow() obiektu wyniku tabeli. Alternatywnie mo\u017cna r\u00f3wnie\u017c doda\u0107 kilka obiekt\u00f3w wierszy wynik\u00f3w do wyniku za pomoc\u0105 metody addAllRows() zamiast kilku wywo\u0142a\u0144 addRow().<\/p>\n<p>Wiersz wyniku jest uwzgl\u0119dniany w wyniku tylko wtedy, gdy zosta\u0142 dodany do wyniku za pomoc\u0105 jednej z tych metod.<\/p>\n<div><strong>Specjalne cechy wykonywania blokowego<\/strong><\/div>\n<div><\/div>\n<p>Po okre\u015bleniu wszystkich wierszy wynik\u00f3w nale\u017cy wywo\u0142a\u0107 metod\u0119 setAll-RowsLoaded() na obiekcie wyniku tabeli. Informuje ona system, \u017ce obliczanie wyniku tabeli zosta\u0142o zako\u0144czone. Metoda run() nie jest ju\u017c wtedy wywo\u0142ywana. Je\u015bli obiekt wyniku tabeli zostanie zwr\u00f3cony z 0 wierszami wynikowymi, metoda run() r\u00f3wnie\u017c nie zostanie ponownie wywo\u0142ana.<\/p>\n<p>Metoda getFetchSize() na obiekcie wyniku tabeli mo\u017ce by\u0107 u\u017cyta do zapytania o liczb\u0119 wierszy w bloku wynik\u00f3w wymaganych przez system dla bie\u017c\u0105cego wywo\u0142ania metody run(). Je\u015bli ten rozmiar jest przestrzegany, wynik jest przesy\u0142any z serwera do klienta przy minimalnej wymaganej liczbie po\u0142\u0105cze\u0144 w obie strony. Rzeczywista liczba wierszy w bloku mo\u017ce jednak odbiega\u0107 od po\u017c\u0105danej warto\u015bci, a zatem mo\u017ce wymaga\u0107 wi\u0119kszej liczby podr\u00f3\u017cy w obie strony.<\/p>\n<p><strong>Sortowanie wierszy tabeli<\/strong><\/p>\n<p>Kolejno\u015b\u0107 dodawania odpowiada wyj\u015bciowej kolejno\u015bci wierszy tabeli. Je\u015bli sortowanie zosta\u0142o zdefiniowane w instrukcji bazy danych SQL za pomoc\u0105 klauzuli ORDER-BY, system zwraca wiersze wynik\u00f3w dla tabeli typu <em>pojedyncze wykonanie<\/em> zgodnie z sortowaniem.<\/p>\n<p>W przypadku tabeli typu <em>wykonanie blokowe<\/em> za sortowanie odpowiada tw\u00f3rca tabeli wirtualnej. Zwykle taka tabela obs\u0142uguje tylko sortowanie sta\u0142e, kt\u00f3re jest okre\u015blane przez kolejno\u015b\u0107 dodawania wierszy wynik\u00f3w. Je\u015bli ma by\u0107 obs\u0142ugiwane sortowanie zmienne, sortowanie okre\u015blone w instrukcji bazy danych SQL mo\u017cna sprawdzi\u0107 za pomoc\u0105 metod getSortOrder() i getSort-Directions(). W dokumentacji tabeli wirtualnej deweloper powinien okre\u015bli\u0107, w jaki spos\u00f3b tabela sortuje wyniki i czy obs\u0142ugiwane s\u0105 r\u00f3\u017cne porz\u0105dki sortowania.<\/p>\n<div>\n<p><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><span style=\"color: initial;\">Okre\u015blanie warto\u015bci parametr\u00f3w wej\u015bciowych.<\/span><\/p>\n<p>W tym przyk\u0142adzie tworzony jest obiekt wiersza wynik\u00f3w, w kt\u00f3rym sprawdzana jest warto\u015b\u0107 parametru wej\u015bciowego dla kolumny in_itemGuid. Je\u015bli nie zostanie ustawiona \u017cadna warto\u015b\u0107, nie b\u0119dzie mo\u017cna obliczy\u0107 \u017cadnego wyniku, a tabela wirtualna nie zwr\u00f3ci \u017cadnych wierszy wynikowych.<\/p>\n<p>public void run(CisODBCVirtualTableResult result) {<\/p>\n<p>CisODBCVirtualTableRow resultRow= result.createRow();<\/p>\n<p>byte[] itemGuid= resultRow.getGuid(&#8222;in_itemGuid&#8221;);<\/p>\n<p>if (itemGuid == null) {<\/p>\n<p>return;<\/p>\n<p>}<\/p>\n<div><\/div>\n<div>\u00a0 \/\/ pobieranie wierszy wynik\u00f3w tabeli<\/div>\n<div>\u00a0 &#8230;<\/div>\n<div>}<span style=\"color: initial;\"><\/div><\/section><\/span><\/div>\n<\/div>\n<div><\/div>\n<div><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><span style=\"color: initial;\">Dodawanie wiersza do obiektu wynik\u00f3w<\/span><\/p>\n<div>Je\u015bli jako parametr wej\u015bciowy okre\u015blono Item-Guid, \u0142adowana jest odpowiednia instancja Item. Je\u015bli zosta\u0142a ona znaleziona, warto\u015bci kolumn wyj\u015bciowych s\u0105 ustawiane w obiekcie wiersza resultRow. Jest on nast\u0119pnie dodawany do wyniku. W tym przyk\u0142adzie tabela wirtualna zwraca wiersz wynikowy dla Item-Guid.<\/div>\n<div>public void run(CisODBCVirtualTableResult result) {<\/div>\n<div>\u00a0 &#8230;<\/div>\n<div><\/div>\n<div>\u00a0 \/\/ pobierz wiersze wynik\u00f3w tabeli<\/div>\n<div>\u00a0 Item item= (Item) om.getObject(Item.buildPrimaryKey(itemGuid));<\/div>\n<div>\u00a0 if (item == null) {<\/div>\n<div>\u00a0 \u00a0 return;<\/div>\n<div>\u00a0 }<\/div>\n<div>\u00a0 resultRow.setString(NUMBER, item.getNumber());<\/div>\n<div>\u00a0 resultRow.setString(DESCRIPTION, item.getDescription());<\/div>\n<div>\u00a0 &#8230;<\/div>\n<div><\/div>\n<div>\u00a0 result.addRow(resultRow);<\/div>\n<div>}<span style=\"color: initial;\"><\/div><\/section><\/span><\/div>\n<\/div>\n<div><\/div>\n<h5 id=\"funkcja-wirtualna\" ><span class=\"ez-toc-section\" id=\"Funkcja_wirtualna\"><\/span>Funkcja wirtualna<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p><span style=\"color: initial;\">Metoda run() funkcji wirtualnej jest wywo\u0142ywana blok po bloku. Przekazany obiekt CisODBCVirtualFunctionResult zawiera wiersze wynikowe bie\u017c\u0105cego bloku do wype\u0142nienia, w kt\u00f3rych ustawiane s\u0105 odpowiednie warto\u015bci parametr\u00f3w wej\u015bciowych. Warto\u015b\u0107 parametru wej\u015bciowego wiersza jest okre\u015blana przez ocen\u0119 klauzuli JOIN powi\u0105zanego JOIN. Okre\u015bla ona kolumn\u0119 partnera \u0142\u0105czenia, z kt\u00f3rej parametr wej\u015bciowy funkcji wirtualnej uzyskuje swoj\u0105 warto\u015b\u0107. Wiersze wynikowe partnera po\u0142\u0105czenia zosta\u0142y wcze\u015bniej obliczone w bazie danych. W metodzie run() warto\u015bci palet wyj\u015bciowych tabeli wirtualnej musz\u0105 teraz zosta\u0107 obliczone dla ka\u017cdego wiersza wynikowego i przypisane do wiersza wynikowego. Wywo\u0142anie jest zatem wykonywane blokowo, aby umo\u017cliwi\u0107 wydajn\u0105 implementacj\u0119. Wywo\u0142anie mo\u017ce by\u0107 wykonane kilka razy w zale\u017cno\u015bci od liczby blok\u00f3w.<\/span><\/p>\n<p>Ka\u017cda funkcja wirtualna u\u017cywa jednej pami\u0119ci podr\u0119cznej na zapytanie, kt\u00f3ra zawiera wiersze wynik\u00f3w. Je\u015bli wiersz wyniku ju\u017c istnieje w pami\u0119ci podr\u0119cznej dla kombinacji warto\u015bci parametr\u00f3w wej\u015bciowych, wiersz wyniku nie jest obliczany ponownie, ale zwracana jest zawarto\u015b\u0107 pami\u0119ci podr\u0119cznej. Dlatego wa\u017cne jest, aby wiersz wyniku w zapytaniu zale\u017ca\u0142 tylko od warto\u015bci parametr\u00f3w wej\u015bciowych, a nie od poprzednich wierszy wynik\u00f3w.<\/p>\n<p>Wiersz wynikowy jest reprezentowany przez obiekt CisODBCVirtualFunctionRow. Metoda set() lub get() odpowiadaj\u0105ca typowi kolumny mo\u017ce by\u0107 u\u017cyta do zapytania lub ustawienia warto\u015bci poprzez okre\u015blenie nazwy kolumny. Nie mo\u017cna ju\u017c zmieni\u0107 warto\u015bci przypisanego parametru wej\u015bciowego. Metoda isParameterLocked() obiektu CisODBCVirtualFunctionResult mo\u017ce by\u0107 u\u017cyta do zapytania, czy okre\u015blony parametr wej\u015bciowy jest zablokowany, tj. czy zosta\u0142a mu przypisana warto\u015b\u0107 i czy nie mo\u017cna jej zmieni\u0107.<\/p>\n<p>Metoda getRowCount() obiektu CisODBCVirtualFunctionResult zwraca liczb\u0119 wierszy wynikowych do przetworzenia, metoda getRow() zwraca obiekt CisODBCVirtualFunctionRow dla okre\u015blonego wiersza wynikowego. Warto\u015bci parametr\u00f3w wej\u015bciowych mog\u0105 by\u0107 nast\u0119pnie odpytywane, a warto\u015bci kolumn wyj\u015bciowych obliczane i umieszczane w obiekcie wiersza wynikowego.<\/p>\n<p><span style=\"font-size: revert; color: initial;\"><section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\"><\/span><span style=\"font-size: revert; color: initial;\">W tym przyk\u0142adzie p\u0119tla jest u\u017cywana do iteracji po wierszach wynik\u00f3w i obliczania kolumn wyj\u015bciowych w ka\u017cdym przypadku.<\/span><\/p>\n<div>\n<p>Parametry wej\u015bciowe &#8222;in_organizationalUnit&#8221; i &#8222;in_item&#8221; s\u0105 obowi\u0105zkowe dla oblicze\u0144. Je\u015bli \u017cadne warto\u015bci nie s\u0105 ustawione, nie mo\u017cna obliczy\u0107 \u017cadnych warto\u015bci dla tego wiersza wynik\u00f3w, a proces jest kontynuowany od nast\u0119pnego wiersza wynik\u00f3w. Parametr wej\u015bciowy &#8222;in_customer&#8221; jest opcjonalny i nie musi by\u0107 ustawiony. Nast\u0119pnie okre\u015blane s\u0105 warto\u015bci dla kolumn wyj\u015bciowych, kt\u00f3re s\u0105 ustawiane w obiekcie wiersza wynik\u00f3w za pomoc\u0105 metod set() odpowiadaj\u0105cych danemu typowi.<\/p>\n<p>public void run(CisODBCVirtualFunctionResult virtualFunctionResult) {<\/p>\n<p>for(int i= 0,s= virtualFunctionResult.getRowCount(); i&lt;s; i++) {<\/p>\n<p>CisODBCVirtualFunctionRow row= virtualFunctionResult.getRow(i);<\/p>\n<p>byte[] organisation= row.getGuid(&#8222;in_organizationalUnit&#8221;);<\/p>\n<p>if (organisation == null) continue;<\/p>\n<p>byte[] item= row.getGuid(&#8222;in_item&#8221;);<\/p>\n<p>if (item == null) continue;<\/p>\n<p>byte[] customer= row.getGuid(&#8222;in_customer&#8221;);<\/p>\n<p>\/\/ obliczenie warto\u015bci dla kolumn wyj\u015bciowych<\/p>\n<p>SalesItemData data= Items.retrieveSalesItemData(<\/p>\n<p>organisation, item, customer);<\/p>\n<p>if (data == null) continue;<\/p>\n<p>&#8230;<\/p>\n<p>\/\/ ustawienie warto\u015bci kolumn wyj\u015bciowych w wierszu wynik\u00f3w<\/p>\n<p>row.setGuid(&#8222;text&#8221;, data.getText());<\/p>\n<p>row.setDecimal(&#8222;minMargin&#8221;, data.getMinMargin());<\/p>\n<p>&#8230;<\/p>\n<p>}<\/p>\n<p>}<span style=\"color: initial;\"><\/div><\/section><\/span><\/p>\n<h5 id=\"okreslanie-kontekstu-runtime\" ><span class=\"ez-toc-section\" id=\"Okreslanie_kontekstu_runtime\"><\/span>Okre\u015blanie kontekstu runtime<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Metoda getODBCContext() mo\u017ce by\u0107 u\u017cyta do zapytania o kontekst runtime podczas wykonywania metody run(). Guid aktywnej organizacji, w kt\u00f3rej kontek\u015bcie wykonywany jest raport, mo\u017cna okre\u015bli\u0107 na obiekcie kontekstu za pomoc\u0105 metody getOrganisationGuid(). Metoda isMultiSite() mo\u017ce by\u0107 u\u017cyta do okre\u015blenia, czy aktywna baza danych OLTP dzia\u0142a w \u015brodowisku wielostanowiskowym. Metoda getDatabaseGuid() zwraca identyfikator bazy danych, do kt\u00f3rej odbywa si\u0119 bie\u017c\u0105cy dost\u0119p ODBC.<\/p>\n<h4 id=\"rejestracja-wirtualnych-tabel-lub-funkcji\" ><span class=\"ez-toc-section\" id=\"Rejestracja_wirtualnych_tabel_lub_funkcji\"><\/span>Rejestracja wirtualnych tabel lub funkcji<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Aby wirtualna tabela lub funkcja by\u0142a dost\u0119pna przez ODBC, powi\u0105zana klasa musi zosta\u0107 zarejestrowana. Do tego celu s\u0142u\u017cy hook: <em>com.cisag.pgm.appserver.hook.ODBCRegistryHook<\/em>, kt\u00f3ry jest zdefiniowany w Hook Contract:<em> com.cisag.pgm.appserver.Server<\/em>. Mo\u017cna u\u017cy\u0107 w\u0142asnej implementacji tego hook&#8217;a, aby zarejestrowa\u0107 wirtualne tabele lub funkcje bez konflikt\u00f3w.<\/p>\n<h4 id=\"automatyczna-konwersja-zawartosci-kolumny-typu-danych-text\" ><span class=\"ez-toc-section\" id=\"Automatyczna_konwersja_zawartosci_kolumny_typu_danych_Text\"><\/span>Automatyczna konwersja zawarto\u015bci kolumny typu danych <em>Text<\/em><span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>W przypadku kolumny podstawowego typu danych <em>Text<\/em> mo\u017cliwa jest automatyczna konwersja zawarto\u015bci przez serwer ODBC. Jest to obecnie obs\u0142ugiwane tylko w przypadku danych wyj\u015bciowych tekst\u00f3w HTML. Mog\u0105 one zawiera\u0107 znaczniki HTML, kt\u00f3re nie s\u0105 obs\u0142ugiwane przez aplikacj\u0119 klienck\u0105 ODBC (np. Crystal Reports) i dlatego tekst nie jest wy\u015bwietlany zgodnie z oczekiwaniami (np. brak pogrubienia lub kursywy). Aby aktywowa\u0107 automatyczn\u0105 konwersj\u0119 dla kolumny typu <em>Text<\/em> wirtualnej tabeli\/funkcji, nale\u017cy j\u0105 zarejestrowa\u0107. Do tego celu s\u0142u\u017cy hook <em>com.cisag.pgm.appserver.hook.ODBCRegistryHook<\/em>, kt\u00f3ry jest zdefiniowany w Hook Contract: <em>com.cisag.pgm.appserver.Server<\/em>. Mo\u017cna u\u017cy\u0107 w\u0142asnej implementacji tego hook&#8217;a, aby zarejestrowa\u0107 kolumn\u0119 typu danych <em>Text<\/em> bez konfliktu.<\/p>\n<p>Ze wzgl\u0119d\u00f3w wydajno\u015bciowych automatyczna konwersja powinna by\u0107 stosowana tylko w przypadku problem\u00f3w z wy\u015bwietlaniem tekst\u00f3w HTML w aplikacji klienckiej ODBC.<\/p>\n<h3 id=\"programowanie-wirtualnych-kolumn-relacji\" ><span class=\"ez-toc-section\" id=\"Programowanie_wirtualnych_kolumn_relacji\"><\/span>Programowanie wirtualnych kolumn relacji<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Istnieje mo\u017cliwo\u015b\u0107 dodania kolumny wirtualnej do tabeli obiektu biznesowego, kt\u00f3rej zawarto\u015b\u0107 jest obliczana w czasie wykonywania zapytania. Taka wirtualna kolumna jest oparta na relacji mi\u0119dzy obiektem biznesowym a okre\u015blonym obiektem biznesowym.<\/p>\n<p>Dla wirtualnej kolumny relacji musi zosta\u0107 zaimplementowana oddzielna klasa. Musi ona wywodzi\u0107 si\u0119 z klasy com.cisag.pgm.base.CisODBCVirtualColumn, kt\u00f3ra zapewnia podstawow\u0105 funkcjonalno\u015b\u0107. Jej metody abstrakcyjne musz\u0105 zosta\u0107 zaimplementowane przez klas\u0119 pochodn\u0105.<\/p>\n<h4 id=\"nazwa-kolumny\" ><span class=\"ez-toc-section\" id=\"Nazwa_kolumny-2\"><\/span>Nazwa kolumny<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Nazwa kolumny sk\u0142ada si\u0119 z nazwy atrybutu \u017ar\u00f3d\u0142owego relacji i sufiksu po\u0142\u0105czonego z podkre\u015bleniem.<\/p>\n<h4 id=\"typ-danych\" ><span class=\"ez-toc-section\" id=\"Typ_danych-2\"><\/span>Typ danych<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Typ danych kolumny wirtualnej jest definiowany poprzez logiczny typ danych. Dozwolone s\u0105 wszystkie podstawowe typy danych systemu (z wyj\u0105tkiem BLOB, SBLOB, tekstu). Etykieta opisu danych powi\u0105zanego z logicznym typem danych okre\u015bla etykiet\u0119 kolumny.<\/p>\n<h4 id=\"obliczanie-wartosci-zwracanej\" ><span class=\"ez-toc-section\" id=\"Obliczanie_wartosci_zwracanej\"><\/span>Obliczanie warto\u015bci zwracanej<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Metoda getValueByKey() jest wywo\u0142ywana w celu obliczenia warto\u015bci kolumny relacji wirtualnej dla ka\u017cdego wiersza wynikowego tabeli obiektu biznesowego. Klucz us\u0142ugi trwa\u0142o\u015bci, kt\u00f3ry jest u\u017cywany do \u0142adowania docelowej instancji obiektu biznesowego, oraz j\u0119zyk bazy danych s\u0105 przesy\u0142ane. Klucz us\u0142ugi trwa\u0142o\u015bci mo\u017ce by\u0107 nast\u0119pnie u\u017cyty do za\u0142adowania instancji obiektu biznesowego, bior\u0105c pod uwag\u0119 j\u0119zyk bazy danych, a warto\u015b\u0107 zwracana mo\u017ce zosta\u0107 okre\u015blona. Podstawowe typy Java musz\u0105 zosta\u0107 zwr\u00f3cone jako obiekt.<\/p>\n<p>Metoda ta jest wywo\u0142ywana dla ka\u017cdego wiersza wynikowego \u017ar\u00f3d\u0142owej tabeli obiekt\u00f3w biznesowych.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Kod \u017ar\u00f3d\u0142owy pokazuje implementacj\u0119 wirtualnej kolumny relacji dla obiektu biznesowego com.cisag.app.general.obj.UnitOfMeasure. Konstruktor klasy nadrz\u0119dnej jest wywo\u0142ywany w konstruktorze, a sufiks nazwy kolumny i \u015bcie\u017cka logicznego typu danych s\u0105 przekazywane.<\/p>\n<p>W metodzie getValueByKey() instancja UnitOfMeasure jest \u0142adowana dla przekazanego klucza us\u0142ugi trwa\u0142o\u015bci, a warto\u015b\u0107 kodu atrybutu jest zwracana jako wynik.<\/p>\n<p>public static class UnitOfMeasureBK extends CisODBCVirtualColumn {<\/p>\n<p>private CisEnvironment env= CisEnvironment.getInstance();<\/p>\n<p>private CisTransactionManager tm= env.getTransactionManager();<\/p>\n<p>private CisObjectManager om= env.getObjectManager();<\/p>\n<p>public UnitOfMeasureBK() {<\/p>\n<p>super(&#8222;BK&#8221;, &#8222;com.cisag.app.general:UomCode.lt&#8221;);<\/p>\n<p>}<\/p>\n<p>public Object getValueByKey(byte[] key, String language) {<\/p>\n<p>byte[] ta = tm.beginNew(CisTransactionManager.OLTP);<\/p>\n<p>try {<\/p>\n<p>UnitOfMeasure uom= (UnitOfMeasure) om.getObject(key,<\/p>\n<p>CisObjectManager.READ, language);<\/p>\n<p>return uom != null ? uom.getCode() : null;<\/p>\n<p>} finally {<\/p>\n<p>tm.rollback(ta);<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>}<\/div><\/section>\n<div><\/div>\n<h5 id=\"okreslanie-kontekstu-runtime\" ><span class=\"ez-toc-section\" id=\"Okreslanie_kontekstu_runtime-2\"><\/span>Okre\u015blanie kontekstu runtime<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Metoda getODBCContext() mo\u017ce by\u0107 u\u017cyta do zapytania o kontekst runtime podczas wykonywania metody run(). Guid aktywnej organizacji, w kt\u00f3rej kontek\u015bcie wykonywany jest raport, mo\u017cna okre\u015bli\u0107 na obiekcie kontekstu za pomoc\u0105 metody getOrganisationGuid(). Metoda isMultiSite() mo\u017ce by\u0107 u\u017cyta do okre\u015blenia, czy aktywna baza danych OLTP dzia\u0142a w \u015brodowisku wielostanowiskowym. Metoda getDatabaseGuid() zwraca identyfikator bazy danych, do kt\u00f3rej odbywa si\u0119 bie\u017c\u0105cy dost\u0119p ODBC.<\/p>\n<h5 id=\"waznosc-instancji-klasy\" ><span class=\"ez-toc-section\" id=\"Waznosc_instancji_klasy-2\"><\/span>Wa\u017cno\u015b\u0107 instancji klasy<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Dla ka\u017cdego zapytania SQL, w kt\u00f3rym u\u017cywana jest wirtualna kolumna relacji, tworzona jest jedna lub wi\u0119cej instancji powi\u0105zanej klasy, przy czym ustawiana jest odpowiednia sesja i kontekst OLTP. Czas \u017cycia instancji jest powi\u0105zany z podr\u00f3\u017c\u0105 w obie strony ODBC. Oznacza to, \u017ce zawarto\u015b\u0107 zmiennych instancji nie jest zachowywana, a zatem \u017caden stan nie mo\u017ce zosta\u0107 zapami\u0119tany.<\/p>\n<h5 id=\"rejestracja-wirtualnej-kolumny-zaleznosci\" ><span class=\"ez-toc-section\" id=\"Rejestracja_wirtualnej_kolumny_zaleznosci\"><\/span>Rejestracja wirtualnej kolumny zale\u017cno\u015bci<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<p>Aby wirtualna kolumna relacji by\u0142a dost\u0119pna za po\u015brednictwem ODBC, nale\u017cy zarejestrowa\u0107 powi\u0105zan\u0105 z ni\u0105 klas\u0119. Do tego celu s\u0142u\u017cy metoda getVirtualRelati-onshipColumns() klasy com.cisag.app.general.log.CisODBCExtensionLogicImpl. Metoda ta jest wywo\u0142ywana przez SAS podczas inicjalizacji interfejsu ODBC. Jako parametr otrzymuje w pe\u0142ni kwalifikowan\u0105 nazw\u0119 obiektu biznesowego. Dodanie konstrukcji else-if do instrukcji if powoduje dodanie nowej kolumny relacji dla obiektu biznesowego. Je\u015bli nazwa okre\u015blonego obiektu biznesowego jest zgodna z nazw\u0105 przekazanego obiektu biznesowego, metoda zwraca tablic\u0119 z klasami wirtualnych kolumn relacji.<\/p>\n<section class=\"document-alert-box example\"><div class=\"document-alert-title\">Przyk\u0142ad<\/div><div class=\"document-alert-content\">Przyk\u0142ad prezentuje rejestracj\u0119 wirtualnej kolumny relacji dla obiektu biznesowego &#8222;com.cisag.app.general.obj.UnitOfMeasure&#8221; i dw\u00f3ch kolumn relacji dla obiektu biznesowego &#8222;com.cisag.app.shipping.obj.UnitLoad&#8221;.<\/p>\n<p>public Class[] getVirtualRelationshipColumns(String fullBoName) {<\/p>\n<p>if (&#8222;com.cisag.app.general.obj.UnitOfMeasure&#8221;.equals(fullBoName))<\/p>\n<p>{<\/p>\n<p>return new Class[]{UnitOfMeasureBK.class};<\/p>\n<p>}<\/p>\n<p>&#8230;<\/p>\n<p>} else<\/p>\n<p>if (&#8222;com.cisag.app.shipping.obj.UnitLoad&#8221;.equals(fullBoName)) {<\/p>\n<p>return new Class[] {UnitLoadPath.class,<\/p>\n<p>UnitLoadSsccPath.class};<\/p>\n<p>}<\/p>\n<p>return null;<\/p>\n<p>}<\/div><\/section>\n<\/div>\n","protected":false},"author":28,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"class_list":["post-9671","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-interfejsy-techniczne"],"_links":{"self":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb"}],"about":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/comments?post=9671"}],"version-history":[{"count":8,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9671\/revisions"}],"predecessor-version":[{"id":15420,"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/ht_kb\/9671\/revisions\/15420"}],"wp:attachment":[{"href":"https:\/\/pomoc.comarch.pl\/cee\/640\/index.php\/wp-json\/wp\/v2\/media?parent=9671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}