এসকিউএল সার্ভার: একই সাথে দুটি টেবিলের মধ্যে প্রবেশ করা কি সম্ভব?


143

আমার ডাটাবেসের তিন টেবিল নামক রয়েছে Object_Table, Data_Tableএবং Link_Table। লিঙ্ক সারণীতে সবেমাত্র দুটি কলাম রয়েছে, একটি অবজেক্ট রেকর্ডের পরিচয় এবং ডেটা রেকর্ডের একটি পরিচয়।

আমি ডেটা অনুলিপি করতে চাই DATA_TABLEযেখানে এটিকে একটি প্রদত্ত বস্তুর পরিচয়ের সাথে যুক্ত করা হয়েছে Data_Tableএবং Link_Tableকোনও ভিন্ন প্রদত্ত বস্তুর পরিচয়ের জন্য এবং সম্পর্কিত রেকর্ডগুলি সন্নিবেশ করতে চাই ।

আমি একটি টেবিল ভেরিয়েবল এবং প্রতিটি পুনরাবৃত্তির জন্য দুটি সন্নিবেশ করার মাধ্যমে লুপিং নির্বাচন করে এটি করতে পারি।

এটি কি এটি সেরা উপায়?

সম্পাদনা : আমি দুটি কারণে একটি লুপ এড়াতে চাই, প্রথমটি হ'ল আমি অলস এবং একটি লুপ / ​​টেম্প টেবিলের জন্য আরও কোড প্রয়োজন, আরও কোডের অর্থ ভুল করার জন্য আরও বেশি জায়গা এবং দ্বিতীয় কারণটি পারফরম্যান্স সম্পর্কে উদ্বেগ।

আমি একটি তথ্য সন্নিবেশ করে সমস্ত তথ্য অনুলিপি করতে পারি তবে যেখানে প্রতিটি রেকর্ডে নতুন আইডি রয়েছে সেখানে নতুন ডেটা রেকর্ডের সাথে লিঙ্ক টেবিলটি কীভাবে পাবেন?


এটি একটি সন্নিবেশ করে করার চেষ্টা করার আগ্রহ আমি পাই না, যখন 2 টি সন্নিবেশ করে এটি পুরোপুরি ভালভাবে কাজ করে। আপনি কী বোঝাতে চেয়েছেন যে 2 টি সন্নিবেশ দুটিই সম্পন্ন হয়েছে তা নিশ্চিত করতে চান? তারপরে আপনাকে এই প্রতিশ্রুতিবদ্ধ / রোলব্যাক নির্দেশ পরীক্ষা করতে হবে।
ফিলিপ গ্রান্দিয়ার

2
আমি দুটি সন্নিবেশ করে খুশি হব, এটি ঠিক যে লিঙ্ক টেবিলের মধ্যে যে পরিচয়গুলি সন্নিবেশ করা দরকার তা হ'ল প্রথম সন্নিবেশে উত্পন্ন পরিচয়।
tpower

উত্তর:


219

এক বিবৃতিতে : না।

একটি লেনদেনে : হ্যাঁ

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

সুসংবাদটি হ'ল উপরের কোডটিও পারমাণবিক হওয়ার নিশ্চয়তা রয়েছে এবং ক্লায়েন্ট অ্যাপ্লিকেশন থেকে একটি একক ফাংশন কলে একটি বর্গক্ষেত্রের স্ট্রিং সহ সার্ভারের কাছে পাঠানো যেতে পারে যেন এটি একটি বিবৃতি were একটি একক সন্নিবেশনের প্রভাব পেতে আপনি একটি টেবিলে ট্রিগারও প্রয়োগ করতে পারেন। যাইহোক, এটি শেষ পর্যন্ত এখনও দুটি বিবৃতি এবং আপনি সম্ভবত প্রতিটি sertোকানোর জন্য ট্রিগারটি চালাতে চান না ।


2
এটি আমি দীর্ঘদিন ধরে অনুসন্ধান করছি। ধন্যবাদ :)
nandu.com

33
@ জোয়েল, দুর্দান্ত প্রশ্ন। সম্ভবত কেউ বিকল্প বাস্তবতার জন্য কামনা করেছিলেন এবং আপনি খারাপ সংবাদের বাহক ছিলেন। ;)
কর্ক ওয়াল

2
এটি আমার আজকের দিনটি রক্ষা করেছে :)
থ্যাঙ্কস

12
এটি সমস্যার সমাধান করে না। তিনি অবজেক্টট্যাবল থেকে পঠিত ডেটা toোকাতে চান। অর্থাৎ একটি insert into ... select ...বিবৃতি। উপরের কোডটি কীভাবে অবজেক্ট_Table ডেটা পড়ে বা লুপ করে। তারপরে আপনার তখন একটি সারণী ভেরিয়েবল ব্যবহার করা দরকার যা প্রশ্নকর্তা করতে চান নি।
hofnarwillie

