[mssql]funkcja, Insert, ststystki

0

Witam,

Chciałbym zrobić zliczanie punktow z jednej tabeli i podzilić to na grupy z predzialami punktowymi i wyniki wrzucic do innej tabeli. Napisałem coś takiego ale nie działa. Pytanie dlaczego, i jak to poprawić aby działało. Z gory dzięki

create function statystyki
(
	@trzy int,
	@szesc int,
	@reszta int
)
RETURNS int
as


begin

declare 
	
	@cos int,
	@kursor Cursor,
	@punkty int
	
	set @cos = 1
	set @trzy =0 
	set @szesc =0
	set @reszta = 0
	set @kursor = cursor for(Select Points from tblUser)
	
open @kursor
Fetch next from @kursor into @punkty

while(@@Fetch_status =0)

begin

	if(@punkty<3)
			set @trzy = @trzy+1
	else if ((@punkty>2)and(@punkty<7))
			set @szesc= @szesc +1
	else
			set @reszta= @reszta+1
	
	fetch next from @kursor into @punkty

end

  insert into staty(do3,od3do6,od7do10) values (@trzy, @szesc,@reszta)
  return 1

end
</email>
1

A takie cos nie lepiej?

select count(*) from tblUser where Points < 3;
select count(*) from tblUser where Points between 3 and 6;
select count(*) from tblUser where Points > 6;
0

Msg 444, Level 126, State 2, Procedure statystyki, Line 124
Select statements included within a function cannot return data to a client

A wolge wrzucić potem wynik zapytania do zmiennej

set @zmienna = zapytanie ?

0

select @zmienna = count(*) ...

A blad wkleiles, bo?

0

Skoro juz funkcja mi sie skompilowala ma jeden parametr @ile varchar(20) to ja to wywołać ?
Bo jak piszę
execute nazwa('cos') to twierdzi ze Incorrect syntax near 'cos'.

Jak to poprawnie wywołać , Zwracam zmienna typu varchar(20) w ktorej jest napis jakiś ;]
</email>

0

Ech..., co to bedzie, jak google upadnie [glowa]

select user.fun('param1')

0

tak też robilem ale niestesty dostałem bład

Msg 557, Level 16, State 2, Line 1
Only functions and extended stored procedures can be executed from within a function.

co z tym mozna zrobic ?

0

Co wlasciwie starasz sie zrobic z ta funkcja? Bo mam wrazenie, ze nie widze calego obrazu sytuacji.

0

oto kod:


create function lol2
(
	@ile nvarchar(20)
)
RETURNS varchar(20) 
as
begin
	declare @trzy int
 	declare @szesc int
	declare @reszta int
	declare @napis nvarchar(20) 
	set @napis = 'costam'
	DECLARE @query nvarchar(4000)


	SELECT @trzy= count(*) FROM tblUser WHERE Points < 3;
	SELECT @szesc= count(*) FROM tblUser WHERE Points BETWEEN 3 AND 6;
	SELECT @reszta = count(*) FROM tblUser WHERE Points > 6;
	

	SET @query ='Insert into staty(od3,od3do6,od7do10) values(@trzy,@szesc,@reszta)';
	exec sp_executesql @query

return @napis

end

to ma zliczac mi ile jest teamtow ponizej 3 pkt ile od 3 do 7 i tak dalej ... i wrzucac do innej tabeli te dane
oto co ;]
sory ale dopiero ucze sie ssql i mam pewne braki jeszcze takze sorki za swoj laicyzm w temacie

0

Ekhem... Skad pomysl na budowanie dynamicznego sqla, do tego zreszta niepoprawnie?

Wystarczy samo

Insert into staty(od3,od3do6,od7do10)  values(@trzy,@szesc,@reszta)
0

stąd pomysł że jak statycznie chcialem to wrzucić to dostawałem coś takiego

Msg 443, Level 16, State 15, Procedure lol2, Line 24
Invalid use of side-effecting or time-dependent operator in 'INSERT' within a function.

dlatego dynamicznie ... wrzucilem twoj kod ale dalej nie działa ;]

0

To zrob to jednym zapytaniem

insert into stat (val1, val2, val3)
select (select count(*) from users where points < 3) as range1, 
(select count(*) from users where points between 3 and 6) as range2,
(select count(*) from users where points > 6) as range3
0

