Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Pomoc oko sql upita

[es] :: MS SQL :: Pomoc oko sql upita

[ Pregleda: 1728 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

bikazl

Član broj: 287637
Poruke: 7
95.180.36.*



Profil

icon Pomoc oko sql upita09.07.2011. u 21:09 - pre 155 meseci
Zdravo svima,
Imam tabelu nagradna igra sa kolonama: ID, shortcode, broj telefona, Da li je izvucen (opciono je true ili false)
Interesuje me kako da napravim SQL upit koji ce prilikom unosa novog broja u tabelu zabraniti da taj broj moze ponovo biti izvucen, odnosno da je jedino moguce za njega u koloni Da li je izvucen, postaviti true vrednost.
Unapred hvala!
 
Odgovor na temu

Zidar
Canada

Član broj: 15387
Poruke: 3085
*.100.46-69.q9.net.



+79 Profil

icon Re: Pomoc oko sql upita11.07.2011. u 14:37 - pre 155 meseci
Nije jasno sta pokusavas. Jedna mogucnost je da imas mnogo redova u tabeli i samo za neke je vrednost [Da li je izvucen ] = TRUE. Druga mogucnost je da u tabelu upisujes samo one koji su izvuceni, znaci svaki red ima [Da li je izvucen ] = TRUE. Resenje je moguce i jednostavno je u oba slucaja. Koji te slucaj intersuje?
 
Odgovor na temu

bikazl

Član broj: 287637
Poruke: 7
*.static.isp.telekom.rs.



Profil

icon Re: Pomoc oko sql upita11.07.2011. u 15:09 - pre 155 meseci
U pitanju je prva mogucnost imam tabelu u kojoj su vrednosti za pojedine redove kolone [Da li je izvucen ] True a za neke false. I prilikom bilo kog daljeg unosa nekog novog reda treba ispitati da li vec postoji taj broj telefona, da li je true i ako je u oba slucaja odgovor pozitivan, treba zabraniti da se za taj red stavi vrednost true u koloni [Da li je izvucen ], dakle moze da stoji samo [Da li je izvucen ] = FALSE.
Nadam se da sam sad bila malo jasnija.
 
Odgovor na temu

Zidar
Canada

Član broj: 15387
Poruke: 3085
*.100.46-69.q9.net.



+79 Profil

icon Re: Pomoc oko sql upita11.07.2011. u 16:25 - pre 155 meseci
Dobro. Imas znaci tabelu (id,ID, shortcode, [broj telefona], [Da li je izvucen]). Dozvoljava se da broj telefona bude u tabeli vise puta. Za svaki [broj telefona] moguce je samo jednom postaviti [Da li je izvucen] na TRUE. Posto je u pitanju MS SQL forum, pretpostavljam da radis u MS SQL pa ce resenje biti primenljivo na MS SQL.

Prvo, MS SQL ne poznaje TRUE/FALSE, MS SQL poznaje 0 i 1 i BIT kolonama. pretpostavljam da je kolona [Da li je izvucen] tipa 'byte'. Predlazem da promenis tip kolone [Da li je izvucen], sa byte na tinyint. Ovako bi definisao kolonu [Da li je izvuce]:
CREATE TABLE NagradnaIgra
(Id... NOT NULL
, ShortCode... NOT NULL
,[broj telefona]... NOT NULL
, [Da li je izvucen] tinyint NOT NULL CHECK ([Da li je izvucen] IN (0,1)) DEFAULT 0
)

Ovim dozvoljavas samo vrednosti 0 i 1, 0 je pocetna vrednost za svaki novi red.

Kako da dozvolis najvise jednu vrednost 1 u koloni [Da li je izvucen]? Ako koristis MS SQL 2008 onda mozes da koristsi filtrirani index, nesto kao

CREATE UNIQUE INDEX SamoJednoIzvlacenje ON NagradnaIgra ([broj telefona],[Da li je izvucen]) WHERE [da li je izvucen]=1

To je sve sto treba da uradis u MS SQL 2008. SQL 2008 dozvoljava WHEER u definiciji indexa, sto jeveoma zgodna stvar

Ako koristis neku raniju verziju MS SQL, ond ne mozes da koristis filtrirani index. Isti efekat se postize kombinovanjem neke identity kolone i kolone [Da li je izvucen]. Recimo da je tvoja kolona Id integer, identity koji pocinje od 1, NOT NULL (ako nije, dodaj jednu takvu identity kolonu i sve sto sledi primeni na tu kolonu).

1) Treba ti UNIQUE index po koloni Id (koja je NOT NULL kolona, ovo je vazno):

