[ dzigi753 @ 24.05.2005. 10:43 ] @
cao

izgleda OK ovaj kod,ali kad probam da ga izvrsim ispisuje mi "null" ...stored procedura izgleda ovako :

CREATE PROCEDURE sp_pera
@myInput varchar
AS
SELECT SUM(CustFinTrxnLoyalPoints)
FROM CUSTOMERFINTRANSACTIONS
Where CustAccCardNum = @myInput
GO

CustAccCardNum je varchar u tabeli
CustFinTrxnLoyalPoints je float

unapred hvala
[ Simke @ 24.05.2005. 11:21 ] @
Nije nista pogresno, NULL ce ti vratiti ako ne nadje nista za
Where CustAccCardNum = @myInput
[ dzigi753 @ 24.05.2005. 11:24 ] @
pa nece biti....imam masu brojeva i za sve mi vraca NULL...
izgleda sasavo ali ne radi
[ dzigi753 @ 24.05.2005. 12:01 ] @
ok
odgovor je :uz promenljivu obavezno mora da stoji i velicina(length)
pa bi kod izgledao ovako:

CREATE PROCEDURE sp_pera
@myInput varchar(32)
AS
SELECT SUM(CustFinTrxnLoyalPoints)
FROM CUSTOMERFINTRANSACTIONS
Where CustAccCardNum = @myInput
GO


e naucih nesto danas...
[ joxa83 @ 30.05.2006. 16:23 ] @
ako bilo koji zapis sadzi null sum ce biti null.
npr:select null+1+2 isto je iz agregatnu funkciju sum
[ Fedya @ 30.05.2006. 16:35 ] @
Imas metod ISNULL koji ce resiti taj problem

Znaci
SELECT SUM(ISNULL(CustFinTrxnLoyalPoints, 0))
[ rooler @ 29.11.2012. 17:59 ] @
Pozdrav svima,
moj proble kod stored procedure je taj da mi javlja sledeću grešku


"Msg 4902, Level 16, State 1, Procedure menjam_tip, Line 7
Cannot find the object "@ime_tabele" because it does not exist or you do not have permissions."

procedura radi ovako:

reate procedure menjam_tip
@ime_tabele varchar(30),
@ime_kolone varchar(30),
@tip_podatka varchar(30)
as
begin
alter table [@ime_tabele]
alter column [@ime_kolone] [@tip_podatka] commit
end

ako ima pomoći pomagajte.
[ Zidar @ 30.11.2012. 16:34 ] @
[quote]ako ima pomoći pomagajte.[\quote]
Nema ti pomoci. ALTER TABLE i ALTER COLUMN ne priznaju parametre.
[ adzo_ @ 01.12.2012. 09:57 ] @
Postoji resenje tvog problema
Treba da se upoznas sa dinamickim izvrsavanjem SQL procedura, narocito sa "sp_executesql"

Trebalo bi da dalje mozes sam...
[ HladankaoLed @ 01.12.2012. 11:41 ] @
Citat:
joxa83:
ako bilo koji zapis sadzi null sum ce biti null.
npr:select null+1+2 isto je iz agregatnu funkciju sum


Nece. Agregatne funkcije ignorisu NULL vrednosti. SUM(val) ekvivalentno je SUM(ISNULL(val,0)).
Obicna aritmeticka operacija vraca NULL ako je barem jedan operand NULL. SELECT NULL + 1 + 2 vratice NULL.
[ HladankaoLed @ 01.12.2012. 11:48 ] @
Citat:
dzigi753:
ok
odgovor je :uz promenljivu obavezno mora da stoji i velicina(length)
pa bi kod izgledao ovako:

CREATE PROCEDURE sp_pera
@myInput varchar(32)
AS
SELECT SUM(CustFinTrxnLoyalPoints)
FROM CUSTOMERFINTRANSACTIONS
Where CustAccCardNum = @myInput
GO


e naucih nesto danas...



Ovo je tacan odgovor. Ukoliko se prilikom definicije parametra ne navede velicina podrazumevana velicina je 1. To je razlog sto SP vraca NULL. Za tip i velicinu parametra treba navesti tip i velicinu kolone CustAccCardNum.

Ilustracija problema inicijalizacije tekstualnih promenljivih bez navodjenja duzine:

DECLARE @n VARCHAR = 'abc'
SELECT @n

Rezultat:
----
a

Ali, u slucaju konverzije podrazumevana vrednost je 30:

DECLARE @n DATETIME = GETDATE()
SELECT CAST(SYSDATETIME() AS VARCHAR)
GO
DECLARE @n NVARCHAR(2000) = '0123456789012345678901234567890' --31
SELECT CAST(@n AS VARCHAR) -- poslednja nula je eliminisana jer je predsavljala 31. karakter

Rezultat:
------------------------------
2012-12-01 12:46:39.7474518


------------------------------
012345678901234567890123456789


[ rooler @ 01.12.2012. 15:44 ] @
Citat:
adzo_:
Postoji resenje tvog problema
Treba da se upoznas sa dinamickim izvrsavanjem SQL procedura, narocito sa "sp_executesql"

Trebalo bi da dalje mozes sam...


OK dalje ću sam da šljakam
[ HladankaoLed @ 02.12.2012. 13:42 ] @
Citat:
rooler:
Pozdrav svima,
moj proble kod stored procedure je taj da mi javlja sledeću grešku


"Msg 4902, Level 16, State 1, Procedure menjam_tip, Line 7
Cannot find the object "@ime_tabele" because it does not exist or you do not have permissions."

procedura radi ovako:

reate procedure menjam_tip
@ime_tabele varchar(30),
@ime_kolone varchar(30),
@tip_podatka varchar(30)
as
begin
alter table [@ime_tabele]
alter column [@ime_kolone] [@tip_podatka] commit
end

ako ima pomoći pomagajte.


Generalno u stored procedure se ne pakuju komande koje menjaju strukturu baze podataka (dodavanje ili eliminsanje tabela i kolona, promena tipa podataka i sl.). U tu svrhu koristi se batch skript koji se izvrsava zajedno sa instalacijom verzije aplikacije. Znaci, prva sugestija je da se ova akcija preusmeri na batch skript umesto u stored proceduru.

Dalje, kod stored procedura imena database objekata ne mogu se koristiti kao parametri. Znaci ime tabele, kolone ili funkcije ne moze da bude argument jedne staticke SP. Kao sto rece Zidar, tu pomoci nema - SQL Server database engine ne podrzava imena objekata kao parametre.

Ako uprkos svemu moras da koristis SP i objekte kao argumente, onda, opet kao sto kolega rece, moras da koristis tzv. dinamicki SQL. U konkretnom slucaju to znaci da se SQL komanda dinamicki generise pomocu tekstualnih parametara kao obican string i kasnije, specijalnom komandom (ili sistemskom stored procedurom) tako generisani string dinamicki izvrsi.

Dinamicki SQL je veoma fleksibilan, po pravilu veoma performantan, ali pre svega toga opasan zbog mogucnosti SQL injection napada. Detalje o SQL Injection mozes da nadjes po webu. Ja ti dostavljam ovde jedno resenje koje je zasticeno od napada, vise kao demonstraciju jedne dinamicke SP nego kao putokaz za resenje tvog problema. Jos jednom, ALTER komandu treba da izbacis iz stored procedure i prebacis je u deploymnet skript.
A evo dinamicke SP:
Code:

IF OBJECT_ID('dbo.menjam_tip','P') IS NOT NULL DROP PROCEDURE dbo.menjam_tip
GO
CREATE PROCEDURE dbo.menjam_tip
@ime_tabele varchar(30),
@ime_kolone varchar(30),
@tip_podatka varchar(30)
AS
BEGIN
IF EXISTS(SELECT * FROM sys.tables WHERE name =@ime_tabele)
BEGIN
    IF EXISTS(SELECT * FROM sys.columns WHERE name =@ime_kolone AND object_id=OBJECT_ID(@ime_tabele))
    BEGIN
        IF EXISTS(SELECT * FROM sys.types WHERE name =LTRIM(RTRIM(LEFT(@tip_podatka,CHARINDEX('(',@tip_podatka)-1))))
        BEGIN
            DECLARE @sql NVARCHAR(2000);
            SET @sql = N'ALTER TABLE ' + CAST(@ime_tabele AS NVARCHAR(30));
            SET @sql+= N' ALTER COLUMN ' + CAST(@ime_kolone AS NVARCHAR(30));
            SET @sql+= N' ' + CAST(@tip_podatka AS NVARCHAR(30));
            EXEC (@sql);
        END
        ELSE
        BEGIN  
            RAISERROR ('SQL Server ne podrzava tip podataka sa navedenim imenom.',16,1);
        END
    END
    ELSE
    BEGIN  
        RAISERROR ('Kolona sa takvim imenom ne postoji u datoj tabeli.',16,1);
    END    
