منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب

نسخة كاملة : كيف يمكنني عمل trigger يقوم بإضافة بيانات حقل من جدول ما إلى حقل في جدول آخر
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
الصفحات : 1 2 3
حريف برمجة كتب :مرحبا مره أخرى ،،،،

الأخ محمد ماقصر الله يجزاه خير ،،، ولكن لي ملاحظتين :

# الملاحظة الأولى : الأخ محمد عمل ثلاث عمليات العملية الأولى : (ادخال اسم الفصل في جدول الفصول) العملية الثانية (ادخال رقم الآيدي للفصل في جدول الشعب) العملية الثالثة (تعديل على جدول الشعب بموجب شرط آخر رقم للآيدي واضافة اسم الشعبة)

بينما هي عمليتين بالأصل (ادخال اسم الفصل في جدول الفصول) و (ادخال رقم الآيدي للفصل واسم الشعبة في جدول الشعب) فقط

# الملاحظة الثانية : والتي اعتبرها مشكلة ان لم تنتبهو لها وشرح المشكلة كالتالي :

ماتفضل به اخي محمد : انه ادخل اسم الفصل ثم جلب آخر رقم للأيدي من جدول الفصل وقام ادخل في جدول الشعب .... هنا المشكلة

لنفرض يوجد في سجل الفصول سجل واحد فقط ،،، بإسم الفصل الأول . والآيدي التابع له رقم 1 .

وقمت انا ادخال اسم الفصل الثاني حيكون الآيدي التابع له رقم 2 .

لنفرض موظف آخر قام بإدخال سجل في نفس الوقت في الجدول . سيكون الآيدي التابع له رقم 3 .

عند تنفيذ الجملة المطروحه من أخي محمد سيجلب آخر رقم للآيدي من الجدول وهنا يكون رقم 3 .... هنا الخطأ .

الحل يكون كالتالي : عند اضافة سجل نجلب الآيدي للسجل نفسه بجملة واحده مع عملية الإدخال :

لاحظو الحل يتكون أولاً من عمليتين وليس ثلاث ، أيضاً رقم الآيدي يكون مخصوص لرقم السجل المضاف وليس آخر سجل اضيف .

كود :
Dim cmd As New SqlCommand
        cmd.Connection = conn
        conn.Open()

        cmd.CommandText = "INSERT INTO classes (classname) OUTPUT(Inserted.classno) VALUES (@classname)"
        cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

        Dim sid As Integer = cmd.ExecuteScalar    'المسؤول عن ادخال البيانات وجلب رقم الآيدي في المتغير
        cmd.Dispose()


        Dim cmd2 As New SqlCommand
        cmd2.Connection = conn

        cmd2.CommandText = "INSERT INTO sections (classno,section) VALUES (@classno,@section)"
        cmd2.Parameters.AddWithValue("@classno", sid)
        cmd2.Parameters.AddWithValue("@section", TextBox2.Text)

        cmd2.ExecuteNonQuery()

        cmd2.Dispose()
        conn.Close()
المثال في المرفقات اي غموض انا موجود / بالتوفيق

لم أفهم المقصود بعبارة output الموجودة في السطر التالي
cmd.CommandText = "INSERT INTO classes (classname) OUTPUT(Inserted.classno) VALUES (@classname)"
cmd.Parameters.AddWithValue("@classname", TextBox1.Text)
شكرا لكم ( حريف برمجة ) و (محمد الحاج خلف)
على هذه المعلومات قيمة وعلى إثراء الموضوع
وبكل الاحوال اختلاف وجهات النظر لايفسد للود قضية
dena كتب :لم أفهم المقصود بعبارة output الموجودة في السطر التالي
cmd.CommandText = "INSERT INTO classes (classname) OUTPUT(Inserted.classno) VALUES (@classname)"
cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

output نسند لها بعد inseted اسم الحقل المراد جلب الآيدي له ، بمعنى عند اضافة السجل ارجع برقم الآيدي التابع للسجل نفسه .

أيضاً يمكن عمل المطلوب بطريقة أخرى ،،،،،،، بإجراء مخزن واحد كالتالي :

كود :
create PROCEDURE savetwotables
@classname nvarchar(50),
@classno int,
@section nvarchar(50)
AS
Begin
  Set Nocount On
  DECLARE @ssid int
  INSERT INTO classes(classname) VALUES (@classname)
  SELECT @ssid=SCOPE_IDENTITY()
  INSERT INTO sections(classno, section) VALUES (@ssid, @section)