CREATE UNIQUE INDEX UniqID ON NagradnaIgra(Id)

2) Zatim, dodaj jednu racunsku kolonu u tabelu, ovako:

ALTER TABLE NagradnaIgra
ADD RacunskaKolona AS (CASE WHEN [da li je izvucen]=1 THEN 0 ELSE Id END)

3) onda dodas ovakav UNIQUE index:

CREATE UNIQUE INDEX UniqueRacunskaKolona ON NagradnaIgra([BrojTelefona],RacunskaKolona)

Gotovo. To je to.

Za sve slucajeve redove koji nisu izvuceni, vrednost RacunskeKolone bice jednaka Id, a to je UNIQUE po celoj tabeli jer je ID jedinstven po celoj tabeli. U slucajevima da je [Da li je izvucen]=1 imamo RacunskaKolona = 0. Kombinacija ([Brojtelefona],RacunskaKolona) bice jednaka na primer (416-123-456,0) i to ce moci da se desi samo jednom za dati broj telefona, zbog indeksa UniqueRacunskaKolona.

Tvoja tabela nece prihvatiti vise od jedne vrednosti 1 u koloni [da li je izvuce] po jednom telefonskom broju. Broj vrednosti 0 u koloni [Da li je izvucen], po svakom telefonskom broju, nije ogranicen.

Nemas potrebe da pises nikakav kod da bi obezbedio "najvise jedna vrednost 1 po telefonu u koloni [da li je izvucen] ".

Sve je u skaldu sa Zidarevom teoremom "The best code is no code at all"

 
Odgovor na temu

bikazl

Član broj: 287637
Poruke: 7
*.static.isp.telekom.rs.



Profil

icon Re: Pomoc oko sql upita12.07.2011. u 15:09 - pre 155 meseci
Hvala na pomoci, ali ovo ce mi resiti samo pozadinski deo problema. A sada ako moze pomoc vezana za sledeci slican problem:

Potrebno je napisati stored procedure bez parametara, koja ce se ponasati kao nagradna igra, dakle iz tabele NagradnaIgra ([ID], [BrojTelefona], [Code]) izvlaciti brojeve i napraviti tako da jedan broj ne moze biti izvucen vise puta.

Cini mi se da ce ovo biti malo tezi zahtev od predhodnog, pa ako neko ima ideju, pomoc bi mi dobro dosla :)

Unapred hvala!
 
Odgovor na temu

Zidar
Canada

Član broj: 15387
Poruke: 3085
*.100.46-69.q9.net.



+79 Profil

icon Re: Pomoc oko sql upita12.07.2011. u 16:45 - pre 155 meseci
Zasto bi bilo teze?


Ovaj SELECt izvlaci 5 slucajnig brojeva koji nisu ranije bili izvuceni:

[Code]
SELECT TOP 5
*
FROM NagradnaIgra
WHERE [Da li je izvucen] = 0
ORDER BY NewID()
[/code]

Kad se izvlacenje potvrdi, neko uradi UPDATE tako da se u sledecm krugi ti brojevi nece ponovo izvuci. WHERE komanda je cudo jedno


 
Odgovor na temu

bikazl

Član broj: 287637
Poruke: 7
95.180.36.*



Profil

icon Re: Pomoc oko sql upita12.07.2011. u 22:33 - pre 155 meseci
Da, ali je potrebno napraviti proceduru koja vraca povratnu vrednost izuceni broj i kada ponovo pokrenem proceduru, ne moze se pojaviti taj isti broj. Mozda treba koristiti indekse?
A bojim se da mi nije bas najjasnije ovo sa UPDATE? :-)
 
Odgovor na temu

Zidar
Canada

Član broj: 15387
Poruke: 3085
*.100.46-69.q9.net.



+79 Profil

icon Re: Pomoc oko sql upita13.07.2011. u 15:01 - pre 155 meseci
Mislim da ne razumes kako generalno stored procedure rade. Proceduru kreiras ovako:
Code:

CREATE PROCEDURE uspIzvuciBroj 
AS
SELECT TOP 5
*
FROM NagradnaIgra 
WHERE [Da li je izvucen] = 0
ORDER BY NewID()
GO

Kad je pozoves, to radis ovako:
Code:

EXECUTE uspIzvuciBroj 