8
অবশ্যই এটি সমস্যার সমাধান করে। সম্ভবত আমি এর জন্য সমস্ত কোড লিখি না , তবে তারপরে ওপি কপি করতে চাইলে সমস্ত কলামই ভাগ করে নি। এই উত্তরে প্রদর্শিত বৈশিষ্ট্যগুলি ওপিকে যা জিজ্ঞাসা করছে তা করার অনুমতি দেবে ... একটি রেকর্ড তৈরি করতে, একটি নতুন রেকর্ডের আইডি পেতে এবং কোনও আইডিটিকে পরমাণুর উপায়ে সেই আইডিটি ব্যবহার করার জন্য একটি ক্যোয়ারী চালাতে পারে। কীভাবে সন্নিবেশ / নির্বাচন করতে হবে তা ওপি ইতিমধ্যে জানে। এই যে টুকরোটি সে নিখোঁজ ছিল।
জোয়েল কোহর্ন 14

35

আপনি এখনও দুই প্রয়োজন INSERTবিবৃতি, কিন্তু শোনাচ্ছে মত পেতে চান IDENTITYপ্রথম সন্নিবেশ থেকে এবং দ্বিতীয় এটি ব্যবহার, যে ক্ষেত্রে, আপনি দেখব করতে চাইতে পারেন OUTPUTবা OUTPUT INTO: http://msdn.microsoft.com/en- মার্কিন / লাইব্রেরি / ms177564.aspx


1
ধন্যবাদ! আমি OUTPUT কীওয়ার্ড সম্পর্কে জানতাম না, আমি ঠিক কী খুঁজছিলাম। +1
রেক্স মরগান


@ ভি.উইউউ আমি এমনটা ভাবি না, আমাকে দেখতে একটি পরীক্ষা করতে হবে।
কেড রক্স

18

নীচে সারণী ভেরিয়েবলগুলি ব্যবহার করে আমার যে পরিস্থিতি হয়েছিল তা সেট আপ করে।

DECLARE @Object_Table TABLE
(
    Id INT NOT NULL PRIMARY KEY
)

DECLARE @Link_Table TABLE
(
    ObjectId INT NOT NULL,
    DataId INT NOT NULL
)

DECLARE @Data_Table TABLE
(
    Id INT NOT NULL Identity(1,1),
    Data VARCHAR(50) NOT NULL
)

-- create two objects '1' and '2'
INSERT INTO @Object_Table (Id) VALUES (1)
INSERT INTO @Object_Table (Id) VALUES (2)

-- create some data
INSERT INTO @Data_Table (Data) VALUES ('Data One')
INSERT INTO @Data_Table (Data) VALUES ('Data Two')

-- link all data to first object
INSERT INTO @Link_Table (ObjectId, DataId)
SELECT Objects.Id, Data.Id
FROM @Object_Table AS Objects, @Data_Table AS Data
WHERE Objects.Id = 1

অন্য একটি উত্তরের জন্য ধন্যবাদ যা আমাকে সমাধান প্রকাশ করতে পারে এমন OUTPUT ধারাটির দিকে আমাকে ইঙ্গিত করেছে:

-- now I want to copy the data from from object 1 to object 2 without looping
INSERT INTO @Data_Table (Data)
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId)
SELECT Data.Data
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId
                INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1

এটি দেখা যাচ্ছে যে নিম্নলিখিত ত্রুটির কারণে এটি বাস্তব জীবনে এত সহজ নয়

OUTPUT INTO ধারাটি (প্রাথমিক কী, বিদেশী কী) সম্পর্কের উভয় দিকে থাকতে পারে না

আমি এখনও OUTPUT INTOএকটি টেম্প টেবিল করতে পারি এবং তারপরে সাধারণ withোকানো দিয়ে শেষ করতে পারি। সুতরাং আমি আমার লুপ এড়াতে পারি তবে আমি টেম্প টেবিলটি এড়াতে পারি না।



6

দেখে মনে হচ্ছে লিঙ্ক টেবিলটি অনেকগুলি ক্যাপচার করে: অবজেক্ট টেবিল এবং ডেটা টেবিলের মধ্যে অনেক সম্পর্ক।

আমার পরামর্শ হ'ল লেনদেন পরিচালনা করার জন্য একটি সঞ্চিত পদ্ধতি ব্যবহার করা। আপনি যখন অবজেক্টে প্রবেশ করতে চান বা ডেটা টেবিলটি আপনার সন্নিবেশগুলি সম্পাদন করে, নতুন আইডি পান এবং সেগুলি লিঙ্ক টেবিলটিতে সন্নিবেশ করান।

এটি আপনার সমস্ত লজিককে সহজেই স্প্রোক কল করতে একটির মধ্যে আবদ্ধ থাকতে দেয়।


কেন অন্য কেউ আপনাকে উত্সাহিত করেনি? সঞ্চিত পদ্ধতিটি সুস্পষ্ট এবং সর্বোত্তম উপায়। আপনার উত্তরটি জোয়েল কোহুরনের উত্তরের সাথে একত্রিত করুন এবং আপনি সেরা উত্তরটি পান!
ছড়া

4