dobra pomogło :) dzięki
mam jeszcz jeden problem a nie chce zakładać nowego topicu ... tutaj mam oto taką procedurkę ktorą sobie napisałem ... kompilowac sie kompiluje ale przy uruchomieniu się wali :(

Wg mnie nie moge fetchowa juz z pierwszego kursora.

W procedurce chodzi o to że. :
mam jedna tabelkę z ktorej pobieram login , a potem odwoluje się do tabeli o takiej samej nazwie jaka pobralem wczesniej i zliczam punkty jakie zarobila dana druzyna. nastepnie chce zuploadowac do tbluser.

Co tu może być źle.

create procedure problem
as

declare @cur CURSOR
declare @cur2 CURSOR
declare @username varchar
declare @point int
declare @punkty int
declare @numer int
declare @jest int
declare @curs int
declare @curs2 int

set @jest = 1

set @cur = CURSOR FOR (SELECT Login2 From tblUser)
open @cur

Fetch next from @cur into @username
set @curs = @@Fetch_status
while(@curs = 0)
begin

set @cur2 = cursor for (Select Soloved from @@Cursor_Rows.@cur.Login2)
set @punkty =0
open @cur2

set @point =0
fetch next from @cur2 into @point
set @curs2 = @@Fetch_status 

while(@curs2 =0)
begin

set @punkty = @punkty + @point 
fetch next from @cur2 into @point
set @curs2 = @@Fetch_status 
end

update dbo.tblUser set dbo.tblUser.Points= 2
Fetch next from @cur into @username
close @cur2
deallocate @cur2

end
close @cur
deallocate @cur
0

To jest chyba najbardziej zakrecony sposob na grupowanie danych jaki widzialem. Zalama, sorry. Zdajesz sobie sprawe, ze kursory to chyba najwolniejszy sposob przegladania danych w bazie?

To tez daloby sie zalatwic jednym zapytaniem, ALE CZEMU MASZ OSOBNE TABELE NA LOGINY????? Przeciez to samobojstwo!

Generalnie, gdyby byla jedna tabela z loginami to to wygladaloby tak:

update tlbUser users set points = (select sum(Soloved) from loginData ld where ld.login = users.login)

W powyzszym kodzie poza tym jest blad, bo updateujesz wszystkie punkty na 2.

0

jest jedna tabela z loginami :)
tyle ze ... w tbluser sa loginy userow hasla suma pkt itak dalej i tak dalej ...
przy tworzeniu usera tworze mu tabele z jego kartoteka. w ktorej sa odnotowane jego osiagniecia . tabela ma nazwe taka sama jak login.
dlateego biore dane z 1 tabeli odczytujac login aby odowlac sie do tabeli o takiej samej nazwie.

Potem w tych aktach ... muisze zsumowac pkt jakie zdobyl dany user i wrzucic do tabeli glownej tam gdzie sa loginy , hasla itp itd.. ;]

na tym to polega ;]

0

Ta tabela to tymczasowo czy na stale? Nie za duzo chyba tych userow, skoro to w ogole jakos jeszcze dziala... Daj sobie spokoj z tworzeniem osobnych tabeli na jednego uzytkownika, to paranoja. Struktura bazy powinna byc najbardziej sztywna jak to tylko mozliwe. To sie oczywiscie nie zawsze da w okresie np. paru lat, ale to powinny byc zmiany zwiazane ze zmiana funkcjonalnosci, a nie z zarejestrowaniem nowego uzytkownika. W zyciu tego nie utrzymasz pozniej.

0

Userow max 50. A nie mam czasu przenosic wszystkiego teraz.. w wakacje sie tym zajmnę teraz potrzebuje kilku reczy aby to troszke usprawnić ;)

masz jakis pomysl aby taka prostą procedurkę zrobić ?

0

To zrob dynamiczne zapytanie i podstaw nazwy loginu do tego co podalem wczesniej.

PS. Uprzedzam, ze prowizorki lubia sie dlugo trzymac, a to cos nie bedzie dzialac szybko i sprawnie. Zwlaszcza, jak bedziesz to łatał takimi procedurami z kursorami na lewo i prawo.

0

hmm chciałem to zrobić w ten sposób i cosik nie działa .. mam pytanie czy jak mam nazwe tabeli w jakieś zmiennej to jak mogę wykorzystać tą zmienna bo jak zrobiłem to tak jak na logikę być powinno to mam bład :(

ALTER procedure [dbo].[zlicz]
as
declare @ile int
declare @nazwa varchar(20)
declare @i int
declare @suma varchar(20)
DECLARE @query nvarchar(4000)
begin

	select @ile= count(*) from tblUser where ID != 0
	set @i= @ile
	
	while(@i>-1)
	begin
	select @nazwa = Login from tblUser where ID= @i
	
	UPDATE tblUser users SET Points = (SELECT sum(Soloved) FROM @nazwa ld WHERE @nazwa = users.Login)
	set @i = @i-1;
	end

end

Msg 156, Level 15, State 1, Procedure zlicz, Line 17
Incorrect syntax near the keyword 'select'.
Msg 1087, Level 15, State 2, Procedure zlicz, Line 17
Must declare the table variable "@nazwa".

0

Nie, musisz zrobic zapytanie dynamiczne:

set @query = 'UPDATE tblUser users SET Points = (SELECT sum(Soloved) FROM ' + @nazwa + ' ld WHERE ' + @nazwa+ ' = users.Login)'
exec(@query)

Wez pod uwage, ze moj update byl ogolny. Ten ustawi WSZYSTKIE wiersze na podana wartosc, wiec skonczysz na tym, ze bedziesz mial wszystkie punkty ustawione na wartosc ostatniego loginu. Czy na pewno o to Ci chodzilo?

0

Dobra , dzięki ;) w sumie próbowałem robić to dynamicznym ale pluł mi się o tego users przy wykonaniu już. Ale napisałem sobie coś podobnego i już działa mi wszystko elegancko.
Dzieki Za pomoc Jony ;)

Masz u mnie browarka ;]

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.