Kao rezultat, vidis ceo red, za onaj broj koji je izvucen. Mozes i da upotrebis output parametre, ali je nepotrebno komplikovano. To mozes da probas sam, ocekuej se da neke stvari znas, ako si postavio ovo pitanje. Sintaksu kreiranja i pozivanja procedure moras da naucis iz knjiga, ja ti samo pomazem oko logike.

UPDATE problem
----------------
Kad si jednom izvukao broj (koji ti je vratila procedura uspIzvuciBroj , uz neke druge kolone) nekako treba da kazes bai podataka da je taj broj izvucen. To radis atko sto u tabeli [NagradnaIgra] postavis vrednost [Da li je izvucen] da bude = 1, bas za ovaj broj koji si upravo izvukao. To moze da radi neka druga procedura, a moze da se strpa i u uspIzvuciBroj. kako god d auradis, posto je broj oznacen sa [Da li je izvucen] = 1, procedura uspIzvuciBroj vise taj broj nece videti i nikad ga nece moci izvuci. WHERE [Da li je izvucen] = 0 znci 'uzmi samo brojeve koji nikad nisu izvuceni' ORDER BY NewID() poredja te brojeve po slucajnom redosledu, a SELECT TOP 5 pokaze prvih 5 brojeva, koji ce biti 5 slucajnih brojeva. Ako izvlacis jedan broj, onda uzmes TOP 1.

Medjutim, ne znam tacno sta predstavlja 'Broj koji izvlacis'. je li ti telefonski broj ili neki ID, na znam koja kolona iz tabele NagradnaIgra predstavlja broj koji se izvlaci. Ako je u pitanju telefonski broj, koji dozvoljavas da bude vise puta u tabeli, onda se SELECT TOP 5.. izraz komplikuje. Necu da komplikujem sad, mozda je ovo i nebitno.

Bilo bi korisno d apostavis skritu za tabelu sa kojom radimo i nekoliko test podataka, takvih da predstavljaju tipican slucaj. Ako su dopusteni duplikati negde, neka ih bude i u test podacima. Tada bismo mogli da zaista napisemo sve stored procedure i operacije koje treba izvrsiti, bilo bi jasnije.


:-)
 
Odgovor na temu

bikazl

Član broj: 287637
Poruke: 7
95.180.36.*



Profil

icon Re: Pomoc oko sql upita14.07.2011. u 08:29 - pre 155 meseci
Predpostavimo da je u pitanju sledeca tabela, dakle imamo brojeve, od kojih se neki ponavaljaju i neka za pocetak ni jedan nije izvucen:


| ID | BrojTelefona | DaLiJeIzvucen |
-------------------------------------------------------------
| 1 | 064/111111 |0 |
-------------------------------------------------------------
| 2 | 064/111111 | 0 |
-------------------------------------------------------------
| 3 | 064/222222 | 0 |
-------------------------------------------------------------
| 4 | 065/333333 | 0 |
-------------------------------------------------------------
| 5 | 065/333333 |0 |
-------------------------------------------------------------
| 6 | 065/444444 | 0 |
-------------------------------------------------------------
| 7 | 065/555555 | 0 |
-------------------------------------------------------------
| 8 | 065/666666 | 0 |
-------------------------------------------------------------
| 9 | 065/777777 | 0 |
-------------------------------------------------------------
| 10 | 065/777777 | 0 |
-------------------------------------------------------------
| 11 | 065/888888 |0 |
-------------------------------------------------------------

Dalje cemo napisati stored procedure koja ce nam izvuci jedan nasumicno izabran broj iz date tabele, to koliko sam razumela mozemo odraditi pomocu SELECT:

CREATE PROCEDURE uspIzvuciBroj
AS
SELECT TOP 1
*
FROM NagradnaIgra
WHERE [Da li je izvucen] = 0
ORDER BY NewID()
GO


E sad dalje treba mozda ovaj broj koji smo izvukli nekako oznaciti i preko UPDATE staviti kolonu DaLiJeIzvucen = 1, nesto ovako

UPDATE NagradnaIgra
SET DaLiJeIzvucen = 1

Sada treba napraviti da se taj broj vise ne izvlaci, posto se mozda ponavalja u tabeli pa imamo da mu je na jednom mestu vrednost za kolonu DaLiJeIzvucen 0 a na drugom mestu 1.

Ovde me interesuje kako ovo povezati, posto prvi put koristim stored procedure. A mozda sam na pogresnom putu. Bilo kako bilo, nadam se da sam napukom postavila pravo pitanje sa konkretnim podacima.

