ورود

View Full Version : Insert در چند جدول



Davood_amega
سه شنبه 19 مرداد 1389, 13:13 عصر
بنده یک Stored Procedure نیاز دارم که در چند Table عمل Insert را انجام می دهد .
در Table به نام Reserve عمل Insert را انجام می دهد و مقدار فیلد Identity را برمی گرداند چون نیاز داریم که در Table به نام real_One ذخیره شود .

CREATE PROCEDURE SP_Insert_Reserve (@R_Participant_Qty smallint
,@R_Bond_Type nvarchar(15)
,@R_Entry_Time time(0)
,@RO_Sex bit
,@RO_Name nvarchar(25)
,@RO_Family nvarchar(50))
AS
INSERT INTO Reserve
(R_Participant_Qty
,R_Bond_Type
,R_Entry_Time)
VALUES
(@R_Participant_Qty
,@R_Bond_Type
,@R_Entry_Time)return ident_Current('Reserve')
GO
INSERT INTO Real_One
(RO_Res_ID
,RO_Sex
,RO_Name
,RO_Family)
VALUES
(@RO_Res_ID
,@RO_Sex
,@RO_Name
,@RO_Family)
GO
Stored Procedure را ایجاد نمی کند و خطای زیر را می دهد :

Msg 137, Level 15, State 2, Line 7
Must declare the scalar variable "@RO_Res_ID".سوالاتم :
1- این خطا را چه جوری برطرف کنم ؟
2- چه جوری یک متغیر بگیریم که این فیلد Identity را در خود نگه دارد تا در Table دیگر ازآن استفاده کنیم ؟

حمیدرضاصادقیان
سه شنبه 19 مرداد 1389, 13:19 عصر
سلام.شما باید بااستفاده از Declare متغیر Ro_res_id رو تعریف کنید بعد مقدار identity رو به این متغیر اختصاص بدید.با یک Select ساده میتونید مقدار اخرین identity رو بعد از insert اولی خونده و در این متغیر نگه داری کنید.
موفق باشید

Davood_amega
سه شنبه 19 مرداد 1389, 13:27 عصر
به نظرم return انتهای Insert مقدار فیلد Identity را برمی گرداند . اما نمی دانم که چه جوری آن را در یک متغیر ذخیره کنم .
در مورد سوال دوم Go قبل از Insert دوم را برداشتم دیگه خطای ندارد . Go را برای این گذاشته بودم که تا Insert اول تموم نشده سراغ Insert دوم نرود .
Go همچین کاری می کنه دیگه ، درسته؟

Rocker
سه شنبه 19 مرداد 1389, 13:43 عصر
به نظرم return انتهای Insert مقدار فیلد Identity را برمی گرداند . اما نمی دانم که چه جوری آن را در یک متغیر ذخیره کنم .
در مورد سوال دوم Go قبل از Insert دوم را برداشتم دیگه خطای ندارد . Go را برای این گذاشته بودم که تا Insert اول تموم نشده سراغ Insert دوم نرود .
Go همچین کاری می کنه دیگه ، درسته؟

میتونی از یک پارامتر خروجی (output parameter) استفاده کنی و مقدار مورد نظر رو برگردونی
اون GO هم که گفتی همچین کاری رو انجام میده منتها یادت نره که باید به صورت مجزا در یک خط باشه

Rocker
سه شنبه 19 مرداد 1389, 14:10 عصر
همچنین از یه دستور مثل زیر میتونی استفاده کنی اگر با ADO.NET کار کنی مسلما کار با پارامترها رو بلدی

EXEC @return_value = YourProcName([parameter list])
SELECT 'Return Value' = @return_value

Davood_amega
سه شنبه 19 مرداد 1389, 15:52 عصر
همچنین از یه دستور مثل زیر میتونی استفاده کنی اگر با ADO.NET کار کنی مسلما کار با پارامترها رو بلدی

EXEC @return_value = YourProcName([parameter list])
SELECT 'Return Value' = @return_value
کار با پارامترها را بلدم اما هنوز جوابو نگرفتم .
دقت کنید که دستور Insert دوم از مقدارIdentity از Insert اول مقدار می گیرد .
می خواهم دستور Insert اولم ، Identity که اضافه کرده را برگرداند و در دستور Insert دوم مقدار را وارد کنم .

Rocker
سه شنبه 19 مرداد 1389, 15:59 عصر
پس شما اصلا نباید از Return استفاده کنی چون باعث میشه از Proc خارج بشی و ادامه ی دستوراتت اجرا نشه
وایستا ببینم چیزی میتونم پیدا کنم
مطمئنا هست

Rocker
سه شنبه 19 مرداد 1389, 16:07 عصر
بیا برای اینکه راحت تر بخونی دستورات اصلی رو برات میزارم اینو من رو دو تا جدول آزمایشی تو SQL Server خودم تست کردم جواب داد.
فقط بگم این یه شبیه سازیه تو خودت باید به اون شکلی که نیاز داری استفاده کنی

declare @p int
set @p = ident_Current('Table1')

INSERT INTO Table2 ([name],family,tel,age) VALUES ('a','b','123',@p)

Rocker
سه شنبه 19 مرداد 1389, 16:09 عصر
در ضمن برای اینکه مقدار فیلد آخرین کلید رو در بیاری باید بعد از Insert یه GO بزنی تا رکورد درج بشه بعد با همون دستوراتی که تو پست قبلیم بهت گفتم مقدار کلید رو در بیاری و بریزی تو یه متغیر و الباقیه ماجرا

