PDA

View Full Version : While AND Stored Procedure



mehdi58
جمعه 13 مرداد 1385, 18:49 عصر
سلام
فرض کنیم که یه SP داریم که نتیجه خروجی اون مثلا 5 تا فیلده .

CREATE PROCEDURE mysp
SELECT Field1 From Table1


حالا آیا این امکان وجود داره که داخل این SP یه حلقه While داشته باشیم که تا زمان خوندن هر فیلد , هر کدوم رو هم که خوند در یه جدول دیگه ذخیره کنه .
متشکرم

AminSobati
جمعه 13 مرداد 1385, 20:22 عصر
اگر قصد دارید خروجی sp رو جایی insert کنید:
insert mytable exec mysp

mehdi58
جمعه 13 مرداد 1385, 21:58 عصر
با عرض معذرت
ولی میشه یه کم بیشتر توضیح بدین
چون من توی SQL خیلی حرفه ای نیستم .

AminSobati
جمعه 13 مرداد 1385, 23:22 عصر
عزیزم چی رو توضیح بدم؟ دستور Insert کاملا واضحه، حاصل این sp وارد جدول مورد نظر میشه:
insert mytable exec mysp

explod_javad
جمعه 27 شهریور 1388, 11:46 صبح
اگر قصد دارید خروجی sp رو جایی insert کنید:
insert mytable exec mysp

امین خان اگه قصد insert نداشته باشیم چی؟
میشه راهنمایی کنید.؟
ممنون

AminSobati
جمعه 27 شهریور 1388, 23:43 عصر
امین خان اگه قصد insert نداشته باشیم چی؟
میشه راهنمایی کنید.؟
ممنون

دوست عزیزم دقیق تر توضیح بدین قصد انجام چه کاری رو دارید

explod_javad
شنبه 28 شهریور 1388, 05:05 صبح
امین خان سلام
من یک جدول دارم که ازش برای پیاده سازی Tree استفاده میشه.


ID
Name
ParentID
Sort

فیلد Sort که از نوع عددی هست و برای مرتب سازی و مکان قرار گرفتن زیر گروه متعلق به یک گروه خاص ،در Tree را مشخص می کند
حالا میخام که توی SP ، مرتب سازی و مکان قرارگیری را پیاده سازی کنم.
من برای این کار نخست فیلد Sort رکورد مورد نظر را برابر Row+0.5 قرار میدم( دستور Update) .سپس مجداد کوئری Select رو با Order by انجام میدم.حلا توی یک حلقه شرطی دوباره بر اساس متغیر شرط،فیلد Sort همه رکورد های متعلق به یک گروه خاص را برابر با متغییر حلقه شرطی Update میکنم.
Row+0.5 : این قسمت شماره ردیف مصد رو + 0.5 میکنم که موقع select مرتب سازی به صورتی انجام بشه که من میخام.
من زیاد به SP کار نکردم.ممنون میشم اگه روش بهتری به من معرفی کنید.

محمد سلیم آبادی
شنبه 28 شهریور 1388, 12:26 عصر
امین خان سلام
من یک جدول دارم که ازش برای پیاده سازی Tree استفاده میشه.


ID
Name
ParentID
Sort

فیلد Sort که از نوع عددی هست و برای مرتب سازی و مکان قرار گرفتن زیر گروه متعلق به یک گروه خاص ،در Tree را مشخص می کند.

سلام،
Navigation در یک درخت و مشخص کردن path هر node یک مبحث عمومی محسوب می شود، و روشی که برای ذخیره کردن tree استفاده کردید Adjacency List Model نام دارد. که روش هوشمند تر آن روش Nested Set می باشد که فردی به نام Joe CELKO روی آن مانور فراوانی داده است.
من دقیقا نمی دانم می خواهید چه کاری انجام دهید ولی اگر می خواهید مسیر هر گره و level هر گره را در درخت مشخص کنید یک مثالی آورده ام که می توانید استفاده کنید.
یک توضیح کوچکی هم بدهم برای طراحی الگوریتم های مربوط به درخت ما نیاز به مبحثی به نام recursion داریم و از هر ابزاری در SQL که ماهیت بازگشتی دارد از GOTO و WHILE گرفته تا SELF-JOIN و Recusive CTE و ... می توانیم استفاده کنیم!

