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.
Sad šta je tu je. A možda će da dođe i ova tvoja tetka iz Bosanske Krupe.