Új hozzászólás Aktív témák
-
DS39
nagyúr
válasz kw3v865 #3394 üzenetére
Szia!
Ezt úgy lehet megoldani, hogy megnézed mi lenne insertálva:
INSTEAD OF INSERT
AS
BEGININSERT INTO TABLANEV (oszlopnevek....)
SELECT oszlopnevek...
FROM INSERTED IEND
--------
itt a SELECT-en belül használhatsz CASE WHEN-eket, hogy adott oszlop értéke ha ez, akkor legyen helyette amaz. remélem érted[ Szerkesztve ]
-
DS39
nagyúr
válasz kw3v865 #3399 üzenetére
túlbonyolítod, de itt:
@ID=(SELECT OBJECTID FROM INSERTED)
minek a kurzor, ha itt benne hagyod azt a belső selected ami több sort fog visszahozni.
miért nem csinálod úgy ahogy írtam az elején?
ALTER TRIGGER nepesseg_szum ON OVEZETEK
INSTEAD OF INSERT
AS
BEGIN--és a triggeren belül insertálod
INSERT INTO OVEZETEK (oszlopnevek....)
SELECT oszlop1, oszlop2,
(SELECT SUM (TELEPULES.LAKOSOK) FROM TELEPULES
WHERE TELEPULES.SHAPE.STWithin(I.SHAPE)=1),
oszlop4, oszlop5 ....
FROM INSERTED IEND
--(kb ennyi, csak egészítsd ki a tényleges oszlopnevekkel a selectben, és az insert into sorban)ne after insert után update-elj, hanem eleve ne engedd addig az insertet a táblába míg át nem alakítod úgy az eredményt, ahogy neked megfelelő.
így szerintem nem kapnál eleve ilyen hibaüzenetet, hiszen az inserted táblában soronként egy SHAPE érték lesz, ezért a SUM is csak egy értéket ad vissza.
[ Szerkesztve ]
-
-
kw3v865
senior tag
válasz kw3v865 #3403 üzenetére
Egyébként én valószínűnek tartom, hogy a PK (OBJECTID) okozhat gondokat, mert amíg csak UPDATE-elem, nincs gond, mindig növekszik szépen eggyel.
http://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/object-id.htmKicsit összekavarodnak a dolgok, amikor nem az ArcGIS adja az értéket az ObjectID-nak, viszont enélkül sem megy, mert ez a PK (és muszáj, hogy legyen egy PK).
-
DS39
nagyúr
válasz kw3v865 #3404 üzenetére
értem, akkor javítsuk meg az update-es megoldásodat:
(itt ugye csak a subquery-vel volt gond, azt én így orvosolnám)ALTER TRIGGER nepesseg_szum ON OVEZETEK
AFTER INSERT
AS
BEGINDECLARE @TERULET GEOMETRY
DECLARE @ID INTDECLARE @kurzor CURSOR
SET @kurzor = cursor FOR
SELECT SHAPE, OBJECTID FROM INSERTEDOPEN @kurzor
FETCH NEXT FROM @kurzor INTO @TERULET, @IDWHILE @@FETCH_STATUS = 0
BEGINUPDATE OVEZETEK
SET Nepesseg_ossz = (SELECT SUM(n.lakosok) from NEPESSEG_EOV N WHERE N.SHAPE.STWithin(@TERULET)=1)
WHERE OVEZETEK.OBJECTID=@IDFETCH NEXT FROM @kurzor INTO @TERULET, @ID
ENDCLOSE @kurzor
DEALLOCATE @kurzor
END;a kiemelt részt módosítottam, kivettem a belső selectet, ott felesleges, ha a kurzorban van már az id.
[ Szerkesztve ]
-
-
válasz kw3v865 #3665 üzenetére
annak a true-nak meg false-nek nem sok értelmét látom, mert ha védett régióban van, akkor a védett régió neve oszlop nem null lesz, ha meg nem ott van, akkor igen.
viszont ez nem kellene, hogy sokat lassítson, mert a postgresql elméletileg becacheli az adatokat meg az eredményeket.
ha a kifejezés elé írsz egy explain-t, akkor megmondja az optimalizáló, hogy mit fog csinálni. azt érdemes bogarászgatni.
szerk: azt az egész case-t ki lehetne váltani szerintem úgy, hogy a lekérdezett mezők közé felveszed a védett régió nevét, és egy coalesce-vel beleírsz valamit, ha üres: coalesce(pr.name,'FALSE') as name.
[ Szerkesztve ]
Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis
-
-
-
kw3v865
senior tag
válasz kw3v865 #3833 üzenetére
Na, elvileg megoldottam, így:
for rec in
select format('copy(select valami from table where nev=''%s'' order by gid)
to ''%s'' with csv delimiter '';'' HEADER',nev,telepules,'C:/eredmeny/'||telepules||'_'||nev||'.csv' ) scr from(
Select distinct nev, telepules from tabla)t
loop
execute rec.scr;
end loop;Azért még leellenőrzöm alaposan, hogy tényleg jó-e.
-
válasz kw3v865 #3860 üzenetére
ha az a kérdés, hogy hogyan hozod össze a rekordot meg az utána következő rekordot, akkor ebből inspirálódhatsz:
lehet táblának saját magával vett descartes szorzatát venni:
select t1.*,t2.* from tabla t1, tabla t2;
ezt a te esetedben nagyjából így kellene alkalmazni:
select t1.*,fuggveny(t1.masvalami,t2.masvalami) from tabla t1, tabla t2 where t1.id+1=t2.id;
ebből meg tudod faragni az udapte utasítást.
ha egy 8 millió soros táblára ráborítod, jusson eszedbe, hogy adatbáziskezelésnél a sok ramot csak a mégtöbb ram pótolhatja
Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis
-
Ispy
veterán
válasz kw3v865 #3860 üzenetére
Ötlet, én így csinálnám (nincsen tapasztalatom ekkora táblával, szkuzi):
- hozzáadsz egy ID mezőt a táblához, running number 1-8000000-ig folyamatos sorszámod lesz, sorba rendezés, ahogy neked sorba kellenek az adatok
- joinolod a táblát saját magához úgy, hogy tábla1 ID=tábla2ID+1, igy kapni fogsz egy olyan lekérdezést, ahol minden tábla1 sor mellett ott lesz a következő sor adatai
- ráereszted a függvényt az updattel
- én a helyedben tesztelném mondjuk a megoldást 100k adattal és ha jó, akkor darabokban futtatnám a taskot nem egyben, mert a világ összes memóriája sem lesz elég, pláne ha tranzakcióban fut az update...."Debugging is like being the detective in a crime movie where you're also the murderer."
-
nagyúr
válasz kw3v865 #3900 üzenetére
hogy mi lesz gyorsabb, azt neked kell kimérned. táblától, és hardvertől függően változhat.
alternatívák vannak,select id from table order by id desc limit 1;
select currval(pg_get_serial_sequence('tábla', 'id'));
stb.Tudod, mit jelent az, hogy nemezis? Az érintett, erősebb fél kinyilatkoztatása a méltó büntetés mértékét illetően. Az érintett fél jelen esetben egy szadista állat... én.
-
válasz kw3v865 #3900 üzenetére
ha postgresql-hez kötött megoldás is megfelel, akkor:
where id = (select last_value from table_id_seq);
ezzel a lekérdezéssel bármikor le tudod kérdezni a legutolsó id-t. de ez nem szép.
ha az adott sessionben raktad bele a sort, akkor egy fokkal rendesebben néz ki:
where id = (select currval('table_id_seq'));
vagy, szerintem a legjobb megoldás, kérdezd le, hogy milyen értéket szúrt be az insert, ha ez megoldható:
insert blablab returning id;
ezt akkor tudod használni, ha az insertet akkor csinálod, amikor az id-je is kell.
Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis
-
-
-
martonx
veterán
-
-
Apollo17hu
őstag
válasz kw3v865 #4122 üzenetére
Így?
SELECT tabla.mezo
,substr(tabla.mezo, instr(tabla.mezo, '"ref"=>""') + length('"ref"=>""')) relevans_adattartalom
FROM (SELECT 'asfasf saf"ref"=>""ez kell' mezo
FROM dual
UNION
SELECT 'asfasf ssadfalksijdfkeefaf "ref"=>""ez is kell, de ez hosszabb' mezo
FROM dual) tablaSubstr utolsó paraméterét elhagyva a mező utolsó karakteréig mindent leválogat. Ha nem jó, akkor mindenképp kell egy ismérv/logika, ami meghatározza a releváns karaktersorozat végét.
-
Lortech
addikt
válasz kw3v865 #4377 üzenetére
'INSERT INTO '||$1||'.table (azonosito, nev) SELECT '||id||','||name;
>>
kiértékelés után: INSERT INTO abc.table (azonosito, nev) SELECT id_erteke, name_erteke;
Hiányzik tehát id és name változó értékei körül az aposztróf, különben azt hiszi, hogy nem egy literál, hanem egy oszlop, azért nem találja. (az id azért oké, mert number típus gondolom)
Aposztróf escape-eléséhez duplázni kell.[ Szerkesztve ]
Thank you to god for making me an atheist
-
Lortech
addikt
válasz kw3v865 #4380 üzenetére
Mert a formatos megoldásod dollar quotingot használ, ami a jobban olvasható, biztosabb, egyszóval a javasolt megoldás.
Ha visszamegyünk az eredeti statikus, működő insert statementedhez:
INSERT INTO tesztsema.table (azonosito, nev) SELECT 2332,'xyz';
Az volt a cél, hogy ezt a stringet dinamikusan előállítsd, és átadd az EXECUTE statementnek.
Azt pedig úgy tudod megtenni, hogy aposztrófokat is odateszed a példában az xyz köré.
A '||name csak annyit csinál, hogy a name értékét hozzáfűzi a stringhez, de aposztrófok ettől még nem lesznek körülötte, és text típusnál ez szükséges. Szóval, vagy te fűzöd oda (nem javasolt, csak a probléma megértéséért említettem az előző hozzászólásomban), vagy dollar quotingot vagy quote_literal() / quote_ident() fgv-t használsz.Másikhoz. Ilyen szerkezet nincs, hogy IF EXECUTE
Olyan tudsz csinálni, hogy
EXECUTE STATEMENT into VAR és a VAR értékét vizsgálod IF-fel.[ Szerkesztve ]
Thank you to god for making me an atheist
-
martonx
veterán
-
válasz kw3v865 #4390 üzenetére
a postgresql is tud olyat, hogy ip címre vagy tartományra korlátozni a klienseket, illetve ugyanezt tűzfallal is meg lehet oldani. ez akkor jó, ha a klienseknek ismert az ip címtartománya.
elvileg használ ssl-t, tehát akár azt is meg lehet csinálni, hogy csak ismert kulcsú klienseket beengedni.
hogy ez mennyire biztonságos, az attól is függ, hogy milyen adatokat teszel bele.
a másik lehetőség, én valószínűleg ezt választanám, hogy az insert utasításokat kiírom egy text fájlba, azt rsync+ssh-val szinkronizálnám a szerverre, és ott betölteném adatbázisba.
A db-ben hosztolt adatbázisról meg annyit, hogy a benne tárolt adatok fajtájától és a hozzá tartozó szabályzatoktól, eljárásrendtől függően (úgy értem: ezek nem elegendően precíz meghatározása esetén) akár 2 év börtönnel fenyegetett bűncselekmény is lehet felhőbe adatbázist rakni.
Az api api hátán api-val megbolondítva típusú túltervezettségről továbbra is az a véleményem, hogy semmi értelme, mert egy saját fejlesztésű apiban nagyobb valószínűséggel lesz bug, mint egy postgresql net protokollban, vagyis olyan plusz energiabefektetés, ami sose térül meg, csak ront a helyzeten.
Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis
-
nyunyu
félisten
válasz kw3v865 #4459 üzenetére
Mi volt a baj az eredeti elképzeléseddel?
FOR nem a mögé írt query által visszaadott sorrendben megy végig a sorokon, mint ahogyan a kurzorok tennék? De.
Indexelős ötleted nagyon elborult, egyrészt nehéz megvalósítani, pl. mi van akkor, ha jön egy új elem a táblába, akkor minden sort megupdatelsz az aktuális sorrend alapján?
Iszonyúan nagy overheadet produkálnának az ehhez szükséges triggerek.Ha csak annyi lenne a kérdés, hogyan tudod megmondani egy sorról, hogy ő valamilyen rendezés szerint hanyadik a táblában, akkor a row_number() over (order by x,y) függvényt tudod használni.
Egyébként meg a relációs adatbázisok mindig halmazokkal dolgoznak, nem egy-egy elemmel, így a más programnyelvek procedurális gondolkozásmódja (ciklusok, kurzorok...) SQLben sosem ad jó teljesítményt.
Próbálj inkább úgy gondolkozni, hogyan lehet egy queryvel az összes adatot egyszerre frissíteni/beszúrni.Előző projekten amúgy belefutottam hasonlóba, mint amit most szeretnél.
Örököltem egy kódot, ami egy táblából csinált egy rendezett kurzort, majd azon ment végig egyesével, és dinamikus SQLben kért új értéket egy szekvenciából, majd updatelte rá a tábla soraira, kvázi új indexet vezetett be.
Persze, hogy 15000 sor esetén húsz percig szöszmötölt rajta az Oracle.
Megoldás az lett, hogy egy segédtáblába leválogattam a fő tábla azonosítóit, meg a row_number() over (order by x,y) rn-t, aztán következett egy jól irányzott merge a fő táblára.
Egyből lefut 10 másodperc alatt...[ Szerkesztve ]
Hello IT! Have you tried turning it off and on again?
-
nyunyu
félisten
válasz kw3v865 #4617 üzenetére
Ha az a cél, hogy egy külső alkalmazás paraméterezetten hívjon egy eljárást/függvényt, akkor nem tudod refcursorral visszaadni a szűrt halmazt?
Legalábbis mi Oracle 11g alapon így szoktuk visszaadni az adatokat:
procedure get_order_status(p_group_id number, p_posting_id number, p_id number, p_order_num varchar2, c out sys_refcursor) is
begin
open c for
select
i.group_id,
i.posting_id,
i.id,
i.order_num,
o.status as status,
to_char(o.status_dt,'yyyy-mm-dd hh24:mi:ss') as status_ts
from input i
left join s_order o
on o.order_num= i.order_num
where i.id = p_id
or i.group_id = p_group_id
or i.posting_id = p_posting_id
or i.order_num = p_order_num;
end;Aztán Javaban fetchelik a kurzort.
[ Szerkesztve ]
Hello IT! Have you tried turning it off and on again?
-
-
válasz kw3v865 #4798 üzenetére
azt, hogy a postgresql ne cacheljen, úgy a legegyszerűbb elérni szerintem, hogy kicsire veszed a neki adott memóriát. esetleg egy fals lekérdezéssel kiszorítod az értékes adatot a ramból.
hogy az oprendszer a blokkos eszközt ne cachelje, az az oprendszertől függ.
Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis
-
-
-
sztanozs
veterán
válasz kw3v865 #4910 üzenetére
Ez már operációkutatás, nem adatbázis kérdés...
tegyük fel a következőt:
1 | 2 | 10 | 20
2 | 2 | 10 | 30
3 | 2 | 10 | 40
4 | 2 | 20 | 30
5 | 2 | 20 | 40
6 | 2 | 20 | 50
7 | 2 | 30 | 40
8 | 2 | 30 | 50
9 | 2 | 30 | 60
Ezzel a forrással milyen range-eket hozol létre és melyik melyikbe tartozna?[ Szerkesztve ]
JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...
Új hozzászólás Aktív témák
- PlayStation 5
- LG 34GS95QE-B: OLED paneles, ívelt gamer monitor
- Teljes verziós, ingyenes mobil játékok és alkalmazások
- Bambu Lab X1/X1C, P1P-P1S és A1 mini tulajok
- Eredeti játékok OFF topik
- Politika
- Fotók, videók mobillal
- iPhone topik
- PlayerUnknown’s Battlegrounds
- Milyen billentyűzetet vegyek?
- További aktív témák...
- Tyű-ha! HP EliteBook 850 G7 Fémházas Szuper Strapabíró Laptop 15,6" -65% i7-10610U 32/512 FHD HUN
- Bomba ár! HP EliteBook 840 G5 - i5-8G I 8GB I 128GB SSD I 14" FHD I HDMI I Cam I W10 I Gari!
- The Last of Us Part I Ps5
- Bomba ár! HP EliteBook 830 G6 - i7-8G I 8GB I 256GB SSD I 13,3" FHD I HDMI I Cam I W11 I Gari!
- Bomba ár! Dell Latitude 5580 - i5-G6 I 8-16GB I 256 SSD I 15,6" FHD I HDMI I CAM I W10 I Garancia
- 3DB 50e Ft 6/128GB IPS PEAQ 10.9 COLOS TABLET ÚJ ÁLLAPOTBAN SZOFTVER NÉLKÜL
- Samsung Galaxy Watch 6 - 40MM - Arany
- Sony FE 85mm f1.8 objektív
- LG 75NANO869PA TV 189 cm 120 Hz, Smart TV.2 ÉV GYÁRI GARANCIA!!
- Retro alaplap gyűjteményem felszámolása (11 alaplap: 6 működik, ezekről BIOS képekkel) - egyben 7k