END 
ELSE
BEGIN  
    RAISERROR ('Tabela sa takvim imenom ne postoji.',16,1);
END
END


Ovi silni IF-ovi su tu da se user input poredi sa listom postojecih tabela, kolona i tipova (tzv. white list approach) kako bi se svi pokusaji manipulacije i injekcije elegantno i sigurno izbegli. Izostanak IF-ova iz procedure ulepsao bi dan nekom hakeru ili programu koji po bespucima weba traga za rupama u aplikacijama pogodnim za eksploataciju.

[ rooler @ 17.12.2012. 10:47 ] @
Citat:
HladankaoLed: Generalno u stored procedure se ne pakuju komande koje menjaju strukturu baze podataka (dodavanje ili eliminsanje tabela i kolona, promena tipa podataka i sl.). U tu svrhu koristi se batch skript koji se izvrsava zajedno sa instalacijom verzije aplikacije. Znaci, prva sugestija je da se ova akcija preusmeri na batch skript umesto u stored proceduru.

Dalje, kod stored procedura imena database objekata ne mogu se koristiti kao parametri. Znaci ime tabele, kolone ili funkcije ne moze da bude argument jedne staticke SP. Kao sto rece Zidar, tu pomoci nema - SQL Server database engine ne podrzava imena objekata kao parametre.

Ako uprkos svemu moras da koristis SP i objekte kao argumente, onda, opet kao sto kolega rece, moras da koristis tzv. dinamicki SQL. U konkretnom slucaju to znaci da se SQL komanda dinamicki generise pomocu tekstualnih parametara kao obican string i kasnije, specijalnom komandom (ili sistemskom stored procedurom) tako generisani string dinamicki izvrsi.

Dinamicki SQL je veoma fleksibilan, po pravilu veoma performantan, ali pre svega toga opasan zbog mogucnosti SQL injection napada. Detalje o SQL Injection mozes da nadjes po webu. Ja ti dostavljam ovde jedno resenje koje je zasticeno od napada, vise kao demonstraciju jedne dinamicke SP nego kao putokaz za resenje tvog problema. Jos jednom, ALTER komandu treba da izbacis iz stored procedure i prebacis je u deploymnet skript.
A evo dinamicke SP:
Code:

IF OBJECT_ID('dbo.menjam_tip','P') IS NOT NULL DROP PROCEDURE dbo.menjam_tip
GO
CREATE PROCEDURE dbo.menjam_tip
@ime_tabele varchar(30),
@ime_kolone varchar(30),
@tip_podatka varchar(30)
AS
BEGIN
IF EXISTS(SELECT * FROM sys.tables WHERE name =@ime_tabele)
BEGIN
IF EXISTS(SELECT * FROM sys.columns WHERE name =@ime_kolone AND object_id=OBJECT_ID(@ime_tabele))
BEGIN
IF EXISTS(SELECT * FROM sys.types WHERE name =LTRIM(RTRIM(LEFT(@tip_podatka,CHARINDEX('(',@tip_podatka)-1))))
BEGIN
DECLARE @sql NVARCHAR(2000);
SET @sql = N'ALTER TABLE ' + CAST(@ime_tabele AS NVARCHAR(30));
SET @sql+= N' ALTER COLUMN ' + CAST(@ime_kolone AS NVARCHAR(30));
SET @sql+= N' ' + CAST(@tip_podatka AS NVARCHAR(30));
EXEC (@sql);
END
ELSE
BEGIN  
RAISERROR ('SQL Server ne podrzava tip podataka sa navedenim imenom.',16,1);
END
END
ELSE
BEGIN  
RAISERROR ('Kolona sa takvim imenom ne postoji u datoj tabeli.',16,1);
END
END 
ELSE
BEGIN  
RAISERROR ('Tabela sa takvim imenom ne postoji.',16,1);
END
END


Ovi silni IF-ovi su tu da se user input poredi sa listom postojecih tabela, kolona i tipova (tzv. white list approach) kako bi se svi pokusaji manipulacije i injekcije elegantno i sigurno izbegli. Izostanak IF-ova iz procedure ulepsao bi dan nekom hakeru ili programu koji po bespucima weba traga za rupama u aplikacijama pogodnim za eksploataciju.