Davood_amega
سه شنبه 19 مرداد 1389, 16:54 عصر
بیا برای اینکه راحت تر بخونی دستورات اصلی رو برات میزارم اینو من رو دو تا جدول آزمایشی تو SQL Server خودم تست کردم جواب داد.
فقط بگم این یه شبیه سازیه تو خودت باید به اون شکلی که نیاز داری استفاده کنی

declare @p int
set @p = ident_Current('Table1')

INSERT INTO Table2 ([name],family,tel,age) VALUES ('a','b','123',@p)
ممنون با کد زیر جواب داد که تقریبا شبیه به کد شماست .

CREATE PROCEDURE SP_Insert_Reserve (@R_Participant_Qty smallint
,@R_Bond_Type nvarchar(15)
,@R_Entry_Time time(0)
,@RO_Sex bit
,@RO_Name nvarchar(25)
,@RO_Family nvarchar(50))
AS
BEGIN
DECLARE @RETURN_VALUE INTEGER
INSERT INTO Reserve
(R_Participant_Qty
,R_Bond_Type
,R_Entry_Time)
VALUES
(@R_Participant_Qty
,@R_Bond_Type
,@R_Entry_Time)SET @RETURN_VALUE = SCOPE_IDENTITY()
INSERT INTO Real_One
(RO_Res_ID
,RO_Sex
,RO_Name
,RO_Family)
VALUES
(@RETURN_VALUE
,@RO_Sex
,@RO_Name
,@RO_Family)
End


در ضمن برای اینکه مقدار فیلد آخرین کلید رو در بیاری باید بعد از Insert یه GO بزنی تا رکورد درج بشه بعد با همون دستوراتی که تو پست قبلیم بهت گفتم مقدار کلید رو در بیاری و بریزی تو یه متغیر و الباقیه ماجرا
وقتی این کار را می کنم به پارامترهای Insert دوم ایراد میگیره میگه که تعریف نشده اند .

Rocker
سه شنبه 19 مرداد 1389, 17:09 عصر
ممنون با کد زیر جواب داد که تقریبا شبیه به کد شماست .

CREATE PROCEDURE SP_Insert_Reserve (@R_Participant_Qty smallint
,@R_Bond_Type nvarchar(15)
,@R_Entry_Time time(0)
,@RO_Sex bit
,@RO_Name nvarchar(25)
,@RO_Family nvarchar(50))
AS
BEGIN
DECLARE @RETURN_VALUE INTEGER
INSERT INTO Reserve
(R_Participant_Qty
,R_Bond_Type
,R_Entry_Time)
VALUES
(@R_Participant_Qty
,@R_Bond_Type
,@R_Entry_Time)SET @RETURN_VALUE = SCOPE_IDENTITY()
INSERT INTO Real_One
(RO_Res_ID
,RO_Sex
,RO_Name
,RO_Family)
VALUES
(@RETURN_VALUE
,@RO_Sex
,@RO_Name
,@RO_Family)
End
وقتی این کار را می کنم به پارامترهای Insert دوم ایراد میگیره میگه که تعریف نشده اند .

خوب واسه اینکه باید این دستور رو

DECLARE @RETURN_VALUE INTEGER
بلافاصله قبل از این دستور تعریف کنی

SET @RETURN_VALUE = SCOPE_IDENTITY()

گرفتی چی میگم؟؟
چون وقتی Go میکنی انگار رفته تو یه Proc دیگه واسه همین پارمتر رو نمیشناسه

Davood_amega
سه شنبه 19 مرداد 1389, 17:41 عصر
وقتی GO می گذارم از کدهای زیر ERROR میگیره !


VALUES
(@RETURN_VALUE
,@RO_Sex
,@RO_Name
,@RO_Family)که از کل پارامترهای Insert دوم ایراد می گیرد حتی @RETURN_VALUE و بقیه متغیرهای مربوط به آن را پاک می کنم باز هم به این پارامترها خطا میده (البته بعد از گذاشتن GO)

Rocker
سه شنبه 19 مرداد 1389, 17:44 عصر
پس اون GO رو که بعد از اینزرت اولی گذاشتی وردارد درست میشه

Davood_amega
سه شنبه 19 مرداد 1389, 18:11 عصر
آره درست شده اما شک به این دارم که دستور Insert تا زمانیکه اجراش تمام نشده دستور Insert دوم اجرا بشه !

Rocker
سه شنبه 19 مرداد 1389, 19:09 عصر
نه شک نداشته باش
البته یه کار مطمئن تر اینه که
اینزرت دوم رو تویه پروسیجر دیگه بزاری و پارامترها رو به اون پاس بدی
آره این کار بهتره

احمد سامعی
چهارشنبه 20 مرداد 1389, 01:32 صبح
ببخشید دوستان وسط بحث وارد می شم (چون سوالم در همین رابطه بود تاپیک جدید ندادم)

من می خوام مشابه کار دوستمون انجام بدم یعنی اول تو یک جدول اینزرت کنم بعد تو جدول دوم

حالا اگر تو اینزرت دوم مشکل پیش اومد چطوری رول بک کنم ؟ منظورم دستورات شروع و پایان ترنکشن چطوری بدم

من تازه کار با sp دارم یاد می گیرم ممنون می شم