PDA

View Full Version : سوال: مشکل در Update Query



mahdi87_gh
پنج شنبه 21 آبان 1388, 22:02 عصر
سلام به دوستان

من ی جدول به این شکل دارم با ی فیلد (number). ی عدد از ورودی تابع می گیرم. می خوام به تعداد اون عدد از جدول من کم بشه. ی مثال میزنم قضیه روشنتر بشه.

رکوردهای داخل جدول:

3

2

6

8

حالا فرض میکنیم عدد ورودی 7 باشه.تابع باید جدول رو به این جدول زیر تبدیل کنه:

0

0

4

8

امیدوارم تونسته باشم منظورم رو برسونم. منتظر همفکری شما هستم.ممنون:لبخندساده:

shahab2025
جمعه 22 آبان 1388, 01:14 صبح
سلام
فکر کنم این دوستمون داره یه برنامه شبیه انبارداری مینویسه چیزی هم که میخواد میتونه این معنا رو داشته باشه :

ما 4 تا رسید داریم که به ترتیب 2و3و6و8 تا از یک کالا وارد انبار شده است حالا یک حواله زده میشه که میخواد هفت تا از موجودی کسر کنه به طبع چون سیستم fifo است (first in, first out) باید از اولین رسید کم کنه و به ترتیب جلو بره تا میزان حواله از انبار کسر بشه پس اولی صفر میشه سپس دومی صفر میشه و سومی هم 4 میشه ...
طبیعی است چون رسیدهای مختلف با قیمتهای مختلف وارد شده اند و با قیمتهای متفاوت هم خارچ میشوند، استفاده از جمع جبری مقادیر نادرست است

خوشحال میشم که من هم از جواب این مساله آگاه بشم

محمد سلیم آبادی
جمعه 22 آبان 1388, 10:07 صبح
سلام،
با استفاده از Assignment Update مساله حل شد.
توجه کنید که تمام کد در SQL Server 2008 نوشته و چک شده است.

ابتدا یک جدول ایجاد کرده و سطرهای مورد نظر را درج می کنم.


--Assignment Update
Set Nocount On
Create table Sample1
(
i int
);

Go
Insert Into Sample1 (i)
Values (3),
(2),
(6),
(8);

Go


سپس یک SP تعریف کرده و عبارت Update را در آن قرار می دهم.
و با کمک گرفتن از ماده ی Output سطرهای جدید و قدیمی را نیز به نمایش در خواهم آورد.



Create Proc Sample @n int
as
begin

Declare @current int,
@i int;

Select @current = 0,
@i = 0;

Update Sample1
Set i = @i,
@i = case when i < @n - @current then 0
when (@n - @current) > 0 and (@current - i) < i then i - (@n - @current)
else i
end,
@current += i
Output
inserted.i as new,
deleted.i as old
end


و برای به اجرا در آوردن آن با پارامتر با مقدار 7 از کد زیر استفاده می کنم:


execute Sample 7


و بعد از اجرای رویه ی ذخیره شده سطرهای زیر باید به نمایش در بیایند:


new old
----------- -----------
0 3
0 2
4 6
8 8

Msalim--