OK hvala na opširnom odgovoru, možda nekakav link sa batch skriptom.
[ rooler @ 17.12.2012. 10:52 ] @
Narode kad smo već tu,
na koji način da postavim trigger koji će mi nakon unosa podatka u jednu tabelu u nekoj drugoj
da pravi npr sum dodanih elemenata?
npr.:
tbl1 ----------------------tbl2
_________________________
imena----------------------brojac
_________________________
mitar mirić _________________2
hanka paldum

i da li je tako nešto moguće.
predpostavljam da tabele treba da su uvezane sa pk i fk
[ plague @ 17.12.2012. 11:31 ] @
Suma kakvih dodatnih elementa?

Ovo ti je forma triggera:
Code:

CREATE TRIGGER Okidac ON tbl1 
    AFTER INSERT
AS 
/*kod*/
GO


Ako hoces da ti konkretno pomognemo, opisi bolje sta ti zapravo treba.
[ rooler @ 17.12.2012. 13:15 ] @
Citat:
plague: Suma kakvih dodatnih elementa?

Ovo ti je forma triggera:
Code:

CREATE TRIGGER Okidac ON tbl1 
AFTER INSERT
AS 
/*kod*/
GO


Ako hoces da ti konkretno pomognemo, opisi bolje sta ti zapravo treba.
Citat:
plague: Suma kakvih dodatnih elementa?


ovako:ako ja unesem podatak u tbl1, želeo bih da mi u tbl2 radi 'count' elemenata iz tbl1.

Recimo da mi je tbl2 nekakva statistička tabela, naravno tbl2 se neće sastojati od jedne kolone
[ rooler @ 17.12.2012. 13:30 ] @
Citat:
rooler: ovako:ako ja unesem podatak u tbl1, želeo bih da mi u tbl2 radi 'count' elemenata iz tbl1.

Recimo da mi je tbl2 nekakva statistička tabela, naravno tbl2 se neće sastojati od jedne kolone
[quote]

ok Hvala plague!!!
moj sad izgleda ovako:
CREATE TRIGGER Okidac ON tbl1
AFTER INSERT
AS
/*kod*/
insert into tbl2(broj)
select COUNT(ime)from tbl1
GO
_______________________
Da li bi mogao da konstruišem ovaj triger sa nekakvom
dinamičkom vrednošću:
npr
CREATE TRIGGER Okidac ON @tbl1
AFTER INSERT
AS
/*kod*/
insert into @tbl2(@broj)
select COUNT(@ime)from @tbl1
GO
[ plague @ 17.12.2012. 13:38 ] @
Razumem da hoces count, ali count cega? Po kom kriterijumu?

Kazes da su tbl1 i tbl2 vezane PK/FK, to bi znacilo da tbl2 sadrzi informaciju o konkretnom zapisu iz tbl1, ne znam kakav count tu mozes da uradis?

Npr zamislimo da je tbl1 = SaleOrders, a da je tbl2 neki coutner za tu tabelu. Ako hoces da prebrojis porudzbine za nekog Usera, tbl2 treba biti vezana za Users tabelu, a ne za SalesOrder.

Ovo tvoje ima smisla jedino ako postoji jos neka tabela npr SaleOrderItems vezana za SaleOrders, pa tada da brojis te SalesOrderItems koji su vezani za SaleOrders a dalje je tbl2 vezana za SalesOrderID, mada bi i tada mogao to da uradis bez dodatne tabele. Osim ako ne postoji neka zavrzlama koju ne mogu da prepoznam za sta se izvinjavam. Do tada moje pitanje je: Sta zapravo brojis?

I sta znaci staticka tabela? Mislis na tabele koje se veoma retko menjaju?

Citat:
rooler: ovako:ako ja unesem podatak u tbl1, želeo bih da mi u tbl2 radi 'count' elemenata iz tbl1.

Kada bi ovo uradio imao bi gomilu zapisa u tbl2 gde bi kolona "brojac" zapravo bila nesto sto podseca na "redni broj" zapisa iz tbl1. Da li ti to treba?


Edit:
Mislim da ne shvatas triggere. Oni se vezuju za tabelu ili bazu i predstavljaju evente koji se izvrsavaju kada se nesto dogodi. Oni postoje "snimljeni" i "zakaceni", kao sto ti postoji stored procedure, samo sto se izvrsavaju automatski(bez bilo kakvog manuelnog pozivanja) nakon nekog dogadjaja.
[ rooler @ 17.12.2012. 14:02 ] @
Citat:
plague: Razumem da hoces count, ali count cega? Po kom kriterijumu?