البته شکی نیست که آقای امین ثباتی تنها فردی در این سایت/ایران خواهند بود که به شما می توانند کمک شایان توجهی کنند در صورتی که حد اقل همکاری را با ایشان داشته باشید!




--Originali Write And Post By Mohammad Salimabadi.

--Creating a tree and inserting some rows in it
--Adjacency List Model
create table tree
(
node char primary key,
parent char,
)
insert tree values ('a',null)
insert tree values ('b','a')
insert tree values ('c','a')
insert tree values ('d','b')
insert tree values ('e','b')
insert tree values ('f','c')


GO
--Calculating path of all node
CREATE FUNCTION [dbo].[Navigation](@node1 char)
RETURNS NVARCHAR(1000)
AS
BEGIN

DECLARE @parent char
DECLARE @node NVARCHAR(200)

SELECT @Parent = Parent, @node = node FROM tree WHERE node= @node1
IF @Parent is not null
SET @node = dbo.Navigation(@Parent)+'-->'+@node

RETURN @node
END

go

--Calculating level of any node
declare @a table (a char, b bit, l int)
insert into @a select 'a', 1, 1

declare @l int
select @l=l from @a

while @@rowcount>0
begin
set @l=@l+1
insert into @a
select node, 1, @l from tree where parent in (select a from @a where b=1)
update @a set b=0 where l=@l-1
end
---Select Statement
select a as node,
l as level,
[path]=dbo.navigation(node)
from @a a, tree t
where a.a=t.node;
/*
Result/Output
node level path
---- ----------- ----------------
a 1 a
b 2 a-->b
c 2 a-->c
d 3 a-->b-->d
e 3 a-->b-->e
f 3 a-->c-->f
*/
------------------------------------------------

explod_javad
شنبه 28 شهریور 1388, 17:41 عصر
دوست من از کدی که گذاشتی ممنون.
ولی من نمیخام موقع زدن کوئری ، این مرتب سازی انجام بشه.
میخام رکورد ها بر اساس فیلد ParentId و Sort مرتب بشن.
در حقیقت فیلد Sort باید Update بشه. میخام توی SP با گرفتن شماره رکورد موردنظر (ID) و ردیف جدید قرار گیری این زیر گروه در گروه خود ، جدول رو Update کنم.
حالا با این توضیحات راه حلی به نظرتون میرسه؟

AminSobati
یک شنبه 29 شهریور 1388, 17:50 عصر
سلام،
روش Nested Sets اگرچه یک ابتکار بسیار جالبه اما تنها مزیتش سرعت بالا در بدست آوردن زیر مجموعه های یک Node هست. در صورتیکه درخت بخواد ویرایش بشه، Updateهای پر دردسری روی فیلدهای Left و Right سایر رکوردها خواهد داشت. لذا توصیه نمیکنم.
و اما در مورد سوال اصلی، ای کاش نسخه SQL Server رو مشخص میکردین.
اگرچه کمی شک دارم که هنوز صورت مسئله رو دقیق درک کرده باشم، حدس میزنم در هر Level شما میخواین به فرزندانی که در اون Level هستند، شماره بدین، چیزی شبیه به Rank.
اگر حدس من درسته، شما میتونین یک پیمایش از بالاترین Node تا پایین ترین رو انجام بدین تا Level هر Node مشخص بشه، بعد با تابع ROW_NUMBER که از PARTITION BY Level استفاده میکنه، به هر Level از 1 تا n شماره بدین. از حاصل بدست آمده استفاده کنین تا جدول اصلی رو Update کنین

AminSobati
دوشنبه 30 شهریور 1388, 00:09 صبح
برای دیدن نتیجه درست این مثال، از Result to text به جای Result to grid استفاده کنید:




CREATE TABLE Employees
(
empid int NOT NULL,
mgrid int NULL,
empname varchar(25) NOT NULL,
salary money NOT NULL,
CONSTRAINT PK_Employees PRIMARY KEY(empid),
CONSTRAINT FK_Employees_mgrid_empid
FOREIGN KEY(mgrid)
REFERENCES Employees(empid)
)

CREATE INDEX idx_nci_mgrid ON Employees(mgrid)


INSERT INTO Employees VALUES(1 , NULL, 'Nancy' , $10000.00)
INSERT INTO Employees VALUES(2 , 1 , 'Andrew' , $5000.00)
INSERT INTO Employees VALUES(3 , 1 , 'Janet' , $5000.00)
INSERT INTO Employees VALUES(4 , 1 , 'Margaret', $5000.00)
INSERT INTO Employees VALUES(5 , 2 , 'Steven' , $2500.00)
INSERT INTO Employees VALUES(6 , 2 , 'Michael' , $2500.00)
INSERT INTO Employees VALUES(7 , 3 , 'Robert' , $2500.00)
INSERT INTO Employees VALUES(8 , 3 , 'Laura' , $2500.00)
INSERT INTO Employees VALUES(9 , 3 , 'Ann' , $2500.00)
INSERT INTO Employees VALUES(10, 4 , 'Ina' , $2500.00)
INSERT INTO Employees VALUES(11, 7 , 'David' , $2000.00)
INSERT INTO Employees VALUES(12, 7 , 'Ron' , $2000.00)
INSERT INTO Employees VALUES(13, 7 , 'Dan' , $2000.00)
INSERT INTO Employees VALUES(14, 11 , 'James' , $1500.00)

;WITH EmpCTE(empid, empname, mgrid, lvl, sortcol)
AS
(SELECT empid, empname, mgrid, 0,
CAST(empid AS VARBINARY(900))
FROM Employees
WHERE empid =1

UNION ALL

SELECT E.empid, E.empname, E.mgrid, M.lvl+1,
CAST(sortcol + CAST(E.empid AS BINARY(4)) AS VARBINARY(900))
FROM Employees AS E
JOIN EmpCTE AS M
ON E.mgrid =M.empid
)
SELECT
REPLICATE(' | ', lvl)
+ '(' + (CAST(empid AS VARCHAR(10))) + ') '
+ empname AS empname
FROM EmpCTE
ORDER BY sortcol

explod_javad
دوشنبه 30 شهریور 1388, 14:45 عصر
امین خان ، خدایی خیلی شرمندت شدم.
مثل اینکه من نمی تونم منظورم را خوب برسونم.من قصد دارم جدل همنطوری که گفتم ، با دستور Update بروز بشه.ولی توی کدی که زحمت کشیدی ، اصلا Update وجود نداره؟
من میخام یک Sp داشته باشم که فقط بهش ID و Level رکورد بچه رو بدم .حالا بادستور Update و دستورا شرطی مابقی بچه های این پدر نسبت به تغییر رکورد بچه مورد نظر ، تغییر کنند(مرتب بشن)
ولی خیلی ازت ممنون هستم ، بخاطر وقتی که گذاشتی.
خودم یه کاریش میکنم.
ممنون.

AminSobati
سه شنبه 31 شهریور 1388, 21:30 عصر
در پست قبلیم تصور کردم اگر این Query بدست بیاد دیگه Updateش باید راحت باشه.
نمیدونم این کد چقدر نزدیکه به چیزی که شما نیاز دارین:


declare @x table(pk char(1) primary key,Parent int, Child int, Location int)

insert @x values('a',1,19,null)
insert @x values('b',1,20,null)
insert @x values('c',1,29,null)
insert @x values('d',1,14,null)
insert @x values('e',1,5,null)

;with MyCTE
as (select *,row_number() over(partition by Parent order by Child) as Rank from @x)
update @x set t1.Location=t2.rank
from @x t1 join MyCTE t2
on t1.pk=t2.pk

select * from @x
order by parent, location