End
شرح الاجراء : اسم الاجراء المخزن = savetwotables
نعمل باراميترات باسماء الحقول المراد التعامل معها
@classname = اسم الحقل من جدول الفصول المراد اضافة فيه اسم الفصل .
@classno = اسم الحقل في جدول الشعب المراد اضافة فيه رقم الفصل .
@section = اسم الحقل من جدول الشعب المراد اضافة فيه اسم الشعبة .

لاحظي DECLARE @ssid int
الباراميتير @ssid هو الذي يحمل رقم الآيدي ليتم ادخالة في جدول الشعب في حقل رقم الفصل .

اسم جدول الفصول = classes
حقول جدول الفصول = (classno int) ترقيم تلقائي
classname nvarchar (50)) نص

اسم جدول الشعب = sections
حقول جدول الشعب = (secid int) ترقيم تلقائي
classno int) = رقم
section = nvarchar(50) = اسم الشعبة

الكود يكون كالتالي :

كود :
Dim cmd As New SqlCommand("savetwotables", conn)
        cmd.CommandType = CommandType.StoredProcedure

        conn.Open()

        cmd.Parameters.AddWithValue("@classname", t1.Text)
        cmd.Parameters.AddWithValue("@classno", "")
        cmd.Parameters.AddWithValue("@section", t2.Text)

        cmd.ExecuteNonQuery()
        conn.Close()
conn = متغير الاتصال بالداتا بيز .
t1 = تكست المراد ادخال اسم الفصل فيه .
t2 = تكست المراد ادخال اسم الشعبة فيه .

بالتوفيق
شكرا جزيلا أخي حريف برمجة وجزاك الله كل خير.
سؤال آخر لنفس المثال بالنسبة للفصول والشعب، سأطرح مثال للتوضيح
مثلا تم ادخال البيانات التالية
الصف kg1
الشعبة a
ثم تم ادخال سجل ثاني
الصف kg1
الشعبة b
فإنه بداخل قاعدة البيانات ستكون الجداول و السجلات كالتالي
[ATTACH=CONFIG]3333[/ATTACH]
بمعنى عند وجود أكثر من شعبة للفصل الواحد فإنه تظهر السجلات وكأنها فصول مختلفة في حين أنني أريد أن لايتم تكرار رقم الفصل عند وجود أكثر من شعبة بمعنى يكون كالتالي
[ATTACH=CONFIG]3335[/ATTACH]

كيف أقوم بتعديل ذلك بداخل جملة الادخال insert في sql ؟
كلامك صحيح اقدم لك الحل مره أخرى :

نفس الاجراء المخزن السابق ولكن الكود يصبح كالتالي :

كود :
Dim cmd As New SqlCommand
        cmd.Connection = conn
        conn.Open()

        cmd.CommandText = "select * from classes where classname=@classname"
        cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

        Dim dr As SqlDataReader = cmd.ExecuteReader

        If dr.Read = True Then
            cmd.Parameters.Clear()

            cmd.CommandText = "INSERT INTO sections (classno,section) VALUES (@classno,@section)"
            cmd.Parameters.AddWithValue("@classno", dr!classno)
            cmd.Parameters.AddWithValue("@section", TextBox2.Text)

            dr.Close()

            cmd.ExecuteNonQuery()
        Else
            dr.Close()

            cmd.Parameters.Clear()

            cmd.CommandText = "savetwotables"
            cmd.CommandType = CommandType.StoredProcedure

            cmd.Parameters.AddWithValue("@classname", TextBox1.Text)
            cmd.Parameters.AddWithValue("@classno", "")
            cmd.Parameters.AddWithValue("@section", TextBox2.Text)

            cmd.ExecuteNonQuery()
        End If

        cmd.Dispose()
        conn.Close()

والإستعلام يكون كالتالي لعرض البيانات في القريد مثلاً :

كود :
Dim dp As New SqlDataAdapter("SELECT classes.classno, classes.classname, sections.section FROM classes INNER JOIN sections ON classes.classno = sections.classno order by classes.classname, sections.section", conn)
        Dim ds As New DataSet
        ds.Clear()
        dp.Fill(ds, "classes")
        GridView1.DataSource = ds.Tables(0)
        GridView1.DataBind()
        dp.Dispose()