Kazes da su tbl1 i tbl2 vezane PK/FK, to bi znacilo da tbl2 sadrzi informaciju o konkretnom zapisu iz tbl1, ne znam kakav count tu mozes da uradis?

Npr zamislimo da je tbl1 = SaleOrders, a da je tbl2 neki coutner za tu tabelu. Ako hoces da prebrojis porudzbine za nekog Usera, tbl2 treba biti vezana za Users tabelu, a ne za SalesOrder.

Ovo tvoje ima smisla jedino ako postoji jos neka tabela npr SaleOrderItems vezana za SaleOrders, pa tada da brojis te SalesOrderItems koji su vezani za SaleOrders a dalje je tbl2 vezana za SalesOrderID, mada bi i tada mogao to da uradis bez dodatne tabele. Osim ako ne postoji neka zavrzlama koju ne mogu da prepoznam za sta se izvinjavam. Do tada moje pitanje ........

Da, uvideo sam nedostatak mog koda, on mi pravi niz elemenata uvećanih za +1, pa sam razmišljao o uslovu 'where'
međutim, pada mi na pamet where broj=values (broj) što nije tačno

Ovaj triger mi je bio testni triger, ono što bi meni trebalo kasnije(slično tvom primeru) je sledeće:
Možda sam na krivom putu, htio sam da mi triger odrađuje nekakve operacije, npr. ako u tbl1 unesem u polje1 i polje2 određenu vrednost, u tbl2 da mi pomnoži ili odradi nekakvu drugu matematičku operaciju sa zadanim poljima iz tbl1.
zato sam razmišljao o promenjivim vrednostima
[ plague @ 17.12.2012. 14:15 ] @
Ne vidim koji je cilj neceg takvog ali jeste moguce. Po meni je to bolje uraditi na nivou klase.

Code:

CREATE TRIGGER Okidac 
   ON  tbl1
   AFTER INSERT
AS 
    SET NOCOUNT ON;
    INSERT INTO tbl2 (tbl1FK, RezultatOperacije) VALUES(inserted.tbl1PK, inserted.Vrednost1 * inserted.Vrednost2);
GO

inserted predstavlja record koji je upravo unet i njemu uvek imas pristup u ovom tipu triggera.
[ rooler @ 17.12.2012. 14:46 ] @
Citat:
plague: Ne vidim koji je cilj neceg takvog ali jeste moguce. Po meni je to bolje uraditi na nivou klase.

Code:

CREATE TRIGGER Okidac 
   ON  tbl1
   AFTER INSERT
AS 
SET NOCOUNT ON;
INSERT INTO tbl2 (tbl1FK, RezultatOperacije) VALUES(inserted.tbl1PK, inserted.Vrednost1 * inserted.Vrednost2);
GO

inserted predstavlja record koji je upravo unet i njemu uvek imas pristup u ovom tipu triggera.

ma ne pitaj, neke stvari ne možeš objasniti nekim ljudima tek tako, no pogledaj na koji način sam rešio onu prethodnu problematiku:
CREATE TRIGGER Okidac1 ON tbl1
AFTER INSERT
AS


update tbl2
set broj=
(select COUNT(ime)

from tbl1)
update tbl2
set broj=(delete tbl2 where rb>1 )
GO

dodao sam samo rb koji je identity 1,1

ne ovo ipak nije pravi kod, hahah radi mi triger ekstra dobro ali sam ga nema
kako sada da vidim kod svog trigera.
select * from sys.triggers
mi samo ispisuje koji triger posedujem.
please help

[Ovu poruku je menjao rooler dana 17.12.2012. u 15:58 GMT+1]
[ rooler @ 17.12.2012. 15:03 ] @
update tbl2
set broj=
(select COUNT(ime)

from tbl1)
delete tbl2 where rb>1
ovako je ipak u redu.

anyway Hvala plauge za kod-ove,
[ plague @ 17.12.2012. 15:07 ] @
Hm, nisam siguran da mogu da se vide tek tako (bar ja ne znam), nego moras da ides Tast > Generate Scipts pa da izaberese triggere i onda ces imati zajedno sa ostalim kodovima. Moja preporuka ti je da u triggeru pozivas stored procedure koji posle mozes da menjas veoma lako (mada tu ces se malo muciti da prosledis inserted) ili makar da sacuvas tu skriptu koja je napravila trigger, pa da kada hoces da menjas prvo ides drop postojeces pa create ponovo. Mozda moze i alter nisam siguran.

Edit: Totalno sam zaboravio da imas kada expandujes tabelu folder Triggers. Lol