PDA

View Full Version : نوشتن کوئری از دو جدول متفاوت



manit44
چهارشنبه 26 شهریور 1393, 15:28 عصر
سلام

من دو جدول دارم یکی جدول امور و دیگری جدول مشترک حالا میخوام کوئری insert رو طوری بنویسم که هر مشترک فقط یک امور داشته باشه و اگر مشترکی خواست دو امور داشته باشه پیغام خطا بده

چکار باید بکنم؟

فیلدهای جدول امور: cid,name,family,address

فیلدهای جدول مشترک: Id,cid,cname,cfamily,caddress

ممنون از تمامی دوستان.

mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 15:38 عصر
درود بر شما
اندکی صبر میکردین همونجا جواب میدادن دوستان:اشتباه:
اگر دیتابیستون رو بگید چیه بهتر راهنمایی می کنم.

manit44
چهارشنبه 26 شهریور 1393, 16:22 عصر
سلام

SQL server 2012

نام دیتابیس: testDB

mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 17:42 عصر
خیلی خیل راحته
شما در جدول مشترک دو فیلد id و cid رو به عنوان primary key تعریف کنید. با query اینجور میشه البته هنگام تعریف جدول:


Constraint PK_table1 PRIMARY KEY(ClassID, StudentID)

اگر از wizard می خواید استفاده کنید. روی table راست کلیک، design و بعد دوتا ستون روی انتخاب کنید و روی دکمه set as primary key کلیک کنید و save کنید.

manit44
چهارشنبه 26 شهریور 1393, 21:57 عصر
آقای بیضاوی منظورم این نبود، منظورم این بود که cid در جدول امور، کلید خارجی در جدول مشترک(cid) هست حالا من میخوام کوئری insert رو طوری هندل کنم که وقتی در جدول مشترک insert انجام میشه همون اطلاعات یعنی نام و نام خانوادگی و آدرس در جدول امور با توجه به cid هاشون انجام بشه. اگه میشه کوئری insert رو بهم بگین چطوری بنویسم؟

ممنون از لطفتون.

mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 22:13 عصر
نمیدونم درست متوجه شدم یا نه
اما طبق فرموده شما راه حل استفاده از Triger هست البته روی همون جدول امور. فک کنم اینجور بشه:


ALTER TRIGGER [dbo].[InsertIntoMoshtarak] ON [dbo].[Omoor]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;




-- get the last id value of the record inserted or updated
DECLARE @id INT
DECLARE @name varchar(50)
DECLARE @family varchar(50)
DECLARE @address varchar(50)
SELECT @id = [cid], @name=[name], @family=[family], @address=[address]
FROM INSERTED




INSERT INTO(cid,cname,cfamily,caddress)
VALUES @id,@name,@family,@address;




END

manit44
چهارشنبه 26 شهریور 1393, 22:57 عصر
این تریگری که شما نوشتین رو ارور میگیره.

mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 23:01 عصر
این تریگری که شما نوشتین رو ارور میگیره.
من دیتابیس ندارم.
همینجور نوشتم، errorش چیه؟؟؟

manit44
چهارشنبه 26 شهریور 1393, 23:18 عصر
Msg 102, Level 15, State 1, Procedure InsertIntoCustomer, Line 21Incorrect syntax near '('.

manit44
چهارشنبه 26 شهریور 1393, 23:52 عصر
دوستان عزیز یه کمکی کنند!!!!!!!!!!!!

mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 23:56 عصر
اوه اوه ببخشید.
بین INTO و پرانتز باز اسم جدول مشترک رو بذار

manit44
پنج شنبه 27 شهریور 1393, 00:01 صبح
حالا یه ارور دیگه داد:

Msg 102, Level 15, State 1, Procedure InsertIntoMoshtarak, Line 22
Incorrect syntax near '@id'.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 00:13 صبح
دارم SQL نصب میکنم.
اینو امتحان کن فک کنم این درستره تا نصب بشه خودمم چک کنم.:


ALTER TRIGGER [dbo].[InsertIntoMoshtarak] ON [dbo].[Omoor]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;