আপনি যদি ক্রিয়াগুলি কম বা কম পারমাণবিক হতে চান তবে আমি সেগুলি কোনও লেনদেনে মুড়ে ফেলার বিষয়টি নিশ্চিত করব। এইভাবে আপনি নিশ্চিত হতে পারেন যে উভয়ই ঘটেছে বা উভয়ই প্রয়োজনীয় হিসাবে ঘটেনি।


2
ক্রিয়াকলাপগুলি পারমাণবিক হয় যদি তারা লেনদেনে জড়িত থাকে, "কম বা কম" পারমাণবিক নয়। অগত্যা যেটি গ্যারান্টিযুক্ত নয় তা হ'ল বিচ্ছিন্নতার স্তর, যদি আপনি এটি নির্দিষ্ট না করেন।
ডেভ মার্কেল

4

আপনি আপনার সন্নিবেশ বিবৃতিতে প্রয়োজনীয় কলামের নাম নির্বাচন করে একটি ভিউ তৈরি করতে পারেন, অন্তর্ভুক্ত ট্রিগারটির একটি ইনস্টল করুন এবং এই দৃশ্যে intoোকান।


4

আমি ব্যবহার উপর চাপ দিতে চাই

SET XACT_ABORT ON;

একাধিক স্কেল স্টেটমেন্ট সহ এমএসএসকিউএল লেনদেনের জন্য।

দেখুন: https://msdn.microsoft.com/en-us/library/ms188792.aspx তারা খুব ভাল উদাহরণ দেয়।

সুতরাং, চূড়ান্ত কোডটি নীচের মতো হওয়া উচিত:

SET XACT_ABORT ON;

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

2

সন্নিবেশ একবারে কেবল একটি টেবিলে পরিচালনা করতে পারে। একাধিক সন্নিবেশকে একাধিক বিবৃতি থাকতে হবে।

আমি জানি না যে আপনাকে একটি টেবিল ভেরিয়েবলের মাধ্যমে লুপিংয়ের দরকার আছে - আপনি কেবল একটি টেবিলের মধ্যে একটি ভর সন্নিবেশ ব্যবহার করতে পারবেন না, তার পরে অন্যটিতে ভর inোকানো যাবে না?

যাইহোক - আমি অনুমান করছি আপনি অবজেক্টট্যাবল থেকে ডেটা অনুলিপি করছেন; অন্যথায় প্রশ্নটি বোঝায় না।


2

ওরাকলে একটি বহুগুণ সন্নিবেশ করতে সক্ষম হবার আগে, আপনি সন্নিবেশগুলি সম্পাদন করার জন্য এটিতে একটি সংজ্ঞা যুক্ত একটি কৌশল ব্যবহার করতে পারেন যা সন্নিবেশকে সঞ্চালনের জন্য এটিতে একটি সংঘবদ্ধ ট্রিগার সংজ্ঞায়িত করা হয়েছিল। এটি কি এসকিউএল সার্ভারে করা যেতে পারে?


-1
-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE InsetIntoTwoTable

(
@name nvarchar(50),
@Email nvarchar(50)
)

AS
BEGIN

    SET NOCOUNT ON;


    insert into dbo.info(name) values (@name)
    insert into dbo.login(Email) values (@Email)
END
GO

আপনি কিছু ব্যাখ্যা যোগ করতে পারেন?
কিএল

-2

// আপনি যদি প্রথম টেবিলের মতো একই সারণি করতে চান

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";

$result = @mysql_query($qry);

$qry2 = "INSERT INTO table2 (one,two, three) VVALUES('$one','$two','$three')";

$result = @mysql_query($qry2);

// অথবা আপনি যদি টেবিলের একটি নির্দিষ্ট অংশ .োকাতে চান

 $qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";


  $result = @mysql_query($qry);

 $qry2 = "INSERT INTO table2 (two) VALUES('$two')";

 $result = @mysql_query($qry2);

// আমি জানি এটি সঠিক হতে খুব ভাল দেখাচ্ছে, তবে এটি কাজ করে এবং আপনি কোয়েরিটির কেবলমাত্র পরিবর্তনটি পরিবর্তন করতে পারেন

    "$qry"-number and number in @mysql_query($qry"")

আমার কাছে 17 টি টেবিল রয়েছে এটিতে কাজ করেছে।


serোকানোর মাঝে যদি কিছু ভুল হয়? আপনার সন্নিবেশগুলি অসম্পূর্ণ হবে। ঠিক আছে? যদি এটি করে থাকে .. এটির চিকিত্সা করার জন্য আপনার কাছে কোনও রোলব্যাক ফাংশন আছে? যদি না হয় .. আপনার ডেটা অখণ্ডতায় আপনার সমস্যা আছে।
ডিপসেল

7
-1। এই উত্তরটি পিএইচপি-তে MySQL পদ্ধতি ব্যবহার করছে বলে মনে হচ্ছে be মাইএসকিউএল বা পিএইচপি-র কোনও উল্লেখ না করেই প্রশ্নটি এসকিএল এবং এসকিএল-সার্ভার ট্যাগ করা হয় ।
এমএসকিফিশার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.