mahdi87_gh
جمعه 22 آبان 1388, 10:49 صبح
دوست عزیزمون shahab2025 (http://barnamenevis.org/forum/member.php?u=53796) کاملا متوجه منظورم شدن.
روشی که آقای msalim (http://barnamenevis.org/forum/member.php?u=108959) انجام دادن کاملا درست عمل میکنه ولی من هنوز مشکلاتی دارم. بیایم جدول sample رو اینطوری در نظر بگیریم(kalaID,mojodi,kharid). من ی جدول دیگه دارم که فروش رو ذخیره می کنم(kalaID,kharid,num). میخوام وقتی که از انبارم داره کم میشه به همون تعدادی که از کالای با قیمت x کم شده در فروش به همون قیمت x ثبت بشه.مثال میزنم واضحتر بشه منظورم:
sample
101,3,400
101,2,420
101,6,430
101,8,500
عدد بعد از ویرگول همون قیمت خرید هستش
به همون شیوه ای که بررسی شد و جواب هم داد باید از انبار کم بشه ولی توی جدول فروش هم باید اینطوری ثبت بشه:
101,3,400
101,420,2
101,430,2
ممنون از توجه دوستان:لبخندساده:

محمد سلیم آبادی
جمعه 22 آبان 1388, 12:36 عصر
اینو امتحان کنید


--Assignment Update
Set Nocount On
--============ Declration Tables and publishing some rows on it
Create table Sample1 --انبار
(
KalaID int,
mojodi int,
kharid int
);
Insert Into Sample1 (KalaID, mojodi, kharid)
Values (101, 3, 400),
(101, 2, 420),
(101, 6, 430),
(101, 8, 500);
Go
Create table Sample2 --ثبت فروش
(
kalaID int,
kharid int,
num int
)
Go

--=============== Create a SP for inserting and Updating data
Create Proc Sample @kalaid int, @n int
as
begin
Declare @current int,
@i int;

Select @current = 0,
@i = 0;

Declare @Sample1_temp table --انبار
(
KalaID int,
mojodi int,
kharid int
);

Insert Into @Sample1_temp
Select * From Sample1
Where KalaID = @kalaid

Update @Sample1_temp
Set mojodi = @i,
@i = case when mojodi < @n - @current then 0
when (@n - @current) > 0 and (@current - mojodi) < mojodi then mojodi - (@n - @current)
else mojodi
end,
@current += mojodi
Where KalaID = @kalaid


Insert Into Sample2 (kalaID, kharid, num)
select s.KalaID ,s.kharid, s.mojodi-p.mojodi as mojodi
from Sample1 as s
inner join @Sample1_temp as p
on s.kharid = p.kharid
and s.kalaid = p.KalaID
where s.mojodi <> p.mojodi

Update s
Set s.mojodi = p.mojodi
From Sample1 s
inner join @Sample1_temp p
on s.kharid = p.kharid
and s.kalaid = p.KalaID
where s.mojodi <> p.mojodi
end

--======== Executing the Stored Procedure
execute Sample @kalaid = 101, @n = 7

Select * From Sample1
/*
KalaID mojodi kharid
----------- ----------- -----------
101 0 400
101 0 420
101 4 430
101 8 500
*/

Select * From Sample2
/*
kalaID kharid num
----------- ----------- -----------
101 400 3
101 420 2
101 430 2
*/

mahdi87_gh
جمعه 22 آبان 1388, 22:07 عصر
با تشکر از شما msalim

کدی که شما نوشتین کاملا درست عمل میکنه. من از sql2005 استفاده می کنم. چندخطشو تغییر دادم مثل @current+=i تا توی 2005 اجرا بشه.درستم کار میکنه. ولی من هرکاری کردم همین روش رو روی جدول های خودم اجرا کنم نشد، اجرا میشه و هیچ خطایی نمیگیره اما مقادیر جدول ها تغییری نمی کنه. مشکلش باید توی همون قسمت اولش باشه(همون که مثلا 7تا کم کنه). منطق کدی که نوشتین کاملا صحیحه. من خود دیتابیس رو اینجا میزارم.اگه حوصله و وقتش رو داشتید یه نگاه بهش بندازید، بلکه گرهی از کار ما باز بشه.ممنون

stored procedure InsertFrosh رو ببینید

محمد سلیم آبادی
جمعه 22 آبان 1388, 22:49 عصر
جای ستون های kharid و mojodi را در جدول متغیری @temp جابجا کنید. یا در عبارت insert select مربوط به @temp نام ستون ها را با یکدیگر match کنید.

AminSobati
شنبه 23 آبان 1388, 23:17 عصر
Create Proc Sample @n int
as
begin

Declare @current int,
@i int;

Select @current = 0,
@i = 0;

Update Sample1
Set i = @i,
@i = case when i < @n - @current then 0
when (@n - @current) > 0 and (@current - i) < i then i - (@n - @current)
else i
end,
@current += i
Output
inserted.i as new,
deleted.i as old
end


مراقب باشید! این قبیل Updateها به خاطر اینکه ماهیتا باید به طور Serial انجام بشن ممکنه روی کامپیوترهای دو هسته ای (یا بیشتر) نتیجه ای که انتظار دارید رو تولید نکنند. چون فرایند Update بین Processorها پارالل میتونه بشه، درست مثل یک دستور Select. برای اینکه تضمین کنید این فرایند تنها با یک Processor انجام میشه، از OPTION MAXDOP 1 میبایست استفاده کنید.
همچنین استفاده از TABLOCKX ضروریه چون اگر سایر کاربرها در همون لحظه Insert یا Delete انجام بدن شاید باز هم نتیجه مطلوب تولید نشه