Forum » Programiranje » [SQL] primary key inkrementalno dodajanje
[SQL] primary key inkrementalno dodajanje
korenje3 ::
Pri nas je SQL slabo skonfiguriran in ne dodaja samodejno primary key vrednosti.
npr.:
Če imam še primary key kolono 'Id' (int). Kakšen mora biti ukaz potem, da mi avtomatsko doda Id vrednost inkrementalno?
npr.:
INSERT INTO [Product] ([ProductName], [SupplierId], [Package]) OUTPUT inserted.[Id] VALUES (CAST('TEST 2 LALA' AS NVARCHAR(50)), PARSE('1' AS INT USING 'Sl-SI'), CAST('24 - 12 oz bottles' AS NVARCHAR(30)));
Če imam še primary key kolono 'Id' (int). Kakšen mora biti ukaz potem, da mi avtomatsko doda Id vrednost inkrementalno?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
zavajon ::
Če gre za T-SQL, moraš kreirati tabelo z identity.
CREATE TABLE Product ( id int IDENTITY, ...
V MySQL je tako: CREATE TABLE Product ( id int NOT NULL AUTO_INCREMENT, ...
korenje3 ::
Kaj pa če ne smem pipat tabele?
Pri insertu mi napiše da Id ne sme biti null. Samodejno mi pa ne doda številke.
Strežnik je pa tsql.
Gre se pa za largo bazo podjetja perftech. Mogoče če kdo dela v tem podjetju da bi vedel ustrezen ukaz...? Ali se zaporedje šifr hrani kje drugje?
Pri insertu mi napiše da Id ne sme biti null. Samodejno mi pa ne doda številke.
Strežnik je pa tsql.
Gre se pa za largo bazo podjetja perftech. Mogoče če kdo dela v tem podjetju da bi vedel ustrezen ukaz...? Ali se zaporedje šifr hrani kje drugje?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Zgodovina sprememb…
- spremenil: korenje3 ()
DamijanD ::
Če hočeš, da se bo ID sam polnil, je potrebno polje definirat, da je identity. (Vsaj pri mssql imaš problem, ker tega ne moreš nastaviti na obstoječem polju...)
Vazelin ::
Lol korenje brez nič ne bo nič
Lahko uporabiš sekvenco samo potem moraš vedno filat s sekvenco
Lahko uporabiš sekvenco samo potem moraš vedno filat s sekvenco
I got 99 problems but 4 usd XTZ ain't one...
Macario ::
Če hočeš, da se bo ID sam polnil, je potrebno polje definirat, da je identity. (Vsaj pri mssql imaš problem, ker tega ne moreš nastaviti na obstoječem polju...)
lahko na obstoječem polju nastaviš identity. Ravno sedaj poskusil.
Sem šel gledat skripto v sql managerju ob spremembi tabele in tehnično je to res, da ne moreš obstoječu stolpcu spremeniti identity.
Namreč skripta naredi temp tabelo z identity on, skopira podatke noter, dropne staro tabelo in preimenuje novo temp tabelo.
Iz uporabniškega vidika je res, da lahko doda identity na obstoječi column toda zadaj pa je v resnici nova tabela, nov column.
Zgodovina sprememb…
- spremenilo: Macario ()
zavajon ::
Kaj pa če ne smem pipat tabele?
Pri insertu mi napiše da Id ne sme biti null. Samodejno mi pa ne doda številke.
Strežnik je pa tsql.
Gre se pa za largo bazo podjetja perftech. Mogoče če kdo dela v tem podjetju da bi vedel ustrezen ukaz...? Ali se zaporedje šifr hrani kje drugje?
Potem naredi trigger, ki pri insertu izračuna max(id) in doda naslednjo vrednost.
Če pa triggerja ne moreš narediti, boš moral najprej prebrati max(id) in nato insertati ta max(id)+1.
Ahim ::
Potem naredi trigger, ki pri insertu izračuna max(id) in doda naslednjo vrednost.
Če pa triggerja ne moreš narediti, boš moral najprej prebrati max(id) in nato insertati ta max(id)+1.
To je nocna mora za vsako resno bazo, do katere ne dostopa samo en klient naenkrat, ki izvaja samo eno transakcijo naenkrat in na kateri ni nobenih rollbackov transakcij.
Zgoraj so lepo napisali, da naj nastavi identity. Largo pa Perftech pa ... ce nimas dostopa do tabele, naj pa oni naredijo.
korenje3 ::
Imam dostop, samo njihov program uporablja SQL bazo, tako da ne smem spreminjat. V bistvu bi moral izvršit enak ukaz kot ga njihov program. To da se ugotavlja kateri je zadnji zapis pa verjetno ne pride v poštev, ker v primeru da 2 naenkrat izvršita ukaz lahko duplicira.
Mi pa ni jasno zakaj je inkrementiranje izklopljeno sploh. Zaradi hitrosti?
Mi pa ni jasno zakaj je inkrementiranje izklopljeno sploh. Zaradi hitrosti?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Zgodovina sprememb…
- spremenil: korenje3 ()
kuall ::
daš v transakcijo, če te skrbi, da se bo med stavka:
get id
insert with id
vrinil get id od drugega uporabnika
transakcija bo zaklenila tabelo, da v času ne bo noben mogel vstavljat
ampak nisem zihetr, da je treba tako komplicirat, v praksi takega kompliciranja nisem videl, ni mi pa jasno zakaj ne, ker teoretično je res možno, da se vmes vrine stavbek od drugega uporabnika
subquery je najbolj zanesljiva rešitev. jaz se transakcijam izogibam, ker če jo pustiš odprto zna bit mau pizdarija.
create table _testz (id int)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
select* from _testz
get id
insert with id
vrinil get id od drugega uporabnika
transakcija bo zaklenila tabelo, da v času ne bo noben mogel vstavljat
ampak nisem zihetr, da je treba tako komplicirat, v praksi takega kompliciranja nisem videl, ni mi pa jasno zakaj ne, ker teoretično je res možno, da se vmes vrine stavbek od drugega uporabnika
subquery je najbolj zanesljiva rešitev. jaz se transakcijam izogibam, ker če jo pustiš odprto zna bit mau pizdarija.
create table _testz (id int)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
select* from _testz
kuall ::
lahko z sql profilerjem pogledš, kakšen ukaz uporablja njihov program in samo tisto prekopiraš v svojo kodo
kuall ::
aja vrstni red bi moral biti takle, da bi se zbrkljalo:
uporabnik2: get id
uporabnik1: get id
uoprabnik1: insert with id
uporabnik2: insert with id
torej totalen nelogičen vrstni red.
zato ti ni treba skrbet. razen če bi se vsak query izvrševal v neki svoji niti, in bi vsaka nit dobila neko svojo random prioriteto in vrstni red izvrševanja bi lahko prišlo do zgornjega zbrkljanja, ampak po moje se sql ukazi izvajajo lepo zaporedno, zato ni treba komplicirat s transkacijami itd.
uporabnik2: get id
uporabnik1: get id
uoprabnik1: insert with id
uporabnik2: insert with id
torej totalen nelogičen vrstni red.
zato ti ni treba skrbet. razen če bi se vsak query izvrševal v neki svoji niti, in bi vsaka nit dobila neko svojo random prioriteto in vrstni red izvrševanja bi lahko prišlo do zgornjega zbrkljanja, ampak po moje se sql ukazi izvajajo lepo zaporedno, zato ni treba komplicirat s transkacijami itd.
Lonsarg ::
To so najhujše vrste bugi/napake, če tega nimaš porihtanega v transakciji, to imamo bič za take ki ne bi to pazili!
kuall ::
da daš get id insert id v transakcijo?
sem pregledal veliko sql kode in nikoli videl tega v transakciji.
ni tako hud bug, bi ti itak javil napako, da je id že zaseden (če imaš unique index, kar ga ponavadi imaš)
sem pregledal veliko sql kode in nikoli videl tega v transakciji.
ni tako hud bug, bi ti itak javil napako, da je id že zaseden (če imaš unique index, kar ga ponavadi imaš)
smacker ::
kaj sem narobe napisal?
Vse, razen tega da je treba uporabit transakcijo, če nočeš da te kaj prekine. Ampak za ta problem tudi to ni najbolj ustrezna rešitev, namreč MAX(id)+1 lahko privede do nevšečnosti, ko nov record dobi isti ID, kot ga je pred tem imel nek drug record, ki je sedaj izbrisan.
kuall ::
kaj je s tem narobe:
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
kuall ::
je treba uporabit transakcijo, če nočeš da te kaj prekine.
transakcija ti v tem primeru nič ne pomaga, ker select max ne zaklene tabele, zaklene jo šele, če pišeš v njo
vse si narobe napisal, nimaš pojma
ok spet sem moral sam najti rešitev, fakin jypeti neuporabni:
create table _test55 (id int)
begin transaction
declare @id int = isnull (((select max(id) from _test55 with (TABLOCKX ))), 0) + 1
insert into _test55 (id) values (@id)
commit
Zgodovina sprememb…
- spremenilo: kuall ()
jype ::
Še vedno pa ne razumeš, kaj si storil?
Šokantno.
No, naj ti pomagam:
Linearizability @ Wikipedia
Read%E2%80%93modify%E2%80%93write @ Wikipedia
Šokantno.
No, naj ti pomagam:
Linearizability @ Wikipedia
Read%E2%80%93modify%E2%80%93write @ Wikipedia
Zgodovina sprememb…
- predlagalo izbris: kuall ()
kuall ::
ne mi limat te debilne wikipedia članke. vem da je teoretično možno, da se sql ukazi izvajajo v random vrstnem redu, saj to sem že napisal.
zanima me kako se sql obnaša v praksi. po moje ni tako random, zakaj bi bil.
zanima me kako se sql obnaša v praksi. po moje ni tako random, zakaj bi bil.
Vazelin ::
Jype: zakaj korenju ne napišes rešitve lol. Boli njega k za lineariablitiy :D on rabi rešitev
I got 99 problems but 4 usd XTZ ain't one...
kuall ::
zato ker ge ne ve, ampak blefira kot ponavadi. saj smo mu v eni temi že dokazali, da je blefer, se ne spomniš. ko je trdil, da ima naloga rešitev in da smo loleki, ker rešitve ne vemo, na koncu pa smo dokazali, da rešitve ni za nalogo.
bleferji daleč pridejo, zato ni za podcenjevat tega njegovega skilla.
bleferji daleč pridejo, zato ni za podcenjevat tega njegovega skilla.
jype ::
zakaj korenju ne napišes rešitve lolKer nima zadostnega dostopa, da bi jo izvedel.
zato ker ge ne ve, ampak blefira kot ponavadi. saj smo mu v eni temi že dokazali, da je blefer, se ne spomniš. ko je trdil, da ima naloga rešitev in da smo loleki, ker rešitve ne vemo, na koncu pa smo dokazali, da rešitve ni za nalogo.Dokazali ste, da nimate pojma o matematiki.
zanima me kako se sql obnaša v praksi. po moje ni tako random, zakaj bi bil.V praksi boš na težave naletel prej, kot si domišljaš.
Zgodovina sprememb…
- spremenilo: jype ()
Spura ::
ne mi limat te debilne wikipedia članke. vem da je teoretično možno, da se sql ukazi izvajajo v random vrstnem redu, saj to sem že napisal.
zanima me kako se sql obnaša v praksi. po moje ni tako random, zakaj bi bil.
Ne vem od kod ti taka vera, da SQL server ukaze on enega connectiona vse izvede do konca, preden gre na druge ukaze. Mislim,
tvoja trditev
ampak po moje se sql ukazi izvajajo lepo zaporedno, zato ni treba komplicirat s transkacijamije povsem zmotna. "Po tvoje" je povsem neinformirano mnenje. Baze izvajajo ukaze iz vecih niti, to so OS niti, ne green threadi, torej tudi ce bi DB hotel razvrscati izvajanje procesov, tega ne more, ker scheduler za niti je v OS kernelu in ta pojma nima kaj baza dela, in lahko ustavi izvajanje niti na vsakem strojnem ukazu.
Manjka ti osnovno znanje o tem podrocju.
korenje3 ::
je treba uporabit transakcijo, če nočeš da te kaj prekine.
transakcija ti v tem primeru nič ne pomaga, ker select max ne zaklene tabele, zaklene jo šele, če pišeš v njo
vse si narobe napisal, nimaš pojma
ok spet sem moral sam najti rešitev, fakin jypeti neuporabni:
create table _test55 (id int)
begin transaction
declare @id int = isnull (((select max(id) from _test55 with (TABLOCKX ))), 0) + 1
insert into _test55 (id) values (@id)
commit
Torej ni možno da se med declare @id in insert nekomu drugemu oba ukaza izvršita prej?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
kuall ::
ampak to pride do izraza v ekstremnih pogojih, v kakšnih naprimer?
v takih ne, če imaš bazo, 2 računalnika povezana na njo in vsak povezan na njo preko (počasnega) interneta. v tem primeru se sigruno 2 sql zaporedna queryja izvedeta do konca, preden se izvaja drug.
mogoče če imaš multiprocesor računalnik in milijone uoprabnikov..
zdele gledam sql kodo od enega večjega programa. kar lepo uporablja select max id in potem dela insert tega idja brez transkacija. očitno tudi njim manjkajo osnove.
ja ta rešitev drži, lahko jo uporabiš brez skrbi:
create table _test55 (id int)
begin transaction
declare @id int = isnull (((select max(id) from _test55 with (TABLOCKX ))), 0) + 1
insert into _test55 (id) values (@id)
commit
v takih ne, če imaš bazo, 2 računalnika povezana na njo in vsak povezan na njo preko (počasnega) interneta. v tem primeru se sigruno 2 sql zaporedna queryja izvedeta do konca, preden se izvaja drug.
mogoče če imaš multiprocesor računalnik in milijone uoprabnikov..
zdele gledam sql kodo od enega večjega programa. kar lepo uporablja select max id in potem dela insert tega idja brez transkacija. očitno tudi njim manjkajo osnove.
ja ta rešitev drži, lahko jo uporabiš brez skrbi:
create table _test55 (id int)
begin transaction
declare @id int = isnull (((select max(id) from _test55 with (TABLOCKX ))), 0) + 1
insert into _test55 (id) values (@id)
commit
Zgodovina sprememb…
- spremenilo: kuall ()
jype ::
Torej ni možno da se med declare @id in insert nekomu drugemu oba ukaza izvršita prej?Seveda je možno. Ne le možno, celo neizogibno v kakršnihkoli sistemih, kjer baza dejansko dela.
zdele gledam sql kodo od enega večjega programa. kar lepo uporablja select max id in potem dela insert tega idja brez transkacija. očitno tudi njim manjkajo osnove.Očitno.
Verjetnost, da s takim početjem ustvarijo nekonsistenten zapis, s številom transakcij narašča skoraj eksponentno na vsakem sodobnem RDBMS, zato pa vsak sodoben RDBMS implementira reči, ki to preprečijo, samo uporabiti ga moraš.
Zgodovina sprememb…
- spremenilo: jype ()
korenje3 ::
V poslovnem okolju "verjetnost napake" odpade. Zadeva mora funkcionirat 100% ali pa izpisat da je bila napaka (key value že obstaja).
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
kuall ::
identity kolona je ta najbolj varen mehanizem?
kaj pa če hočeš imeti autoinc subkolono, npr id, subid? uporabit transakcijo + unique composite index (id, subid) bo kle sigurna rešitev.
kaj pa če hočeš imeti autoinc subkolono, npr id, subid? uporabit transakcijo + unique composite index (id, subid) bo kle sigurna rešitev.
jype ::
korenje3 ::
Jutri pogledam kakšna je ta kolona "Šifra" v resnici s sql explorerjem in zakaj nima auto increment.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
kuall ::
prilimiaj kodo ki jo dobiš z sql profilerjem, kako njihov program dela insert. me zanima, če uporablja transakcijo.
Ti pa ziher nisi programer.
sej lahko po insertu komot narediš preverbo, ali so vsi idji unique ali se je v tem času vrinil en drug isti id, če te tako skrbi, in javiš napako. ampak to je brezveze bluzeneje.
V poslovnem okolju "verjetnost napake" odpade. Zadeva mora funkcionirat 100% ali pa izpisat da je bila napaka (key value že obstaja).
Ti pa ziher nisi programer.
sej lahko po insertu komot narediš preverbo, ali so vsi idji unique ali se je v tem času vrinil en drug isti id, če te tako skrbi, in javiš napako. ampak to je brezveze bluzeneje.
Zgodovina sprememb…
- spremenilo: kuall ()
kuall ::
kaj je s tem narobe:
insert into _testz (id) values (isnull ((select max (id) from _testz), 0) + 1)
no še na tole moram sam odgovorit:
compiler to prevede v dve izjavi, najprej izračuna subquery, nato glavni query. ni dost drgač kot da bi napisal query1 in query2.
med te izjavi se teoretično lahko vrine drug uporabnik s svojim idjem, ki je enak.
ampak ta debata je mim zato, ker so v praksi vsi idji unique index. če že pride do takega primera (zelo redko) bo uporabnik dobil dobil napako, da id že obstaja in bo pač ponovil insert.
me pa zanima od vas "veleumov", če znate napisat test program, ki bo znal ponoviti to napako, da se bo id od drugega uoprabnika vrinil med select max id in insert id. seveda ne znate, ker ste blefereji.
jype ::
korenje3 ::
Za sql profiler nimam dostopa. Kolona pa nima avtomatskega dodajanja vklopljenega. Tako da ne morem vedet kako program dajaja nove vrstice v tabelo...
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
no comment ::
Tako da ne morem vedet kako program dajaja nove vrstice v tabelo...
Glede na to, da polje ni identity lahko "veš", da dodaja po "kmečko". Glede na to, da praviš, da je to polje PK, potem verjetno enostavno ugotovi zadnji ID, ga inkrementira in poskusi z insertom. Če insert crkne, poskusi z naslednjim itd.
korenje3 ::
Tako je kot si rekel, verjetno dodaja po kmečko. Se vidi da so na perftech pocarji... kasirajo pa po 100€/h za sestanek. Že po imenih kolon v različnih tabelah se vidi, da je vsak "programer" delal nekaj po svoje s svojim omejenim znanjem.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W
MrStein ::
sej lahko po insertu komot narediš preverbo, ali so vsi idji unique ali se je v tem času vrinil en drug isti id, če te tako skrbi, in javiš napako. ampak to je brezveze bluzeneje.
What the actual fuck?????
A to delaš neki prank? Vic?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
dmok ::
MrStein ::
Zakaj sploh dodajaš zapise "mimo programa"?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
Vazelin ::
Velika šansa je ja, da jim korenje zjebe in bazo in program
Lahko majo kako svojo tabelo s vrednostjo key-ev. To si pomislil, korenje? Sicer sem bolj sql noob (samo občasno zanima me), ampak igraš se nevarno igro
Lahko majo kako svojo tabelo s vrednostjo key-ev. To si pomislil, korenje? Sicer sem bolj sql noob (samo občasno zanima me), ampak igraš se nevarno igro
I got 99 problems but 4 usd XTZ ain't one...
Zgodovina sprememb…
- spremenilo: Vazelin ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Učenje programiranja PHPOddelek: Programiranje | 1483 (1024) | Spura |
» | Nova različica podatkovne baze PostgreSQL 9.5 prinaša obilico novosti (strani: 1 2 )Oddelek: Novice / Ostala programska oprema | 17676 (14542) | McAjvar |
» | Potrebujem MySQL ukazOddelek: Programiranje | 2884 (2492) | zvmk |
» | [SQL] InsertOddelek: Programiranje | 2075 (1677) | greentech |
» | [T-SQL] Kako vnest podatek v bazo in da ti hkrati vrne id?Oddelek: Programiranje | 2896 (2614) | dmok |