-- get the last id value of the record inserted or updated
DECLARE @id INT;
DECLARE @name varchar(50);
DECLARE @family varchar(50);
DECLARE @address varchar(50);

SET @id = o.id from insertted o;
SET @name = o.name from insertted o;
SET @family = o.family from insertted o;
SET @address = o.address from insertted o;

INSERT INTO(cid,cname,cfamily,caddress)
VALUES @id,@name,@family,@address;
END

manit44
پنج شنبه 27 شهریور 1393, 00:16 صبح
ارورش بیشتر شد که کمتر نشد.:عصبانی++:

samanelf
پنج شنبه 27 شهریور 1393, 00:22 صبح
http://barnamenevis.org/showthread.php?469576-%D8%AA%D8%B3%D8%AA-%D9%BE%D8%B1%D9%88%DA%98%D9%87&p=2104617#post2104617
میشه به این تاپیک منم جواب بدین ؟

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 00:32 صبح
حالا چک کن


CREATE TRIGGER [dbo].[InsertIntoMoshtarak] ON [dbo].[Omoor]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
insert into moshtarak (cid,cname,cfamily,caddress)
(select cid,name,family,address from omoor where id=@@IDENTITY)
END
GO

manit44
پنج شنبه 27 شهریور 1393, 00:43 صبح
این قسمت فکر کنم باید cid باشه:

cid=@@IDENTITY)

درسته؟

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 00:48 صبح
نه، اگر Id جدول omoor به صورت identity باشه با این کوئری آخرین رکورد insert شده رو که id اون با همین@@Identity برابره واکشی میکنه.
فکر میکنم همین درسته. نیست؟

manit44
پنج شنبه 27 شهریور 1393, 01:05 صبح
میبخشید میدونم اینجا جاش نیست ولی خیلی واجبه

تو برنامم یعنی C# وقتی تریگرم رو صدا میزنم با ارور زیر مواجه میشم:

The request for procedure 'trg_customer' failed because 'trg_customer' is a trigger object.