Hvala jos jednom :-)

 
Odgovor na temu

sule99
student

Član broj: 227708
Poruke: 93
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Pomoc oko sql upita14.07.2011. u 14:22 - pre 155 meseci
Ako trebaš UPDATE u svim zapisima gdje se pojavljuje izvučeni BrojTelefona, onda koristiš ovo

Code:

CREATE PROCEDURE uspIzvuciBroj 
AS

CREATE TABLE #TEMP
([ID] [int] NOT NULL,
[BrojTelefona] [varchar](20) NULL,
[DaLiJeIzvucen] [bit] NULL)

INSERT INTO #TEMP
SELECT TOP 1
*
FROM NagradnaIgra  
WHERE [Dalijeizvucen] = 0
ORDER BY NewID()


SELECT BrojTelefona FROM #TEMP

UPDATE NagradnaIgra  SET DaLiJeIzvucen = 1 
WHERE BrojTelefona in
(SELECT BrojTelefona FROM #TEMP )

DROP TABLE #TEMP



Ako trebaš UPDATE samo na ID-ju koji je izvučen onda koristiš ovo

Code:

CREATE PROCEDURE uspIzvuciBroj 
AS

CREATE TABLE #TEMP
([ID] [int] NOT NULL,
[BrojTelefona] [varchar](20) NULL,
[DaLiJeIzvucen] [bit] NULL)

INSERT INTO #TEMP
SELECT TOP 1
*
FROM NagradnaIgra  
WHERE [Dalijeizvucen] = 0
ORDER BY NewID()


SELECT BrojTelefona FROM #TEMP

UPDATE NagradnaIgra  SET DaLiJeIzvucen = 1 
WHERE ID in
(SELECT ID FROM #TEMP )

DROP TABLE #TEMP
 



Naravno ako trebaš 5 brojeva onda napraviš samo zamjenu i staviš TOP 5 umjesto TOP 1 i opet sve radi

Nadam se da sam te dobro razumio ;)
 
Odgovor na temu

Zidar
Canada

Član broj: 15387
Poruke: 3085
*.100.46-69.q9.net.



+79 Profil

icon Re: Pomoc oko sql upita14.07.2011. u 14:41 - pre 155 meseci
Sad je malo jasnije. Kazes 'izvlacim o brojeve". Broj - mislis na BrojTelefona. Moras prcizno da kazes sta se izvlaci. "Broj" moze da znaci i "ID". OK, izvlacis Brojtelefona. Kad izvuces broj telefona (koji se moze ponavlajti) zelsi da se taj broj telefona ne moze izvuci ponovo.

Kada nam dajes primer podataka, bolje da das CREATE TABLE naredbu, tako da vidimo sta je sta, tipovi podataka, ogranicenja i slicno. Onda nam das nekoliko INSERT INTO naredbi, da bismo mogli na nasoj strani da napravimo tabelu bas onakvu kakvu ti imas, sa podacima koji dovoljno verno predstavljaju ono sto se zeli uraditi. Tek onda mozemo da pisemo kod. Sve dotle - sve je samo pseudo kod, kao neka gruba skica.
Code:

CREATE PROCEDURE uspIzvuciBroj 
AS
-- treba nam varijabla da pocitamo telefon
DECLARE @IzvuceniBrojTelefona varchar

-- ovde procitamo izvuceni broj
 @IzvuceniBrojTelefona = (SELECT TOP 1
BrojTelefona
FROM NagradnaIgra 
WHERE [Da li je izvucen] = 0  -- ovo garantuje da ce se izvlaciti samo iz skupa onih koji prethodno nisu bili izvuceni
ORDER BY NewID()
)

-- sad sve rekorde koji imaju taj broj telefona oznacimo da su izvuceni
UPDATE NagradnaIgra 
SET  [Da li je izvucen] = 0
 [Da li je izvucen] = 1
WHERE BrojTelefona = @IzvuceniBrojTelefona 

- na kraju, pokazemo koji je broj izvucen:
SELECT IzvueniBroj = @IzvuceniBrojTelefona 

GO


:-)
 
Odgovor na temu

bikazl

Član broj: 287637
Poruke: 7
*.static.isp.telekom.rs.



Profil

icon Re: Pomoc oko sql upita22.07.2011. u 01:51 - pre 155 meseci
Hvala puno na pomoci :)
Zaista mi je dobro dosla
 
Odgovor na temu

[es] :: MS SQL :: Pomoc oko sql upita

[ Pregleda: 1728 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.