بالتوفيق
حريف برمجة كتب :كلامك صحيح اقدم لك الحل مره أخرى :

نفس الاجراء المخزن السابق ولكن الكود يصبح كالتالي :

كود :
Dim cmd As New SqlCommand
        cmd.Connection = conn
        conn.Open()

        cmd.CommandText = "select * from classes where classname=@classname"
        cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

        Dim dr As SqlDataReader = cmd.ExecuteReader

        If dr.Read = True Then
            cmd.Parameters.Clear()

            cmd.CommandText = "INSERT INTO sections (classno,section) VALUES (@classno,@section)"
            cmd.Parameters.AddWithValue("@classno", dr!classno)
            cmd.Parameters.AddWithValue("@section", TextBox2.Text)

            dr.Close()

            cmd.ExecuteNonQuery()
        Else
            dr.Close()

            cmd.Parameters.Clear()

            cmd.CommandText = "savetwotables"
            cmd.CommandType = CommandType.StoredProcedure

            cmd.Parameters.AddWithValue("@classname", TextBox1.Text)
            cmd.Parameters.AddWithValue("@classno", "")
            cmd.Parameters.AddWithValue("@section", TextBox2.Text)

            cmd.ExecuteNonQuery()
        End If

        cmd.Dispose()
        conn.Close()

والإستعلام يكون كالتالي لعرض البيانات في القريد مثلاً :

كود :
Dim dp As New SqlDataAdapter("SELECT classes.classno, classes.classname, sections.section FROM classes INNER JOIN sections ON classes.classno = sections.classno order by classes.classname, sections.section", conn)
        Dim ds As New DataSet
        ds.Clear()
        dp.Fill(ds, "classes")
        GridView1.DataSource = ds.Tables(0)
        GridView1.DataBind()
        dp.Dispose()

بالتوفيق

ألف شكر لك أخي الفاضل حريف برمجة
ولكن ماذا عن طريقتك الأولى بدون استخدام الإجراء المخزن هل يمكن تطبيق ذلك دون الحاجة للإجراء المخزنstored procedures؟؟
اعتذر عن كثرة الأسئلة بسبب انني مبتدئة واود الاستفادة من خبراتكم وجزاك الله كل خير
dena كتب :ألف شكر لك أخي الفاضل حريف برمجة
ولكن ماذا عن طريقتك الأولى بدون استخدام الإجراء المخزن هل يمكن تطبيق ذلك دون الحاجة للإجراء المخزنstored procedures؟؟
اعتذر عن كثرة الأسئلة بسبب انني مبتدئة واود الاستفادة من خبراتكم وجزاك الله كل خير

العفو ،، وترى ماسوينا غير الواجب

نعم ممكن ،، اي شي في البرمجة ممكن عملها البرمجة ماهي إلا أفكار وتنفيذها ،،

الكود لعمل مطلوبك بدون اجراء مخزن يصبح كالتالي :

كود :
Dim cmd As New SqlCommand
        cmd.Connection = conn
        conn.Open()

        cmd.CommandText = "select * from classes where classname=@classname"
        cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

        Dim dr As SqlDataReader = cmd.ExecuteReader

        If dr.Read = True Then
            cmd.Parameters.Clear()

            cmd.CommandText = "INSERT INTO sections (classno,section) VALUES (@classno,@section)"
            cmd.Parameters.AddWithValue("@classno", dr!classno)
            cmd.Parameters.AddWithValue("@section", TextBox2.Text)

            dr.Close()

            cmd.ExecuteNonQuery()
        Else
            dr.Close()

            cmd.Parameters.Clear()

            cmd.CommandText = "INSERT INTO classes (classname) OUTPUT(Inserted.classno) VALUES (@classname)"
            cmd.Parameters.AddWithValue("@classname", TextBox1.Text)

            Dim sid As Integer = cmd.ExecuteScalar


            Dim cmd2 As New SqlCommand
            cmd2.Connection = conn

            cmd2.CommandText = "INSERT INTO sections (classno,section) VALUES (@classno,@section)"
            cmd2.Parameters.AddWithValue("@classno", sid)
            cmd2.Parameters.AddWithValue("@section", TextBox2.Text)

            cmd2.ExecuteNonQuery()

            cmd2.Dispose()
        End If

        cmd.Dispose()
        conn.Close()

بالتوفيق
الصفحات : 1 2 3