اینم کدمه:
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True"); con.Open();
SqlCommand cmd = new SqlCommand("trg_customer", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("cname", txtName.Text);
SqlParameter p2 = new SqlParameter("cfamily", txtFamily.Text);
SqlParameter p3 = new SqlParameter("caddress", txtAddress.Text);
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
cmd.Parameters.Add(p3);
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "اطلاعات با موفقیت ثبت شد";
GridView1.DataBind();

خیلی ممنون.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 01:14 صبح
میبخشید میدونم اینجا جاش نیست ولی خیلی واجبه

تو برنامم یعنی C#‎ وقتی تریگرم رو صدا میزنم با ارور زیر مواجه میشم:

The request for procedure 'trg_customer' failed because 'trg_customer' is a trigger object.

اینم کدمه:
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True"); con.Open();
SqlCommand cmd = new SqlCommand("trg_customer", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("cname", txtName.Text);
SqlParameter p2 = new SqlParameter("cfamily", txtFamily.Text);
SqlParameter p3 = new SqlParameter("caddress", txtAddress.Text);
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
cmd.Parameters.Add(p3);
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "اطلاعات با موفقیت ثبت شد";
GridView1.DataBind();

خیلی ممنون.
به به، به به....:تشویق:
trigger رو که شما یا توی برنامه صدا نمیزنن، trigger آخرین station قبل از اعمال داده ها روی دیسک سخت افزاری هست و فقط engine دیتابیش اون رو handle می کنه.
از اون گذشته خودتون که میبینید type دستورتون رو storedprocedure گذاشتین چرا می خواید یه کار دیگه باهاش انجام بدین؟؟؟
راستی به trigger پارامتر هم نمیتونید پاس بدید

manit44
پنج شنبه 27 شهریور 1393, 01:16 صبح
پس میتونم همون کد sql ای که در بالا برام گذاشتین قرارش بدم داخل یک پروسیجر؟

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 01:25 صبح
برای اینکه این کد رو بزارین توی sp و درست هم جواب بگیرید حداقلش اینه که Id رو باید بهش پاس بدین
اما یه نکته؛ همون trigger که تمام کارتون بدون ذره ای کد نوشتن در سمت برنامه انجام میده. پس چرا میخواید اینکار رو انجام بدید؟؟؟؟!!!!!!:متفکر:

manit44
پنج شنبه 27 شهریور 1393, 01:50 صبح
ببینید من پروسیجرم رو به این شکل نوشتم ولی این ارور را گرفت:

کد:
USE [testDB]GO
/****** Object: StoredProcedure [dbo].[sp_customer] Script Date: 2014-09-18 1:25:47 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER PROCEDURE [dbo].[sp_customer]


AS
BEGIN


-- Insert statements for procedure here
SET NOCOUNT ON;
insert into tbl_customer(cid,cname,cfamily,caddress)
(select cid,name,family,address from tbl_omoor where cid=@@IDENTITY)
END




ارور:


Procedure sp_customer has no parameters and arguments were supplied.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 02:04 صبح
شما اینجا یه پارامتر دارید که ناشناختست و اون @@IDENTITY هست.
این متغیر در زمان باز بودن connection هنگام INSERT شناخته میشه و اینجا معنی نداره.
شما همین متغیر رو به صورت پارامتر ورودی به این sp پاس بدید و بعد همین پارامتر رو بزارید جای @@IDENTITY.

manit44
پنج شنبه 27 شهریور 1393, 02:21 صبح
ببینید الان درست شد؟

کد:
ALTER PROCEDURE [dbo].[sp_customer]@Id int
AS
BEGIN


-- Insert statements for procedure here
SET NOCOUNT ON;
insert into tbl_customer(cid,cname,cfamily,caddress)
(select cid,name,family,address from tbl_omoor where cid=@Id)
END




اگه درسته تو سی شارپ باید چطوری ازش استفاده کنم؟

ممنون.

manit44
پنج شنبه 27 شهریور 1393, 02:25 صبح
یه سوال اگه بخوام این sp رو مستقیما تو سی شارپ بکار ببرم، میتونم این کار رو انجام بدم؟

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 02:30 صبح
درسته، فقط بهتره اینجا دیگه پرانتز اول و آخر select رو برداری.
برای سی شارپ هم قبلا کدش رو نوشته بودی که. اینجوری:


SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True");
SqlCommand cmd = new SqlCommand("sp_customer", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("Id", txtId.Text);
cmd.Parameters.Add(p1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "اطلاعات با موفقيت ثبت شد";
GridView1.DataBind();

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 02:31 صبح
یه سوال اگه بخوام این sp رو مستقیما تو سی شارپ بکار ببرم، میتونم این کار رو انجام بدم؟
مگه به صورت کج هم داریم!!! آره دیگه همینجور که استفاده کردی و منم تکرارش کردم

manit44
پنج شنبه 27 شهریور 1393, 02:37 صبح
آقای بیضاوی پیام موفقیت آمیز ثبت اطلاعات رو داد ولی چیزی داخل دیتابیس ثبت نکرد. چکار کنم؟

ممنون.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 02:44 صبح
از داخل SQL یا توی VS یک کوئری باز کن و اون sp رو با مقداری که می دونی توی جدول هست امتحان کن . فرض کن Id شماره 4 رو داری:


EXEC sp_customer @id=4;

ببین اجرا میشه با نه؟ چی پیام میده؟

manit44
پنج شنبه 27 شهریور 1393, 02:50 صبح
بله درست اجرا میشه داخل SQL server، ولی وقتی برنامه رو تو ویژوال استودیو اجرا میکنم و فیلدها رو پر میکنم هیچ دیتایی ثبت نمیکنه ولی پیام موفقیت آمیز میده. چکار کنم که از داخل برنامه هم دیتا ثبت کنه؟

ممنون.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 02:57 صبح
می تونید یه break point روی این خط زیر بذارید ببینید مقدار p1 ارجاعی به sp چیه:

con.Open();
احتمالا این مقدار یا خالیه و یا یه مقدار نادرست که توی جدول نیست رو میگیره.

manit44
پنج شنبه 27 شهریور 1393, 03:01 صبح
مقدار p1 رو null میده. باید چطوری پرش کنم؟ چون تو sql درست جواب میده.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:11 صبح
این دوتا خظ رو پاک کن :


SqlParameter p1 = new SqlParameter("Id", txtId.Text);
cmd.Parameters.Add(p1);


از این بجاش استفاده کن ببین اکی میشه:

cmd.Parameters.AddWithValue("Id", txtId.Text);

manit44
پنج شنبه 27 شهریور 1393, 03:16 صبح
نه درست نشد.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:18 صبح
یعنی بازم مقدار پارامتر خالیه؟
اصلا ببین مقداری که میخوای بزاری جای Id پر میشه؟ مقدارش چیه؟!!!:متعجب:

manit44
پنج شنبه 27 شهریور 1393, 03:20 صبح
بله باز هم مقدار پارامتر خالیه

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:22 صبح
نه، گفتم ببین مقدار پارامتری که میخوای بریزی داخل پارامتر چیه، اون یه مشکلی داره نه پارامتره!!!:عصبانی:

manit44
پنج شنبه 27 شهریور 1393, 03:26 صبح
اون رو هم null بزمیگردونه

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:28 صبح
آقا صبح شد
کد این صفحه رو بذار ببینم Id رو چطور داری میگیری و به اینجا میرسونی:افسرده:

manit44
پنج شنبه 27 شهریور 1393, 03:30 صبح
کد:

protected void btnInsert_Click(object sender, EventArgs e) {
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("sp_customer", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("Id", txtID.Text);
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "اطلاعات با موفقیت ثبت شد";
GridView1.DataBind();
}


protected void btnEdit_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True");
con.Open();
string sql = "update tbl_customer set cname=@cname , cfamily=@cfamily , caddress=@caddress where Id=@Id";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("cname", txtName.Text);
cmd.Parameters.AddWithValue("cfamily", txtFamily.Text);
cmd.Parameters.AddWithValue("caddress", txtAddress.Text);
cmd.Parameters.AddWithValue("Id", txtID.Text);
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "اطلاعات ویرایش شد";
GridView1.DataBind();
}


protected void btnDelete_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=testDB;Integrated Security=True");
con.Open();
string sql = "delete from tbl_customer where Id=@Id";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("Id", txtID.Text);
cmd.ExecuteNonQuery();
con.Close();
Label4.Text = "رکورد مورد نظر حذف شد";
GridView1.DataBind();
}

manit44
پنج شنبه 27 شهریور 1393, 03:31 صبح
ویرایش و حذف درست کار می کنند.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:36 صبح
وای وای وای....:عصبانی++:
خب من این txtId رو به عنوان مثال دادم، شما باید id اون اموری که insert می کنی رو هر جا البته insert می کنی، ذخیره کنی و به اینجا پاس بدی.
این بنده خدای txtId از کجا باید بفهمه که کدون Id رو ببره بده به stored procedure?????!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!

امیدوارم اینجاش رو درست کنی دیگه موردی نداشته باشی
شب خوش یا بهتره بگم صبح بخیر

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:37 صبح
البته اگه داخل این txtId هم Id درست رو وارد کنی اینجاشم درست میشه

manit44
پنج شنبه 27 شهریور 1393, 03:42 صبح
میشه این نیم خط کد رو بهم بگین؟ چون خیلی قاطی کردم.

خیلی ممنون میشم.

manit44
پنج شنبه 27 شهریور 1393, 03:43 صبح
Id امور به صورت identity هست.

mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 03:49 صبح
ببین این کارت با همون trigger زودتر و بهتر راه میفتاد اما چون نمیدونستم و هنوزم نمیدونم چیکار داری میکنی گفتم این رو هم با هم پیش ببریم.
هنوزم توصیه می کنم با همون trigger کار کنید. کد نویسیش خیلی کمتره
من فردا 8 به بعد آن هستم . اون موقع اگه سرم شلوغ نبود موردی بود در خدمتم

manit44
پنج شنبه 27 شهریور 1393, 03:51 صبح
باشه ممنون پس تا فردا